ETH Price: $3,110.11 (+0.16%)

Token

The Pixel Portraits (PXP)
 

Overview

Max Total Supply

0 PXP

Holders

718

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 PXP
0xa31e99Ab181D8db8Fb3f84C8f18bbB6229893746
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The Pixel Portraits collection (#1001 - #10000)

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ThePixelPortraits

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 300 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-25
*/

// SPDX-License-Identifier: MIT


pragma solidity ^0.8.0;


// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▀ ▀▓▌▐▓▓▓▓▓▀▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓ ▓▓▌▝▚▞▜▓ ▀▀ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▄▀▓▌▐▓▌▐▓▄▀▀▀▓▓▓▓▓▓▓▓▓▓▛▀▀▀▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓       ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓       ▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▛▀▀▀▄▄▄▄▄▄▄▛▀▀▀▓▓▓▛▀▀▀▓▓▓▙▄▄▄▛▀▀▀▓▓▓▛▀▀▀▙▄▄▄▓▓▓▛▀▀▀▄▄▄▄▄▄▄▛▀▀▀▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▀▀▀▜▓▓▓▓▓▓▓▓▓▓▌   ▀▀▀▀▀▀▀▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓   ▐▓▓▓▓▓▓▓▓▓▓▌          ▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▀▀▀▀▀▀▀▓▓▓▓▓▓▓▌   ▓▓▓▛▀▀▀▙▄▄▄▓▓▓▙▄▄▄▛▀▀▀▓▓▓▓▓▓▓▀▀▀▀▀▀▀▀▀▀▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌          ▓▓▓▓▓▓▓▌   ▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓          ▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▐▓▓▓  ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▓▓▓    ▓▓▓▓▓▓    ▐▓▓▓▓▓▌    ▐▓▓▓      ▐▓▓▓▌    ▐▓▓▓▓▓▌    ▓▓▓▓▓▓▓▌       ▓▓▓    ▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▌   ▓▓▓▓▌  ▓▓▓▓  ▐▌  ▓▓▓▓▌  ▓  ▐▓▓▓▓▌  ▓▓▓  ▐▓▓▓  ▐▓▓▓▓▌  ▓▓▓▓▓▓▓▓  ▐▓  ▐▓▓▓  ▐▓▓▓▌  ▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▙▄▄▄▓▓▓▓▌  ▓▓▓▓  ▐▌  ▓▓▓▓▌  ▓  ▐▓▓▓▓▓▓▓▓▓▓  ▐▓▓▓  ▐▓▓▓▓▓▓▓▓▓▓▌      ▐▓  ▐▓▓▓  ▐▓▓▓▓▓▓    ▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▓▓▓▓  ▐▌  ▓▓▓▓▌  ▓  ▐▓▓▓▓▓▓▓▓▓▓  ▐▓▓▓  ▐▓▓▓▓▓▓▓▓   ▓▓▓▓  ▐▓  ▐▓▓▓  ▐▓▓▓▓▓▓▓▓▓▓  ▐▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌      ▓▓▓▓▓▓    ▐▓▓▓  ▐▓▓▓▓▓▓▓▓▓▓▓▓▌  ▓  ▐▓▓▓▓▓▓▓▓▓▓▌    ▓▓▓▓  ▐▓▓▓▓▓  ▐▓▓▓    ▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
// ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
//
//
//
//
//                     oOOOOOOOo °º¤øøøøøø¤º° ooOOOOOOOOOOOOOOoo °º¤øøøøøø¤º° oOOOOOOOo          
//                    OOOOOOOOOOOOOooooooooOOOOOOOOOOOOOOOOOOOOOOOOooooooooOOOOOOOOOOOOO         
//                    OOOOººººººººººººººººººººººººººººººººººººººººººººººººººººººººººOOOO         
//                    oOOO|                                                        |OOOo         
//                     oOO|                                                        |OOo          
//                    ¤ oO|                                                        |Oo ¤         
//                    O¤ O|                              ░░                        |O ¤O           
//                    O¤ O|                            ░░░░░░                      |O ¤O           
//                    O¤ O|                          ░░░░░░░░░░░░░░░░░░            |O ¤O           
//                    O¤ O|                        ░░░░░░░░░░░░░░░░░░░░░░          |O ¤O          
//                    ¤ oO|                          ░░░░░░░░░░░░░░░░░░░░░░        |Oo ¤          
//                     oOO|                          ░░░░░░░░░░░░░░░░░░░░░░        |OOo          
//                    oOOO|          ##            ░░░░░░░░            ░░░░        |OOOo         
//                    OOOO|        ##  ##########  ░░░░░░                ░░░░      |OOOO         
//                    OOOO|      ##  ##############░░░░░░  SSSS      SSSS▓▓        |OOOO         
//                    OOOO|        ##################░░░░  ▓▓//      ▓▓//▓▓        |OOOO         
//                    oOOO|        ######        ####░░▓▓                ▓▓        |OOOo         
//                     oOO|        ####            ▓▓░░▓▓                ▓▓        |OOo          
//                    ¤ oO|        ####SSSS    SSSS▓▓░░▓▓        ▓▓      ▓▓        |Oo ¤          
//                    O¤ O|      ▓▓    ▓▓//    ▓▓//▓▓  ▓▓    ▓▓          ▓▓        |O ¤O           
//                    O¤ O|      ▓▓▓▓              ▓▓  ▓▓      ▓▓▓▓▓▓    ▓▓        |O ¤O           
//                    O¤ O|        ▓▓        ▓▓    ▓▓  ▓▓              ▓▓          |O ¤O           
//                    O¤ O|        ▓▓    ▓▓        ▓▓    ▓▓  ▓▓      ▓▓            |O ¤O           
//                    ¤ oO|          ▓▓    ▓▓▓▓    ▓▓    ▓▓    ▓▓▓▓▓▓              |Oo ¤          
//                     oOO|          ▓▓          ▓▓    ▓▓▓▓▓▓    ▓▓                |OOo          
//                    oOOO|        XXXX  ▓▓▓▓▓▓▓▓      ▓▓VVVV▓▓  ▓▓▓▓              |OOOo         
//                    OOOOøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøOOOO   
//                    OOOOOOOOOOOOOººººººººOOOOOOOOOOOOOOOOOOOOOOOOººººººººOOOOOOOOOOOOO         
//                     ºOOOOOOOº ¸,øøøøøøøøø,¸ ººOOOOOOOOOOOOOOºº ¸,øøøøøøø,¸ ºOOOOOOOOº         
//                                               _______________                               
//                                              |    Sisters    |                                    
//                                               ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//
//
//
// WE LIKE THE ART
//
// outstretched, emerging from a vital organ
// behind plum stacks, as a friend once more departs
// to go where windswept howlers lie effacing
// in the day on outer shells of garden parts
// who once was flayed up by effect's inverse
// whose face he hides behind in ancient schools
// whose windows were too dark for a distiller
//
// sat on the roof, foretelling lovers' rules
// who stars in only one of twin madonnas
// the early figures which we left and buried
// in distant view, with the ancient wheel spinning
//
// the golden lady's home while she was married
// his hand towards the orb while Moses watches
// ethereal nymphs still swirling all around
// who all discovered force in northern forests
// before the winning city had been crowned
// 
// with fiery spear
// ensemble au voile
// with death as third
//
//
// answers on a postcard, read to verify


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

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

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

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

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

    uint256 private _status;

    constructor () {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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


/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @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);
    }

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

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


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

}


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

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


/**
 * @dev Implement this if you want your extension to have overloadable URI's
 */
interface ICreatorExtensionTokenURI is IERC165 {

    /**
     * Get the uri for a given creator/tokenId
     */
    function tokenURI(address creator, uint256 tokenId) external view returns (string memory);
}

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface,
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return _supportsERC165Interface(account, type(IERC165).interfaceId) &&
            !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return supportsERC165(account) &&
            _supportsERC165Interface(account, interfaceId);
    }

    /**
     * @dev Returns a boolean array where each value corresponds to the
     * interfaces passed in and whether they're supported or not. This allows
     * you to batch check interfaces for a contract where your expectation
     * is that some interfaces may not be supported.
     *
     * See {IERC165-supportsInterface}.
     *
     * _Available since v3.4._
     */
    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) {
        // an array of booleans corresponding to interfaceIds and whether they're supported or not
        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);

        // query support of ERC165 itself
        if (supportsERC165(account)) {
            // query support of each interface in interfaceIds
            for (uint256 i = 0; i < interfaceIds.length; i++) {
                interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);
            }
        }

        return interfaceIdsSupported;
    }

    /**
     * @dev Returns true if `account` supports all the interfaces defined in
     * `interfaceIds`. Support for {IERC165} itself is queried automatically.
     *
     * Batch-querying can lead to gas savings by skipping repeated checks for
     * {IERC165} support.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
        // query support of ERC165 itself
        if (!supportsERC165(account)) {
            return false;
        }

        // query support of each interface in _interfaceIds
        for (uint256 i = 0; i < interfaceIds.length; i++) {
            if (!_supportsERC165Interface(account, interfaceIds[i])) {
                return false;
            }
        }

        // all interfaces supported
        return true;
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     * Interface identification is specified in ERC-165.
     */
    function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {
        bytes memory encodedParams = abi.encodeWithSelector(IERC165(account).supportsInterface.selector, interfaceId);
        (bool success, bytes memory result) = account.staticcall{ gas: 30000 }(encodedParams);
        if (result.length < 32) return false;
        return success && abi.decode(result, (bool));
    }
}

/**
 * @dev Core creator interface
 */
interface ICreatorCore is IERC165 {

    event ExtensionRegistered(address indexed extension, address indexed sender);
    event ExtensionUnregistered(address indexed extension, address indexed sender);
    event ExtensionBlacklisted(address indexed extension, address indexed sender);
    event MintPermissionsUpdated(address indexed extension, address indexed permissions, address indexed sender);
    event RoyaltiesUpdated(uint256 indexed tokenId, address payable[] receivers, uint256[] basisPoints);
    event DefaultRoyaltiesUpdated(address payable[] receivers, uint256[] basisPoints);
    event ExtensionRoyaltiesUpdated(address indexed extension, address payable[] receivers, uint256[] basisPoints);
    event ExtensionApproveTransferUpdated(address indexed extension, bool enabled);

    /**
     * @dev gets address of all extensions
     */
    function getExtensions() external view returns (address[] memory);

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * extension address must point to a contract implementing ICreatorExtension.
     * Returns True if newly added, False if already added.
     */
    function registerExtension(address extension, string calldata baseURI) external;

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * extension address must point to a contract implementing ICreatorExtension.
     * Returns True if newly added, False if already added.
     */
    function registerExtension(address extension, string calldata baseURI, bool baseURIIdentical) external;

    /**
     * @dev add an extension.  Can only be called by contract owner or admin.
     * Returns True if removed, False if already removed.
     */
    function unregisterExtension(address extension) external;

    /**
     * @dev blacklist an extension.  Can only be called by contract owner or admin.
     * This function will destroy all ability to reference the metadata of any tokens created
     * by the specified extension. It will also unregister the extension if needed.
     * Returns True if removed, False if already removed.
     */
    function blacklistExtension(address extension) external;

    /**
     * @dev set the baseTokenURI of an extension.  Can only be called by extension.
     */
    function setBaseTokenURIExtension(string calldata uri) external;

    /**
     * @dev set the baseTokenURI of an extension.  Can only be called by extension.
     * For tokens with no uri configured, tokenURI will return "uri+tokenId"
     */
    function setBaseTokenURIExtension(string calldata uri, bool identical) external;

    /**
     * @dev set the common prefix of an extension.  Can only be called by extension.
     * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
     * Useful if you want to use ipfs/arweave
     */
    function setTokenURIPrefixExtension(string calldata prefix) external;

    /**
     * @dev set the tokenURI of a token extension.  Can only be called by extension that minted token.
     */
    function setTokenURIExtension(uint256 tokenId, string calldata uri) external;

    /**
     * @dev set the tokenURI of a token extension for multiple tokens.  Can only be called by extension that minted token.
     */
    function setTokenURIExtension(uint256[] memory tokenId, string[] calldata uri) external;

    /**
     * @dev set the baseTokenURI for tokens with no extension.  Can only be called by owner/admin.
     * For tokens with no uri configured, tokenURI will return "uri+tokenId"
     */
    function setBaseTokenURI(string calldata uri) external;

    /**
     * @dev set the common prefix for tokens with no extension.  Can only be called by owner/admin.
     * If configured, and a token has a uri set, tokenURI will return "prefixURI+tokenURI"
     * Useful if you want to use ipfs/arweave
     */
    function setTokenURIPrefix(string calldata prefix) external;

    /**
     * @dev set the tokenURI of a token with no extension.  Can only be called by owner/admin.
     */
    function setTokenURI(uint256 tokenId, string calldata uri) external;

    /**
     * @dev set the tokenURI of multiple tokens with no extension.  Can only be called by owner/admin.
     */
    function setTokenURI(uint256[] memory tokenIds, string[] calldata uris) external;

    /**
     * @dev set a permissions contract for an extension.  Used to control minting.
     */
    function setMintPermissions(address extension, address permissions) external;

    /**
     * @dev Configure so transfers of tokens created by the caller (must be extension) gets approval
     * from the extension before transferring
     */
    function setApproveTransferExtension(bool enabled) external;

    /**
     * @dev get the extension of a given token
     */
    function tokenExtension(uint256 tokenId) external view returns (address);

    /**
     * @dev Set default royalties
     */
    function setRoyalties(address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Set royalties of a token
     */
    function setRoyalties(uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Set royalties of an extension
     */
    function setRoyaltiesExtension(address extension, address payable[] calldata receivers, uint256[] calldata basisPoints) external;

    /**
     * @dev Get royalites of a token.  Returns list of receivers and basisPoints
     */
    function getRoyalties(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
    
    // Royalty support for various other standards
    function getFeeRecipients(uint256 tokenId) external view returns (address payable[] memory);
    function getFeeBps(uint256 tokenId) external view returns (uint[] memory);
    function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
    function royaltyInfo(uint256 tokenId, uint256 value) external view returns (address, uint256);

}



/**
 * @dev Required interface of an ERC721Creator compliant extension contracts.
 */
interface IERC721CreatorMintPermissions is IERC165 {

    /**
     * @dev get approval to mint
     */
    function approveMint(address extension, address to, uint256 tokenId) external;
}

/**
 * @dev Your extension is required to implement this interface if it wishes
 * to receive the onBurn callback whenever a token the extension created is
 * burned
 */
interface IERC721CreatorExtensionBurnable is IERC165 {
    /**
     * @dev callback handler for burn events
     */
    function onBurn(address owner, uint256 tokenId) external;
}

/**
 * Implement this if you want your extension to approve a transfer
 */
interface IERC721CreatorExtensionApproveTransfer is IERC165 {

    /**
     * @dev Set whether or not the creator will check the extension for approval of token transfer
     */
    function setApproveTransfer(address creator, bool enabled) external;

    /**
     * @dev Called by creator contract to approve a transfer
     */
    function approveTransfer(address from, address to, uint256 tokenId) external returns (bool);
}

/**
 * @dev Interface for admin control
 */
interface IAdminControl is IERC165 {

    event AdminApproved(address indexed account, address indexed sender);
    event AdminRevoked(address indexed account, address indexed sender);

    /**
     * @dev gets address of all admins
     */
    function getAdmins() external view returns (address[] memory);

    /**
     * @dev add an admin.  Can only be called by contract owner.
     */
    function approveAdmin(address admin) external;

    /**
     * @dev remove an admin.  Can only be called by contract owner.
     */
    function revokeAdmin(address admin) external;

    /**
     * @dev checks whether or not given address is an admin
     * Returns True if they are
     */
    function isAdmin(address admin) external view returns (bool);

}

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

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

abstract contract AdminControl is Ownable, IAdminControl, ERC165 {
    using EnumerableSet for EnumerableSet.AddressSet;

    // Track registered admins
    EnumerableSet.AddressSet private _admins;

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

    /**
     * @dev Only allows approved admins to call the specified function
     */
    modifier adminRequired() {
        require(owner() == msg.sender || _admins.contains(msg.sender), "AdminControl: Must be owner or admin");
        _;
    }   

    /**
     * @dev See {IAdminControl-getAdmins}.
     */
    function getAdmins() external view override returns (address[] memory admins) {
        admins = new address[](_admins.length());
        for (uint i = 0; i < _admins.length(); i++) {
            admins[i] = _admins.at(i);
        }
        return admins;
    }

    /**
     * @dev See {IAdminControl-approveAdmin}.
     */
    function approveAdmin(address admin) external override onlyOwner {
        if (!_admins.contains(admin)) {
            emit AdminApproved(admin, msg.sender);
            _admins.add(admin);
        }
    }

    /**
     * @dev See {IAdminControl-revokeAdmin}.
     */
    function revokeAdmin(address admin) external override onlyOwner {
        if (_admins.contains(admin)) {
            emit AdminRevoked(admin, msg.sender);
            _admins.remove(admin);
        }
    }

    /**
     * @dev See {IAdminControl-isAdmin}.
     */
    function isAdmin(address admin) public override view returns (bool) {
        return (owner() == admin || _admins.contains(admin));
    }

}

/**
 * @dev Core creator implementation
 */
abstract contract CreatorCore is ReentrancyGuard, ICreatorCore, ERC165 {
    using Strings for uint256;
    using EnumerableSet for EnumerableSet.AddressSet;
    using AddressUpgradeable for address;

    uint256 _tokenCount = 0;

    // Track registered extensions data
    EnumerableSet.AddressSet internal _extensions;
    EnumerableSet.AddressSet internal _blacklistedExtensions;
    mapping (address => address) internal _extensionPermissions;
    mapping (address => bool) internal _extensionApproveTransfers;
    
    // For tracking which extension a token was minted by
    mapping (uint256 => address) internal _tokensExtension;

    // The baseURI for a given extension
    mapping (address => string) private _extensionBaseURI;
    mapping (address => bool) private _extensionBaseURIIdentical;

    // The prefix for any tokens with a uri configured
    mapping (address => string) private _extensionURIPrefix;

    // Mapping for individual token URIs
    mapping (uint256 => string) internal _tokenURIs;

    
    // Royalty configurations
    mapping (address => address payable[]) internal _extensionRoyaltyReceivers;
    mapping (address => uint256[]) internal _extensionRoyaltyBPS;
    mapping (uint256 => address payable[]) internal _tokenRoyaltyReceivers;
    mapping (uint256 => uint256[]) internal _tokenRoyaltyBPS;

    /**
     * External interface identifiers for royalties
     */

    /**
     *  @dev CreatorCore
     *
     *  bytes4(keccak256('getRoyalties(uint256)')) == 0xbb3bafd6
     *
     *  => 0xbb3bafd6 = 0xbb3bafd6
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_CREATORCORE = 0xbb3bafd6;

    /**
     *  @dev Rarible: RoyaltiesV1
     *
     *  bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb
     *  bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f
     *
     *  => 0xb9c4d9fb ^ 0x0ebd4c7f = 0xb7799584
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_RARIBLE = 0xb7799584;

    /**
     *  @dev Foundation
     *
     *  bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c
     *
     *  => 0xd5a06d4c = 0xd5a06d4c
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_FOUNDATION = 0xd5a06d4c;

    /**
     *  @dev EIP-2981
     *
     * bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
     *
     * => 0x2a55205a = 0x2a55205a
     */
    bytes4 private constant _INTERFACE_ID_ROYALTIES_EIP2981 = 0x2a55205a;

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

    /**
     * @dev Only allows registered extensions to call the specified function
     */
    modifier extensionRequired() {
        require(_extensions.contains(msg.sender), "Must be registered extension");
        _;
    }

    /**
     * @dev Only allows non-blacklisted extensions
     */
    modifier nonBlacklistRequired(address extension) {
        require(!_blacklistedExtensions.contains(extension), "Extension blacklisted");
        _;
    }   

    /**
     * @dev See {ICreatorCore-getExtensions}.
     */
    function getExtensions() external view override returns (address[] memory extensions) {
        extensions = new address[](_extensions.length());
        for (uint i = 0; i < _extensions.length(); i++) {
            extensions[i] = _extensions.at(i);
        }
        return extensions;
    }

    /**
     * @dev Register an extension
     */
    function _registerExtension(address extension, string calldata baseURI, bool baseURIIdentical) internal {
        require(extension != address(this), "Creator: Invalid");
        require(extension.isContract(), "Creator: Extension must be a contract");
        if (!_extensions.contains(extension)) {
            _extensionBaseURI[extension] = baseURI;
            _extensionBaseURIIdentical[extension] = baseURIIdentical;
            emit ExtensionRegistered(extension, msg.sender);
            _extensions.add(extension);
        }
    }

    /**
     * @dev Unregister an extension
     */
    function _unregisterExtension(address extension) internal {
       if (_extensions.contains(extension)) {
           emit ExtensionUnregistered(extension, msg.sender);
           _extensions.remove(extension);
       }
    }

    /**
     * @dev Blacklist an extension
     */
    function _blacklistExtension(address extension) internal {
       require(extension != address(this), "Cannot blacklist yourself");
       if (_extensions.contains(extension)) {
           emit ExtensionUnregistered(extension, msg.sender);
           _extensions.remove(extension);
       }
       if (!_blacklistedExtensions.contains(extension)) {
           emit ExtensionBlacklisted(extension, msg.sender);
           _blacklistedExtensions.add(extension);
       }
    }

    /**
     * @dev Set base token uri for an extension
     */
    function _setBaseTokenURIExtension(string calldata uri, bool identical) internal {
        _extensionBaseURI[msg.sender] = uri;
        _extensionBaseURIIdentical[msg.sender] = identical;
    }

    /**
     * @dev Set token uri prefix for an extension
     */
    function _setTokenURIPrefixExtension(string calldata prefix) internal {
        _extensionURIPrefix[msg.sender] = prefix;
    }

    /**
     * @dev Set token uri for a token of an extension
     */
    function _setTokenURIExtension(uint256 tokenId, string calldata uri) internal {
        require(_tokensExtension[tokenId] == msg.sender, "Invalid token");
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Set base token uri for tokens with no extension
     */
    function _setBaseTokenURI(string memory uri) internal {
        _extensionBaseURI[address(this)] = uri;
    }

    /**
     * @dev Set token uri prefix for tokens with no extension
     */
    function _setTokenURIPrefix(string calldata prefix) internal {
        _extensionURIPrefix[address(this)] = prefix;
    }


    /**
     * @dev Set token uri for a token with no extension
     */
    function _setTokenURI(uint256 tokenId, string calldata uri) internal {
        require(_tokensExtension[tokenId] == address(this), "Invalid token");
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Retrieve a token's URI
     */
    function _tokenURI(uint256 tokenId) internal view returns (string memory) {
        address extension = _tokensExtension[tokenId];
        require(!_blacklistedExtensions.contains(extension), "Extension blacklisted");

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            if (bytes(_extensionURIPrefix[extension]).length != 0) {
                return string(abi.encodePacked(_extensionURIPrefix[extension],_tokenURIs[tokenId]));
            }
            return _tokenURIs[tokenId];
        }

        if (ERC165Checker.supportsInterface(extension, type(ICreatorExtensionTokenURI).interfaceId)) {
            return ICreatorExtensionTokenURI(extension).tokenURI(address(this), tokenId);
        }

        if (!_extensionBaseURIIdentical[extension]) {
            return string(abi.encodePacked(_extensionBaseURI[extension], tokenId.toString()));
        } else {
            return _extensionBaseURI[extension];
        }
    }

    /**
     * Get token extension
     */
    function _tokenExtension(uint256 tokenId) internal view returns (address extension) {
        extension = _tokensExtension[tokenId];

        require(extension != address(this), "No extension for token");
        require(!_blacklistedExtensions.contains(extension), "Extension blacklisted");

        return extension;
    }

    /**
     * Helper to get royalties for a token
     */
    function _getRoyalties(uint256 tokenId) view internal returns (address payable[] storage, uint256[] storage) {
        return (_getRoyaltyReceivers(tokenId), _getRoyaltyBPS(tokenId));
    }

    /**
     * Helper to get royalty receivers for a token
     */
    function _getRoyaltyReceivers(uint256 tokenId) view internal returns (address payable[] storage) {
        if (_tokenRoyaltyReceivers[tokenId].length > 0) {
            return _tokenRoyaltyReceivers[tokenId];
        } else if (_extensionRoyaltyReceivers[_tokensExtension[tokenId]].length > 0) {
            return _extensionRoyaltyReceivers[_tokensExtension[tokenId]];
        }
        return _extensionRoyaltyReceivers[address(this)];        
    }

    /**
     * Helper to get royalty basis points for a token
     */
    function _getRoyaltyBPS(uint256 tokenId) view internal returns (uint256[] storage) {
        if (_tokenRoyaltyBPS[tokenId].length > 0) {
            return _tokenRoyaltyBPS[tokenId];
        } else if (_extensionRoyaltyBPS[_tokensExtension[tokenId]].length > 0) {
            return _extensionRoyaltyBPS[_tokensExtension[tokenId]];
        }
        return _extensionRoyaltyBPS[address(this)];        
    }

    function _getRoyaltyInfo(uint256 tokenId, uint256 value) view internal returns (address receiver, uint256 amount){
        address payable[] storage receivers = _getRoyaltyReceivers(tokenId);
        require(receivers.length <= 1, "More than 1 royalty receiver");
        
        if (receivers.length == 0) {
            return (address(this), 0);
        }
        return (receivers[0], _getRoyaltyBPS(tokenId)[0]*value/10000);
    }

    /**
     * Set royalties for a token
     */
    function _setRoyalties(uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints) internal {
        require(receivers.length == basisPoints.length, "Invalid input");
        uint256 totalBasisPoints;
        for (uint i = 0; i < basisPoints.length; i++) {
            totalBasisPoints += basisPoints[i];
        }
        require(totalBasisPoints < 10000, "Invalid total royalties");
        _tokenRoyaltyReceivers[tokenId] = receivers;
        _tokenRoyaltyBPS[tokenId] = basisPoints;
        emit RoyaltiesUpdated(tokenId, receivers, basisPoints);
    }

    /**
     * Set royalties for all tokens of an extension
     */
    function _setRoyaltiesExtension(address extension, address payable[] calldata receivers, uint256[] calldata basisPoints) internal {
        require(receivers.length == basisPoints.length, "Invalid input");
        uint256 totalBasisPoints;
        for (uint i = 0; i < basisPoints.length; i++) {
            totalBasisPoints += basisPoints[i];
        }
        require(totalBasisPoints < 10000, "Invalid total royalties");
        _extensionRoyaltyReceivers[extension] = receivers;
        _extensionRoyaltyBPS[extension] = basisPoints;
        if (extension == address(this)) {
            emit DefaultRoyaltiesUpdated(receivers, basisPoints);
        } else {
            emit ExtensionRoyaltiesUpdated(extension, receivers, basisPoints);
        }
    }


}

/**
 * @dev Core ERC721 creator interface
 */
interface IERC721CreatorCore is ICreatorCore {

    /**
     * @dev mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBase(address to) external returns (uint256);

    /**
     * @dev mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBase(address to, string calldata uri) external returns (uint256);

    /**
     * @dev batch mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBaseBatch(address to, uint16 count) external returns (uint256[] memory);

    /**
     * @dev batch mint a token with no extension. Can only be called by an admin.
     * Returns tokenId minted
     */
    function mintBaseBatch(address to, string[] calldata uris) external returns (uint256[] memory);

    /**
     * @dev mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtension(address to) external returns (uint256);

    /**
     * @dev mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtension(address to, string calldata uri) external returns (uint256);

    /**
     * @dev batch mint a token. Can only be called by a registered extension.
     * Returns tokenIds minted
     */
    function mintExtensionBatch(address to, uint16 count) external returns (uint256[] memory);

    /**
     * @dev batch mint a token. Can only be called by a registered extension.
     * Returns tokenId minted
     */
    function mintExtensionBatch(address to, string[] calldata uris) external returns (uint256[] memory);

    /**
     * @dev burn a token. Can only be called by token owner or approved address.
     * On burn, calls back to the registered extension's onBurn method
     */
    function burn(uint256 tokenId) external;

}

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

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

/**
 * @dev Core ERC721 creator implementation
 */
abstract contract ERC721CreatorCore is CreatorCore, IERC721CreatorCore {

    using EnumerableSet for EnumerableSet.AddressSet;

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

    /**
     * @dev See {ICreatorCore-setApproveTransferExtension}.
     */
    function setApproveTransferExtension(bool enabled) external override extensionRequired {
        require(!enabled || ERC165Checker.supportsInterface(msg.sender, type(IERC721CreatorExtensionApproveTransfer).interfaceId), "Extension must implement IERC721CreatorExtensionApproveTransfer");
        if (_extensionApproveTransfers[msg.sender] != enabled) {
            _extensionApproveTransfers[msg.sender] = enabled;
            emit ExtensionApproveTransferUpdated(msg.sender, enabled);
        }
    }

    /**
     * @dev Set mint permissions for an extension
     */
    function _setMintPermissions(address extension, address permissions) internal {
        require(_extensions.contains(extension), "CreatorCore: Invalid extension");
        require(permissions == address(0x0) || ERC165Checker.supportsInterface(permissions, type(IERC721CreatorMintPermissions).interfaceId), "Invalid address");
        if (_extensionPermissions[extension] != permissions) {
            _extensionPermissions[extension] = permissions;
            emit MintPermissionsUpdated(extension, permissions, msg.sender);
        }
    }

    /**
     * Check if an extension can mint
     */
    function _checkMintPermissions(address to, uint256 tokenId) internal {
        if (_extensionPermissions[msg.sender] != address(0x0)) {
            IERC721CreatorMintPermissions(_extensionPermissions[msg.sender]).approveMint(msg.sender, to, tokenId);
        }
    }

    /**
     * Override for post mint actions
     */
    function _postMintBase(address, uint256) internal virtual {}

    
    /**
     * Override for post mint actions
     */
    function _postMintExtension(address, uint256) internal virtual {}

    /**
     * Post-burning callback and metadata cleanup
     */
    function _postBurn(address owner, uint256 tokenId) internal virtual {
        // Callback to originating extension if needed
        if (_tokensExtension[tokenId] != address(this)) {
           if (ERC165Checker.supportsInterface(_tokensExtension[tokenId], type(IERC721CreatorExtensionBurnable).interfaceId)) {
               IERC721CreatorExtensionBurnable(_tokensExtension[tokenId]).onBurn(owner, tokenId);
           }
        }
        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }    
        // Delete token origin extension tracking
        delete _tokensExtension[tokenId];    
    }

    /**
     * Approve a transfer
     */
    function _approveTransfer(address from, address to, uint256 tokenId) internal {
       if (_extensionApproveTransfers[_tokensExtension[tokenId]]) {
           require(IERC721CreatorExtensionApproveTransfer(_tokensExtension[tokenId]).approveTransfer(from, to, tokenId), "ERC721Creator: Extension approval failure");
       }
    }

}

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden
     * in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not 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 _owners[tokenId] != address(0);
    }

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

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

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

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

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

        _balances[to] += 1;
        _owners[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);

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

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

        _balances[owner] -= 1;
        delete _owners[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");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

/**
 * @dev ERC721Creator implementation
 */
contract ERC721Creator is AdminControl, ERC721, ERC721CreatorCore {

    constructor (string memory _name, string memory _symbol) ERC721(_name, _symbol) {
    }
    
    string public arweaveAssetsJSON;
    bytes32 public answer = 0x89891b11a799ba288fdbb0082e23fd93e4f50339f69804ccc5272436e759ef89;

    
    function verifyAnswer(string memory _answer)
    public
    view 
    returns(bool)
    {
      return answer == sha256(abi.encodePacked(_answer));
    }
    
    
    function setArweaveAssetsJSON(string memory _arweaveAssetsJSON)
        public
        adminRequired
    {
        arweaveAssetsJSON = _arweaveAssetsJSON;
    }

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


    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
        _approveTransfer(from, to, tokenId);    
    }

    /**
     * @dev See {ICreatorCore-registerExtension}.
     */
    function registerExtension(address extension, string calldata baseURI) external override adminRequired nonBlacklistRequired(extension) {
        _registerExtension(extension, baseURI, false);
    }

    /**
     * @dev See {ICreatorCore-registerExtension}.
     */
    function registerExtension(address extension, string calldata baseURI, bool baseURIIdentical) external override adminRequired nonBlacklistRequired(extension) {
        _registerExtension(extension, baseURI, baseURIIdentical);
    }


    /**
     * @dev See {ICreatorCore-unregisterExtension}.
     */
    function unregisterExtension(address extension) external override adminRequired {
        _unregisterExtension(extension);
    }

    /**
     * @dev See {ICreatorCore-blacklistExtension}.
     */
    function blacklistExtension(address extension) external override adminRequired {
        _blacklistExtension(extension);
    }

    /**
     * @dev See {ICreatorCore-setBaseTokenURIExtension}.
     */
    function setBaseTokenURIExtension(string calldata uri) external override extensionRequired {
        _setBaseTokenURIExtension(uri, false);
    }

    /**
     * @dev See {ICreatorCore-setBaseTokenURIExtension}.
     */
    function setBaseTokenURIExtension(string calldata uri, bool identical) external override extensionRequired {
        _setBaseTokenURIExtension(uri, identical);
    }

    /**
     * @dev See {ICreatorCore-setTokenURIPrefixExtension}.
     */
    function setTokenURIPrefixExtension(string calldata prefix) external override extensionRequired {
        _setTokenURIPrefixExtension(prefix);
    }

    /**
     * @dev See {ICreatorCore-setTokenURIExtension}.
     */
    function setTokenURIExtension(uint256 tokenId, string calldata uri) external override extensionRequired {
        _setTokenURIExtension(tokenId, uri);
    }

    /**
     * @dev See {ICreatorCore-setTokenURIExtension}.
     */
    function setTokenURIExtension(uint256[] memory tokenIds, string[] calldata uris) external override extensionRequired {
        require(tokenIds.length == uris.length, "Invalid input");
        for (uint i = 0; i < tokenIds.length; i++) {
            _setTokenURIExtension(tokenIds[i], uris[i]);            
        }
    }

    /**
     * @dev See {ICreatorCore-setBaseTokenURI}.
     */
    function setBaseTokenURI(string calldata uri) external override adminRequired {
        _setBaseTokenURI(uri);
    }

    /**
     * @dev See {ICreatorCore-setTokenURIPrefix}.
     */
    function setTokenURIPrefix(string calldata prefix) external override adminRequired {
        _setTokenURIPrefix(prefix);
    }

    /**
     * @dev See {ICreatorCore-setTokenURI}.
     */
    function setTokenURI(uint256 tokenId, string calldata uri) external override adminRequired {
        _setTokenURI(tokenId, uri);
    }

    /**
     * @dev See {ICreatorCore-setTokenURI}.
     */
    function setTokenURI(uint256[] memory tokenIds, string[] calldata uris) external override adminRequired {
        require(tokenIds.length == uris.length, "Invalid input");
        for (uint i = 0; i < tokenIds.length; i++) {
            _setTokenURI(tokenIds[i], uris[i]);            
        }
    }

    /**
     * @dev See {ICreatorCore-setMintPermissions}.
     */
    function setMintPermissions(address extension, address permissions) external override adminRequired {
        _setMintPermissions(extension, permissions);
    }

    /**
     * @dev See {IERC721CreatorCore-mintBase}.
     */
    function mintBase(address to) public virtual override nonReentrant adminRequired returns(uint256) {
        return _mintBase(to, "");
    }

    /**
     * @dev See {IERC721CreatorCore-mintBase}.
     */
    function mintBase(address to, string calldata uri) public virtual override nonReentrant adminRequired returns(uint256) {
        return _mintBase(to, uri);
    }

    /**
     * @dev See {IERC721CreatorCore-mintBaseBatch}.
     */
    function mintBaseBatch(address to, uint16 count) public virtual override nonReentrant adminRequired returns(uint256[] memory tokenIds) {
        tokenIds = new uint256[](count);
        for (uint16 i = 0; i < count; i++) {
            tokenIds[i] = _mintBase(to, "");
        }
        return tokenIds;
    }

    /**
     * @dev See {IERC721CreatorCore-mintBaseBatch}.
     */
    function mintBaseBatch(address to, string[] calldata uris) public virtual override nonReentrant adminRequired returns(uint256[] memory tokenIds) {
        tokenIds = new uint256[](uris.length);
        for (uint i = 0; i < uris.length; i++) {
            tokenIds[i] = _mintBase(to, uris[i]);
        }
        return tokenIds;
    }

    /**
     * @dev Mint token with no extension
     */
    function _mintBase(address to, string memory uri) internal virtual returns(uint256 tokenId) {
        _tokenCount++;
        tokenId = _tokenCount;

        // Track the extension that minted the token
        _tokensExtension[tokenId] = address(this);

        _safeMint(to, tokenId);

        if (bytes(uri).length > 0) {
            _tokenURIs[tokenId] = uri;
        }

        // Call post mint
        _postMintBase(to, tokenId);
        return tokenId;
    }


    /**
     * @dev See {IERC721CreatorCore-mintExtension}.
     */
    function mintExtension(address to) public virtual override nonReentrant extensionRequired returns(uint256) {
        return _mintExtension(to, "");
    }

    /**
     * @dev See {IERC721CreatorCore-mintExtension}.
     */
    function mintExtension(address to, string calldata uri) public virtual override nonReentrant extensionRequired returns(uint256) {
        return _mintExtension(to, uri);
    }

    /**
     * @dev See {IERC721CreatorCore-mintExtensionBatch}.
     */
    function mintExtensionBatch(address to, uint16 count) public virtual override nonReentrant extensionRequired returns(uint256[] memory tokenIds) {
        tokenIds = new uint256[](count);
        for (uint16 i = 0; i < count; i++) {
            tokenIds[i] = _mintExtension(to, "");
        }
        return tokenIds;
    }

    /**
     * @dev See {IERC721CreatorCore-mintExtensionBatch}.
     */
    function mintExtensionBatch(address to, string[] calldata uris) public virtual override nonReentrant extensionRequired returns(uint256[] memory tokenIds) {
        tokenIds = new uint256[](uris.length);
        for (uint i = 0; i < uris.length; i++) {
            tokenIds[i] = _mintExtension(to, uris[i]);
        }
    }
    
    /**
     * @dev Mint token via extension
     */
    function _mintExtension(address to, string memory uri) internal virtual returns(uint256 tokenId) {
        _tokenCount++;
        tokenId = _tokenCount;

        _checkMintPermissions(to, tokenId);

        // Track the extension that minted the token
        _tokensExtension[tokenId] = msg.sender;

        _safeMint(to, tokenId);

        if (bytes(uri).length > 0) {
            _tokenURIs[tokenId] = uri;
        }
        
        // Call post mint
        _postMintExtension(to, tokenId);
        return tokenId;
    }

    /**
     * @dev See {IERC721CreatorCore-tokenExtension}.
     */
    function tokenExtension(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "Nonexistent token");
        return _tokenExtension(tokenId);
    }

    /**
     * @dev See {IERC721CreatorCore-burn}.
     */
    function burn(uint256 tokenId) public virtual override nonReentrant {
        require(_isApprovedOrOwner(msg.sender, tokenId), "Caller is not owner nor approved");
        address owner = ownerOf(tokenId);
        _burn(tokenId);
        _postBurn(owner, tokenId);
    }

    /**
     * @dev See {ICreatorCore-setRoyalties}.
     */
    function setRoyalties(address payable[] calldata receivers, uint256[] calldata basisPoints) external override adminRequired {
        _setRoyaltiesExtension(address(this), receivers, basisPoints);
    }

    /**
     * @dev See {ICreatorCore-setRoyalties}.
     */
    function setRoyalties(uint256 tokenId, address payable[] calldata receivers, uint256[] calldata basisPoints) external override adminRequired {
        require(_exists(tokenId), "Nonexistent token");
        _setRoyalties(tokenId, receivers, basisPoints);
    }

    /**
     * @dev See {ICreatorCore-setRoyaltiesExtension}.
     */
    function setRoyaltiesExtension(address extension, address payable[] calldata receivers, uint256[] calldata basisPoints) external override adminRequired {
        _setRoyaltiesExtension(extension, receivers, basisPoints);
    }

    /**
     * @dev {See ICreatorCore-getRoyalties}.
     */
    function getRoyalties(uint256 tokenId) external view virtual override returns (address payable[] memory, uint256[] memory) {
        require(_exists(tokenId), "Nonexistent token");
        return _getRoyalties(tokenId);
    }

    /**
     * @dev {See ICreatorCore-getFees}.
     */
    function getFees(uint256 tokenId) external view virtual override returns (address payable[] memory, uint256[] memory) {
        require(_exists(tokenId), "Nonexistent token");
        return _getRoyalties(tokenId);
    }

    /**
     * @dev {See ICreatorCore-getFeeRecipients}.
     */
    function getFeeRecipients(uint256 tokenId) external view virtual override returns (address payable[] memory) {
        require(_exists(tokenId), "Nonexistent token");
        return _getRoyaltyReceivers(tokenId);
    }

    /**
     * @dev {See ICreatorCore-getFeeBps}.
     */
    function getFeeBps(uint256 tokenId) external view virtual override returns (uint[] memory) {
        require(_exists(tokenId), "Nonexistent token");
        return _getRoyaltyBPS(tokenId);
    }
    
    /**
     * @dev {See ICreatorCore-royaltyInfo}.
     */
    function royaltyInfo(uint256 tokenId, uint256 value) external view virtual override returns (address, uint256) {
        require(_exists(tokenId), "Nonexistent token");
        return _getRoyaltyInfo(tokenId, value);
    } 

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
        return _tokenURI(tokenId);
    }
    
}

contract ThePixelPortraits is ERC721Creator {
    constructor() ERC721Creator("The Pixel Portraits", "PXP") {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"AdminRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address payable[]","name":"receivers","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"DefaultRoyaltiesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"ExtensionApproveTransferUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"ExtensionBlacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"ExtensionRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":false,"internalType":"address payable[]","name":"receivers","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"ExtensionRoyaltiesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"ExtensionUnregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"extension","type":"address"},{"indexed":true,"internalType":"address","name":"permissions","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"MintPermissionsUpdated","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":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address payable[]","name":"receivers","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"RoyaltiesUpdated","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":"answer","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"admin","type":"address"}],"name":"approveAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"arweaveAssetsJSON","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"extension","type":"address"}],"name":"blacklistExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmins","outputs":[{"internalType":"address[]","name":"admins","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExtensions","outputs":[{"internalType":"address[]","name":"extensions","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFees","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRoyalties","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"isAdmin","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":"to","type":"address"}],"name":"mintBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"name":"mintBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string[]","name":"uris","type":"string[]"}],"name":"mintBaseBatch","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint16","name":"count","type":"uint16"}],"name":"mintBaseBatch","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintExtension","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"name":"mintExtension","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"string[]","name":"uris","type":"string[]"}],"name":"mintExtensionBatch","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint16","name":"count","type":"uint16"}],"name":"mintExtensionBatch","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"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":[{"internalType":"address","name":"extension","type":"address"},{"internalType":"string","name":"baseURI","type":"string"}],"name":"registerExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"extension","type":"address"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"bool","name":"baseURIIdentical","type":"bool"}],"name":"registerExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"}],"name":"revokeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"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":"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":"bool","name":"enabled","type":"bool"}],"name":"setApproveTransferExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_arweaveAssetsJSON","type":"string"}],"name":"setArweaveAssetsJSON","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseTokenURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"},{"internalType":"bool","name":"identical","type":"bool"}],"name":"setBaseTokenURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"extension","type":"address"},{"internalType":"address","name":"permissions","type":"address"}],"name":"setMintPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address payable[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"extension","type":"address"},{"internalType":"address payable[]","name":"receivers","type":"address[]"},{"internalType":"uint256[]","name":"basisPoints","type":"uint256[]"}],"name":"setRoyaltiesExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"uris","type":"string[]"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"uris","type":"string[]"}],"name":"setTokenURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setTokenURIExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"prefix","type":"string"}],"name":"setTokenURIPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"prefix","type":"string"}],"name":"setTokenURIPrefixExtension","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":"tokenId","type":"uint256"}],"name":"tokenExtension","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"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":[{"internalType":"address","name":"extension","type":"address"}],"name":"unregisterExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_answer","type":"string"}],"name":"verifyAnswer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040526000600a557f89891b11a799ba288fdbb0082e23fd93e4f50339f69804ccc5272436e759ef89601b553480156200003a57600080fd5b506040518060400160405280601381526020017f54686520506978656c20506f72747261697473000000000000000000000000008152506040518060400160405280600381526020016205058560ec1b81525081816000620000a16200012560201b60201c565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001805581516200010490600490602085019062000129565b5080516200011a90600590602084019062000129565b50505050506200020c565b3390565b8280546200013790620001cf565b90600052602060002090601f0160209004810192826200015b5760008555620001a6565b82601f106200017657805160ff1916838001178555620001a6565b82800160010185558215620001a6579182015b82811115620001a657825182559160200191906001019062000189565b50620001b4929150620001b8565b5090565b5b80821115620001b45760008155600101620001b9565b600181811c90821680620001e457607f821691505b602082108114156200020657634e487b7160e01b600052602260045260246000fd5b50919050565b6153f0806200021c6000396000f3fe608060405234801561001057600080fd5b506004361061038e5760003560e01c8063715018a6116101de578063b0fe87c91161010f578063e00aab4b116100ad578063f0cdc4991161007c578063f0cdc49914610806578063f2fde38b14610819578063f528a6271461082c578063fe2e1f581461083457600080fd5b8063e00aab4b14610791578063e92a89f6146107a4578063e985e9c5146107b7578063ed42b0c1146107f357600080fd5b8063bb3bafd6116100e9578063bb3bafd61461074a578063c87b56dd1461076b578063ce8aee9d1461077e578063d5a06d4c1461074a57600080fd5b8063b0fe87c914610704578063b88d4fde14610717578063b9c4d9fb1461072a57600080fd5b80638da5cb5b1161017c578063a22cb46511610156578063a22cb465146106b8578063aafb2d44146106cb578063ac0c8cfa146106de578063ad2d0ddd146106f157600080fd5b80638da5cb5b1461068c57806395d89b411461069d57806399e0dd7c146106a557600080fd5b80637aa15f16116101b85780637aa15f161461065557806382dcc0c81461066857806383b7db631461067b57806385bb7d691461068357600080fd5b8063715018a61461062757806372ff03d31461062f5780637884af441461064257600080fd5b806330176e13116102c357806342842e0e116102615780636352211e116102305780636352211e146105db57806366d1e9d0146105ee5780636d73e6691461060157806370a082311461061457600080fd5b806342842e0e1461058f57806342966c68146105a257806356b1b300146105b557806361e5bc6b146105c857600080fd5b8063332dd1ae1161029d578063332dd1ae1461054357806338e52e78146105565780633e6134b8146105695780633f0f37f61461057c57600080fd5b806330176e13146105085780633071a0f91461051b57806331ae450b1461052e57600080fd5b806320e4afe21161033057806324d7806c1161030a57806324d7806c1461048f5780632928ca58146104a25780632a55205a146104c35780632d345670146104f557600080fd5b806320e4afe214610456578063239be3171461046957806323b872dd1461047c57600080fd5b8063081812fc1161036c578063081812fc146103e5578063095ea7b3146104105780630ebd4c7f14610423578063162094c41461044357600080fd5b806301ffc9a71461039357806302e7afb7146103bb57806306fdde03146103d0575b600080fd5b6103a66103a136600461456c565b610847565b60405190151581526020015b60405180910390f35b6103ce6103c936600461459e565b610876565b005b6103d86108d5565b6040516103b29190614613565b6103f86103f3366004614626565b610967565b6040516001600160a01b0390911681526020016103b2565b6103ce61041e36600461463f565b6109fc565b610436610431366004614626565b610b30565b6040516103b291906146a6565b6103ce6104513660046146fa565b610bc6565b6103ce610464366004614789565b610c1b565b6103f8610477366004614626565b610cad565b6103ce61048a366004614802565b610cea565b6103a661049d36600461459e565b610d1b565b6104b56104b036600461459e565b610d54565b6040519081526020016103b2565b6104d66104d1366004614843565b610dc8565b604080516001600160a01b0390931683526020830191909152016103b2565b6103ce61050336600461459e565b610e14565b6103ce610516366004614865565b610ec3565b6103ce6105293660046148a6565b610f4c565b610536610ffa565b6040516103b291906148e1565b6103ce61055136600461492e565b6110a8565b610436610564366004614999565b6110ff565b6103ce610577366004614865565b61123c565b6103ce61058a3660046149ee565b61126f565b6103ce61059d366004614802565b611316565b6103ce6105b0366004614626565b611331565b6103ce6105c3366004614b00565b6113d7565b6103ce6105d6366004614b48565b611434565b6103f86105e9366004614626565b6114ff565b6103ce6105fc366004614865565b611576565b6103ce61060f36600461459e565b6115a7565b6104b561062236600461459e565b611651565b6103ce6116d8565b6104b561063d36600461459e565b61177c565b6104b56106503660046148a6565b611809565b610436610663366004614999565b6118c9565b6103ce610676366004614c07565b611a1d565b610536611a4f565b6104b5601b5481565b6000546001600160a01b03166103f8565b6103d8611af9565b6103ce6106b3366004614865565b611b08565b6103ce6106c6366004614c5d565b611b5c565b6103ce6106d9366004614b48565b611c21565b6103ce6106ec366004614c96565b611d0f565b6104366106ff366004614cb3565b611e33565b6103ce610712366004614ce8565b611f59565b6103ce610725366004614d27565b611fb0565b61073d610738366004614626565b611fe2565b6040516103b29190614ddf565b61075d610758366004614626565b612081565b6040516103b2929190614df2565b6103d8610779366004614626565b61217d565b6103ce61078c36600461459e565b6121bd565b61043661079f366004614cb3565b612210565b6103ce6107b23660046146fa565b612308565b6103a66107c5366004614e20565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b6103a6610801366004614b00565b61233a565b6103ce610814366004614e20565b6123b3565b6103ce61082736600461459e565b612407565b6103d8612521565b6104b56108423660046148a6565b6125af565b600061085282612640565b80610861575061086182612665565b806108705750610870826126a0565b92915050565b336108896000546001600160a01b031690565b6001600160a01b031614806108a457506108a46002336126d5565b6108c95760405162461bcd60e51b81526004016108c090614e4e565b60405180910390fd5b6108d2816126fa565b50565b6060600480546108e490614e92565b80601f016020809104026020016040519081016040528092919081815260200182805461091090614e92565b801561095d5780601f106109325761010080835404028352916020019161095d565b820191906000526020600020905b81548152906001019060200180831161094057829003601f168201915b5050505050905090565b6000818152600660205260408120546001600160a01b03166109e05760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108c0565b506000908152600860205260409020546001600160a01b031690565b6000610a07826114ff565b9050806001600160a01b0316836001600160a01b03161415610a755760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016108c0565b336001600160a01b0382161480610aaf57506001600160a01b038116600090815260096020908152604080832033845290915290205460ff165b610b215760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016108c0565b610b2b83836127f6565b505050565b6000818152600660205260409020546060906001600160a01b0316610b675760405162461bcd60e51b81526004016108c090614ec7565b610b7082612864565b805480602002602001604051908101604052809291908181526020018280548015610bba57602002820191906000526020600020905b815481526020019060010190808311610ba6575b50505050509050919050565b33610bd96000546001600160a01b031690565b6001600160a01b03161480610bf45750610bf46002336126d5565b610c105760405162461bcd60e51b81526004016108c090614e4e565b610b2b8383836128f0565b33610c2e6000546001600160a01b031690565b6001600160a01b03161480610c495750610c496002336126d5565b610c655760405162461bcd60e51b81526004016108c090614e4e565b6000858152600660205260409020546001600160a01b0316610c995760405162461bcd60e51b81526004016108c090614ec7565b610ca6858585858561295f565b5050505050565b6000818152600660205260408120546001600160a01b0316610ce15760405162461bcd60e51b81526004016108c090614ec7565b61087082612aa8565b610cf43382612b65565b610d105760405162461bcd60e51b81526004016108c090614ef2565b610b2b838383612c5c565b6000816001600160a01b0316610d396000546001600160a01b031690565b6001600160a01b0316148061087057506108706002836126d5565b600060026001541415610d795760405162461bcd60e51b81526004016108c090614f43565b6002600155610d89600b336126d5565b610da55760405162461bcd60e51b81526004016108c090614f7a565b610dbe8260405180602001604052806000815250612e07565b6001805592915050565b60008281526006602052604081205481906001600160a01b0316610dfe5760405162461bcd60e51b81526004016108c090614ec7565b610e088484612e81565b915091505b9250929050565b6000546001600160a01b03163314610e6e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b610e796002826126d5565b156108d25760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610ebf600282612f69565b5050565b33610ed66000546001600160a01b031690565b6001600160a01b03161480610ef15750610ef16002336126d5565b610f0d5760405162461bcd60e51b81526004016108c090614e4e565b610ebf82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f7e92505050565b33610f5f6000546001600160a01b031690565b6001600160a01b03161480610f7a5750610f7a6002336126d5565b610f965760405162461bcd60e51b81526004016108c090614e4e565b82610fa2600d826126d5565b15610fe75760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b610ff48484846000612f9e565b50505050565b606061100660026130d9565b6001600160401b0381111561101d5761101d614a55565b604051908082528060200260200182016040528015611046578160200160208202803683370190505b50905060005b61105660026130d9565b8110156110a4576110686002826130e3565b82828151811061107a5761107a614fb1565b6001600160a01b03909216602092830291909101909101528061109c81614fdd565b91505061104c565b5090565b336110bb6000546001600160a01b031690565b6001600160a01b031614806110d657506110d66002336126d5565b6110f25760405162461bcd60e51b81526004016108c090614e4e565b610ff430858585856130ef565b6060600260015414156111245760405162461bcd60e51b81526004016108c090614f43565b6002600155611134600b336126d5565b6111505760405162461bcd60e51b81526004016108c090614f7a565b816001600160401b0381111561116857611168614a55565b604051908082528060200260200182016040528015611191578160200160208202803683370190505b50905060005b8281101561123057611201858585848181106111b5576111b5614fb1565b90506020028101906111c79190614ff8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e0792505050565b82828151811061121357611213614fb1565b60209081029190910101528061122881614fdd565b915050611197565b50600180559392505050565b611247600b336126d5565b6112635760405162461bcd60e51b81526004016108c090614f7a565b610ebf828260006132a0565b336112826000546001600160a01b031690565b6001600160a01b0316148061129d575061129d6002336126d5565b6112b95760405162461bcd60e51b81526004016108c090614e4e565b836112c5600d826126d5565b1561130a5760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b610ca685858585612f9e565b610b2b83838360405180602001604052806000815250611fb0565b600260015414156113545760405162461bcd60e51b81526004016108c090614f43565b60026001556113633382612b65565b6113af5760405162461bcd60e51b815260206004820181905260248201527f43616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016108c0565b60006113ba826114ff565b90506113c5826132dd565b6113cf8183613384565b505060018055565b336113ea6000546001600160a01b031690565b6001600160a01b0316148061140557506114056002336126d5565b6114215760405162461bcd60e51b81526004016108c090614e4e565b8051610ebf90601a90602084019061438a565b61143f600b336126d5565b61145b5760405162461bcd60e51b81526004016108c090614f7a565b8251811461149b5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b60005b8351811015610ff4576114ed8482815181106114bc576114bc614fb1565b60200260200101518484848181106114d6576114d6614fb1565b90506020028101906114e89190614ff8565b61349a565b806114f781614fdd565b91505061149e565b6000818152600660205260408120546001600160a01b0316806108705760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016108c0565b611581600b336126d5565b61159d5760405162461bcd60e51b81526004016108c090614f7a565b610ebf82826134f0565b6000546001600160a01b031633146116015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b61160c6002826126d5565b6108d25760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610ebf60028261350a565b60006001600160a01b0382166116bc5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016108c0565b506001600160a01b031660009081526007602052604090205490565b6000546001600160a01b031633146117325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000600260015414156117a15760405162461bcd60e51b81526004016108c090614f43565b6002600155336117b96000546001600160a01b031690565b6001600160a01b031614806117d457506117d46002336126d5565b6117f05760405162461bcd60e51b81526004016108c090614e4e565b610dbe826040518060200160405280600081525061351f565b60006002600154141561182e5760405162461bcd60e51b81526004016108c090614f43565b6002600155336118466000546001600160a01b031690565b6001600160a01b0316148061186157506118616002336126d5565b61187d5760405162461bcd60e51b81526004016108c090614e4e565b6118bd8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061351f92505050565b60018055949350505050565b6060600260015414156118ee5760405162461bcd60e51b81526004016108c090614f43565b6002600155336119066000546001600160a01b031690565b6001600160a01b0316148061192157506119216002336126d5565b61193d5760405162461bcd60e51b81526004016108c090614e4e565b816001600160401b0381111561195557611955614a55565b60405190808252806020026020018201604052801561197e578160200160208202803683370190505b50905060005b82811015611230576119ee858585848181106119a2576119a2614fb1565b90506020028101906119b49190614ff8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061351f92505050565b828281518110611a0057611a00614fb1565b602090810291909101015280611a1581614fdd565b915050611984565b611a28600b336126d5565b611a445760405162461bcd60e51b81526004016108c090614f7a565b610b2b8383836132a0565b6060611a5b600b6130d9565b6001600160401b03811115611a7257611a72614a55565b604051908082528060200260200182016040528015611a9b578160200160208202803683370190505b50905060005b611aab600b6130d9565b8110156110a457611abd600b826130e3565b828281518110611acf57611acf614fb1565b6001600160a01b039092166020928302919091019091015280611af181614fdd565b915050611aa1565b6060600580546108e490614e92565b33611b1b6000546001600160a01b031690565b6001600160a01b03161480611b365750611b366002336126d5565b611b525760405162461bcd60e51b81526004016108c090614e4e565b610ebf8282613562565b6001600160a01b038216331415611bb55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108c0565b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b33611c346000546001600160a01b031690565b6001600160a01b03161480611c4f5750611c4f6002336126d5565b611c6b5760405162461bcd60e51b81526004016108c090614e4e565b82518114611cab5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b60005b8351811015610ff457611cfd848281518110611ccc57611ccc614fb1565b6020026020010151848484818110611ce657611ce6614fb1565b9050602002810190611cf89190614ff8565b6128f0565b80611d0781614fdd565b915050611cae565b611d1a600b336126d5565b611d365760405162461bcd60e51b81526004016108c090614f7a565b801580611d4f5750611d4f33634ce6d51160e11b61357c565b611dc15760405162461bcd60e51b815260206004820152603f60248201527f457874656e73696f6e206d75737420696d706c656d656e74204945524337323160448201527f43726561746f72457874656e73696f6e417070726f76655472616e736665720060648201526084016108c0565b3360009081526010602052604090205460ff161515811515146108d25733600081815260106020908152604091829020805460ff191685151590811790915591519182527f072a7592283e2c2d1d56d21517ff6013325e0f55483f4828373ff4d98b0a1a36910160405180910390a250565b606060026001541415611e585760405162461bcd60e51b81526004016108c090614f43565b600260015533611e706000546001600160a01b031690565b6001600160a01b03161480611e8b5750611e8b6002336126d5565b611ea75760405162461bcd60e51b81526004016108c090614e4e565b8161ffff166001600160401b03811115611ec357611ec3614a55565b604051908082528060200260200182016040528015611eec578160200160208202803683370190505b50905060005b8261ffff168161ffff161015611f4e57611f1b846040518060200160405280600081525061351f565b828261ffff1681518110611f3157611f31614fb1565b602090810291909101015280611f468161503e565b915050611ef2565b506001805592915050565b33611f6c6000546001600160a01b031690565b6001600160a01b03161480611f875750611f876002336126d5565b611fa35760405162461bcd60e51b81526004016108c090614e4e565b610ca685858585856130ef565b611fba3383612b65565b611fd65760405162461bcd60e51b81526004016108c090614ef2565b610ff484848484613598565b6000818152600660205260409020546060906001600160a01b03166120195760405162461bcd60e51b81526004016108c090614ec7565b612022826135cb565b805480602002602001604051908101604052809291908181526020018280548015610bba57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120585750505050509050919050565b6060806120a5836000908152600660205260409020546001600160a01b0316151590565b6120c15760405162461bcd60e51b81526004016108c090614ec7565b6120ca83613657565b81546040805160208084028201810190925282815291849183018282801561211b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120fd575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561216d57602002820191906000526020600020905b815481526020019060010190808311612159575b5050505050905091509150915091565b6000818152600660205260409020546060906001600160a01b03166121b45760405162461bcd60e51b81526004016108c090614ec7565b61087082613675565b336121d06000546001600160a01b031690565b6001600160a01b031614806121eb57506121eb6002336126d5565b6122075760405162461bcd60e51b81526004016108c090614e4e565b6108d281613926565b6060600260015414156122355760405162461bcd60e51b81526004016108c090614f43565b6002600155612245600b336126d5565b6122615760405162461bcd60e51b81526004016108c090614f7a565b8161ffff166001600160401b0381111561227d5761227d614a55565b6040519080825280602002602001820160405280156122a6578160200160208202803683370190505b50905060005b8261ffff168161ffff161015611f4e576122d58460405180602001604052806000815250612e07565b828261ffff16815181106122eb576122eb614fb1565b6020908102919091010152806123008161503e565b9150506122ac565b612313600b336126d5565b61232f5760405162461bcd60e51b81526004016108c090614f7a565b610b2b83838361349a565b600060028260405160200161234f9190615060565b60408051601f198184030181529082905261236991615060565b602060405180830381855afa158015612386573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906123a9919061507c565b601b541492915050565b336123c66000546001600160a01b031690565b6001600160a01b031614806123e157506123e16002336126d5565b6123fd5760405162461bcd60e51b81526004016108c090614e4e565b610ebf8282613977565b6000546001600160a01b031633146124615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b6001600160a01b0381166124c65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c0565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b601a805461252e90614e92565b80601f016020809104026020016040519081016040528092919081815260200182805461255a90614e92565b80156125a75780601f1061257c576101008083540402835291602001916125a7565b820191906000526020600020905b81548152906001019060200180831161258a57829003601f168201915b505050505081565b6000600260015414156125d45760405162461bcd60e51b81526004016108c090614f43565b60026001556125e4600b336126d5565b6126005760405162461bcd60e51b81526004016108c090614f7a565b6118bd8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e0792505050565b60006001600160e01b03198216639088c20760e01b1480610870575061087082613aac565b60006001600160e01b031982166380ac58cd60e01b148061086157506001600160e01b03198216635b5e139f60e01b14806108705750610870825b60006001600160e01b03198216632a9f3abf60e11b148061087057506301ffc9a760e01b6001600160e01b0319831614610870565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6001600160a01b0381163014156127535760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f7420626c61636b6c69737420796f757273656c660000000000000060448201526064016108c0565b61275e600b826126d5565b156127a65760405133906001600160a01b038316907fd19cf84cf0fec6bec9ddfa29c63adf83a55707c712f32c8285d6180a7890147990600090a36127a4600b82612f69565b505b6127b1600d826126d5565b6108d25760405133906001600160a01b038316907f05ac7bc5a606cd92a63365f9fda244499b9add0526b22d99937b6bd88181059c90600090a3610ebf600d8261350a565b600081815260086020526040902080546001600160a01b0319166001600160a01b038416908117909155819061282b826114ff565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152601960205260408120541561288a5750600090815260196020526040902090565b6000828152601160209081526040808320546001600160a01b031683526017909152902054156128dc57506000908152601160209081526040808320546001600160a01b031683526017909152902090565b505030600090815260176020526040902090565b6000838152601160205260409020546001600160a01b031630146129465760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016108c0565b6000838152601560205260409020610ff490838361440a565b82811461299e5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b6000805b828110156129e2578383828181106129bc576129bc614fb1565b90506020020135826129ce9190615095565b9150806129da81614fdd565b9150506129a2565b506127108110612a2e5760405162461bcd60e51b8152602060048201526017602482015276496e76616c696420746f74616c20726f79616c7469657360481b60448201526064016108c0565b6000868152601860205260409020612a4790868661447e565b506000868152601960205260409020612a619084846144d1565b50857fabb46fe0761d77584bde75697647804ffd8113abd4d8d06bc664150395eccdee86868686604051612a9894939291906150ad565b60405180910390a2505050505050565b6000818152601160205260409020546001600160a01b031630811415612b105760405162461bcd60e51b815260206004820152601660248201527f4e6f20657874656e73696f6e20666f7220746f6b656e0000000000000000000060448201526064016108c0565b612b1b600d826126d5565b15612b605760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b919050565b6000818152600660205260408120546001600160a01b0316612bde5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108c0565b6000612be9836114ff565b9050806001600160a01b0316846001600160a01b03161480612c245750836001600160a01b0316612c1984610967565b6001600160a01b0316145b80612c5457506001600160a01b0380821660009081526009602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612c6f826114ff565b6001600160a01b031614612cd75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016108c0565b6001600160a01b038216612d395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108c0565b612d44838383613b42565b612d4f6000826127f6565b6001600160a01b0383166000908152600760205260408120805460019290612d78908490615131565b90915550506001600160a01b0382166000908152600760205260408120805460019290612da6908490615095565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805460009182612e1883614fdd565b9190505550600a549050612e2c8382613b4d565b600081815260116020526040902080546001600160a01b03191633179055612e548382613be1565b815115612e7c5760008181526015602090815260409091208351612e7a9285019061438a565b505b610870565b6000806000612e8f856135cb565b805490915060011015612ee45760405162461bcd60e51b815260206004820152601c60248201527f4d6f7265207468616e203120726f79616c74792072656365697665720000000060448201526064016108c0565b8054612ef7573060009250925050610e0d565b80600081548110612f0a57612f0a614fb1565b6000918252602090912001546001600160a01b031661271085612f2c88612864565b600081548110612f3e57612f3e614fb1565b9060005260206000200154612f539190615148565b612f5d919061517d565b92509250509250929050565b60006126f3836001600160a01b038416613bfb565b3060009081526012602090815260409091208251610ebf9284019061438a565b6001600160a01b038416301415612fea5760405162461bcd60e51b815260206004820152601060248201526f10dc99585d1bdc8e88125b9d985b1a5960821b60448201526064016108c0565b6001600160a01b0384163b61304f5760405162461bcd60e51b815260206004820152602560248201527f43726561746f723a20457874656e73696f6e206d757374206265206120636f6e6044820152641d1c9858dd60da1b60648201526084016108c0565b61305a600b856126d5565b610ff4576001600160a01b038416600090815260126020526040902061308190848461440a565b506001600160a01b038416600081815260136020526040808220805460ff1916851515179055513392917fd8cb8ba4086944eabf43c5535b7712015e4d4c714b24bf812c040ea5b7a3e42a91a3610ca6600b8561350a565b6000610870825490565b60006126f38383613ce8565b82811461312e5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b6000805b828110156131725783838281811061314c5761314c614fb1565b905060200201358261315e9190615095565b91508061316a81614fdd565b915050613132565b5061271081106131be5760405162461bcd60e51b8152602060048201526017602482015276496e76616c696420746f74616c20726f79616c7469657360481b60448201526064016108c0565b6001600160a01b03861660009081526016602052604090206131e190868661447e565b506001600160a01b03861660009081526017602052604090206132059084846144d1565b506001600160a01b038616301415613259577f2b6849d5976d799a5b0ca4dfd6b40a3d7afe9ea72c091fa01a958594f9a2659b8585858560405161324c94939291906150ad565b60405180910390a1613298565b856001600160a01b03167f535a93d2cb000582c0ebeaa9be4890ec6a287f98eb2df00c54c300612fd78d8f86868686604051612a9894939291906150ad565b505050505050565b3360009081526012602052604090206132ba90848461440a565b50336000908152601360205260409020805460ff19169115159190911790555050565b60006132e8826114ff565b90506132f681600084613b42565b6133016000836127f6565b6001600160a01b038116600090815260076020526040812080546001929061332a908490615131565b909155505060008281526006602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000818152601160205260409020546001600160a01b03163014613444576000818152601160205260409020546133cb906001600160a01b03166311686e4b60e21b61357c565b1561344457600081815260116020526040908190205490516311686e4b60e21b81526001600160a01b03848116600483015260248201849052909116906345a1b92c90604401600060405180830381600087803b15801561342b57600080fd5b505af115801561343f573d6000803e3d6000fd5b505050505b6000818152601560205260409020805461345d90614e92565b15905061347b57600081815260156020526040812061347b9161450b565b600090815260116020526040902080546001600160a01b031916905550565b6000838152601160205260409020546001600160a01b031633146129465760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016108c0565b336000908152601460205260409020610b2b90838361440a565b60006126f3836001600160a01b038416613d6e565b600a80546000918261353083614fdd565b9091555050600a54600081815260116020526040902080546001600160a01b031916301790559050612e548382613be1565b306000908152601460205260409020610b2b90838361440a565b600061358783613dbd565b80156126f357506126f38383613df0565b6135a3848484612c5c565b6135af84848484613ed9565b610ff45760405162461bcd60e51b81526004016108c090615191565b600081815260186020526040812054156135f15750600090815260186020526040902090565b6000828152601160209081526040808320546001600160a01b0316835260169091529020541561364357506000908152601160209081526040808320546001600160a01b031683526016909152902090565b505030600090815260166020526040902090565b600080613663836135cb565b61366c84612864565b91509150915091565b6000818152601160205260409020546060906001600160a01b031661369b600d826126d5565b156136e05760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b600083815260156020526040902080546136f990614e92565b159050613813576001600160a01b0381166000908152601460205260409020805461372390614e92565b159050613774576001600160a01b03811660009081526014602090815260408083208684526015835292819020905161375d93920161527d565b604051602081830303815290604052915050919050565b6000838152601560205260409020805461378d90614e92565b80601f01602080910402602001604051908101604052809291908181526020018280546137b990614e92565b80156138065780601f106137db57610100808354040283529160200191613806565b820191906000526020600020905b8154815290600101906020018083116137e957829003601f168201915b5050505050915050919050565b6138248163e9dc637560e01b61357c565b156138ab5760405163e9dc637560e01b8152306004820152602481018490526001600160a01b0382169063e9dc63759060440160006040518083038186803b15801561386f57600080fd5b505afa158015613883573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126f39190810190615292565b6001600160a01b03811660009081526013602052604090205460ff166138fd576001600160a01b03811660009081526012602052604090206138ec84613fe6565b60405160200161375d9291906152ff565b6001600160a01b0381166000908152601260205260409020805461378d90614e92565b50919050565b613931600b826126d5565b156108d25760405133906001600160a01b038316907fd19cf84cf0fec6bec9ddfa29c63adf83a55707c712f32c8285d6180a7890147990600090a3610ebf600b82612f69565b613982600b836126d5565b6139ce5760405162461bcd60e51b815260206004820152601e60248201527f43726561746f72436f72653a20496e76616c696420657874656e73696f6e000060448201526064016108c0565b6001600160a01b03811615806139f057506139f081631e05385b60e31b61357c565b613a2e5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016108c0565b6001600160a01b038281166000908152600f6020526040902054811690821614610ebf576001600160a01b038281166000818152600f602052604080822080546001600160a01b031916948616948517905551339392917f6a835c4fcf7e0d398db3762332fdaa1471814ad39f1e2d6d0b3fdabf8efee3e091a45050565b60006001600160e01b031982166328f10a2160e01b1480613ad15750613ad182612665565b80613aec57506001600160e01b03198216635d9dd7eb60e11b145b80613b0757506001600160e01b03198216632dde656160e21b145b80613b2257506001600160e01b031982166335681b5360e21b145b8061087057506001600160e01b0319821663152a902d60e11b1492915050565b610b2b8383836140e3565b336000908152600f60205260409020546001600160a01b031615610ebf57336000818152600f602052604090819020549051631e05385b60e31b815260048101929092526001600160a01b03848116602484015260448301849052169063f029c2d890606401600060405180830381600087803b158015613bcd57600080fd5b505af1158015613298573d6000803e3d6000fd5b610ebf828260405180602001604052806000815250614209565b60008181526001830160205260408120548015613cde576000613c1f600183615131565b8554909150600090613c3390600190615131565b90506000866000018281548110613c4c57613c4c614fb1565b9060005260206000200154905080876000018481548110613c6f57613c6f614fb1565b600091825260208083209091019290925582815260018901909152604090208490558654879080613ca257613ca2615324565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610870565b6000915050610870565b81546000908210613d465760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016108c0565b826000018281548110613d5b57613d5b614fb1565b9060005260206000200154905092915050565b6000818152600183016020526040812054613db557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610870565b506000610870565b6000613dd0826301ffc9a760e01b613df0565b80156108705750613de9826001600160e01b0319613df0565b1592915050565b604080516001600160e01b0319831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166301ffc9a760e01b179052905160009190829081906001600160a01b0387169061753090613e57908690615060565b6000604051808303818686fa925050503d8060008114613e93576040519150601f19603f3d011682016040523d82523d6000602084013e613e98565b606091505b5091509150602081511015613eb35760009350505050610870565b818015613ecf575080806020019051810190613ecf919061533a565b9695505050505050565b60006001600160a01b0384163b15613fdb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f1d903390899088908890600401615357565b602060405180830381600087803b158015613f3757600080fd5b505af1925050508015613f67575060408051601f3d908101601f19168201909252613f6491810190615389565b60015b613fc1573d808015613f95576040519150601f19603f3d011682016040523d82523d6000602084013e613f9a565b606091505b508051613fb95760405162461bcd60e51b81526004016108c090615191565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612c54565b506001949350505050565b60608161400a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614034578061401e81614fdd565b915061402d9050600a8361517d565b915061400e565b6000816001600160401b0381111561404e5761404e614a55565b6040519080825280601f01601f191660200182016040528015614078576020820181803683370190505b5090505b8415612c545761408d600183615131565b915061409a600a866153a6565b6140a5906030615095565b60f81b8183815181106140ba576140ba614fb1565b60200101906001600160f81b031916908160001a9053506140dc600a8661517d565b945061407c565b6000818152601160209081526040808320546001600160a01b03168352601090915290205460ff1615610b2b5760008181526011602052604090819020549051638258080560e01b81526001600160a01b03858116600483015284811660248301526044820184905290911690638258080590606401602060405180830381600087803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ab919061533a565b610b2b5760405162461bcd60e51b815260206004820152602960248201527f45524337323143726561746f723a20457874656e73696f6e20617070726f76616044820152686c206661696c75726560b81b60648201526084016108c0565b614213838361423c565b6142206000848484613ed9565b610b2b5760405162461bcd60e51b81526004016108c090615191565b6001600160a01b0382166142925760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108c0565b6000818152600660205260409020546001600160a01b0316156142f75760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108c0565b61430360008383613b42565b6001600160a01b038216600090815260076020526040812080546001929061432c908490615095565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461439690614e92565b90600052602060002090601f0160209004810192826143b857600085556143fe565b82601f106143d157805160ff19168380011785556143fe565b828001600101855582156143fe579182015b828111156143fe5782518255916020019190600101906143e3565b506110a4929150614541565b82805461441690614e92565b90600052602060002090601f01602090048101928261443857600085556143fe565b82601f106144515782800160ff198235161785556143fe565b828001600101855582156143fe579182015b828111156143fe578235825591602001919060010190614463565b8280548282559060005260206000209081019282156143fe579160200282015b828111156143fe5781546001600160a01b0319166001600160a01b0384351617825560209092019160019091019061449e565b8280548282559060005260206000209081019282156143fe57916020028201828111156143fe578235825591602001919060010190614463565b50805461451790614e92565b6000825580601f10614527575050565b601f0160209004906000526020600020908101906108d291905b5b808211156110a45760008155600101614542565b6001600160e01b0319811681146108d257600080fd5b60006020828403121561457e57600080fd5b81356126f381614556565b6001600160a01b03811681146108d257600080fd5b6000602082840312156145b057600080fd5b81356126f381614589565b60005b838110156145d65781810151838201526020016145be565b83811115610ff45750506000910152565b600081518084526145ff8160208601602086016145bb565b601f01601f19169290920160200192915050565b6020815260006126f360208301846145e7565b60006020828403121561463857600080fd5b5035919050565b6000806040838503121561465257600080fd5b823561465d81614589565b946020939093013593505050565b600081518084526020808501945080840160005b8381101561469b5781518752958201959082019060010161467f565b509495945050505050565b6020815260006126f3602083018461466b565b60008083601f8401126146cb57600080fd5b5081356001600160401b038111156146e257600080fd5b602083019150836020828501011115610e0d57600080fd5b60008060006040848603121561470f57600080fd5b8335925060208401356001600160401b0381111561472c57600080fd5b614738868287016146b9565b9497909650939450505050565b60008083601f84011261475757600080fd5b5081356001600160401b0381111561476e57600080fd5b6020830191508360208260051b8501011115610e0d57600080fd5b6000806000806000606086880312156147a157600080fd5b8535945060208601356001600160401b03808211156147bf57600080fd5b6147cb89838a01614745565b909650945060408801359150808211156147e457600080fd5b506147f188828901614745565b969995985093965092949392505050565b60008060006060848603121561481757600080fd5b833561482281614589565b9250602084013561483281614589565b929592945050506040919091013590565b6000806040838503121561485657600080fd5b50508035926020909101359150565b6000806020838503121561487857600080fd5b82356001600160401b0381111561488e57600080fd5b61489a858286016146b9565b90969095509350505050565b6000806000604084860312156148bb57600080fd5b83356148c681614589565b925060208401356001600160401b0381111561472c57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156149225783516001600160a01b0316835292840192918401916001016148fd565b50909695505050505050565b6000806000806040858703121561494457600080fd5b84356001600160401b038082111561495b57600080fd5b61496788838901614745565b9096509450602087013591508082111561498057600080fd5b5061498d87828801614745565b95989497509550505050565b6000806000604084860312156149ae57600080fd5b83356149b981614589565b925060208401356001600160401b038111156149d457600080fd5b61473886828701614745565b80151581146108d257600080fd5b60008060008060608587031215614a0457600080fd5b8435614a0f81614589565b935060208501356001600160401b03811115614a2a57600080fd5b614a36878288016146b9565b9094509250506040850135614a4a816149e0565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614a9357614a93614a55565b604052919050565b60006001600160401b03821115614ab457614ab4614a55565b50601f01601f191660200190565b6000614ad5614ad084614a9b565b614a6b565b9050828152838383011115614ae957600080fd5b828260208301376000602084830101529392505050565b600060208284031215614b1257600080fd5b81356001600160401b03811115614b2857600080fd5b8201601f81018413614b3957600080fd5b612c5484823560208401614ac2565b600080600060408486031215614b5d57600080fd5b83356001600160401b0380821115614b7457600080fd5b818601915086601f830112614b8857600080fd5b8135602082821115614b9c57614b9c614a55565b8160051b614bab828201614a6b565b928352848101820192828101908b851115614bc557600080fd5b958301955b84871015614be357863582529583019590830190614bca565b9850505087013592505080821115614bfa57600080fd5b5061473886828701614745565b600080600060408486031215614c1c57600080fd5b83356001600160401b03811115614c3257600080fd5b614c3e868287016146b9565b9094509250506020840135614c52816149e0565b809150509250925092565b60008060408385031215614c7057600080fd5b8235614c7b81614589565b91506020830135614c8b816149e0565b809150509250929050565b600060208284031215614ca857600080fd5b81356126f3816149e0565b60008060408385031215614cc657600080fd5b8235614cd181614589565b9150602083013561ffff81168114614c8b57600080fd5b600080600080600060608688031215614d0057600080fd5b8535614d0b81614589565b945060208601356001600160401b03808211156147bf57600080fd5b60008060008060808587031215614d3d57600080fd5b8435614d4881614589565b93506020850135614d5881614589565b92506040850135915060608501356001600160401b03811115614d7a57600080fd5b8501601f81018713614d8b57600080fd5b614d9a87823560208401614ac2565b91505092959194509250565b600081518084526020808501945080840160005b8381101561469b5781516001600160a01b031687529582019590820190600101614dba565b6020815260006126f36020830184614da6565b604081526000614e056040830185614da6565b8281036020840152614e17818561466b565b95945050505050565b60008060408385031215614e3357600080fd5b8235614e3e81614589565b91506020830135614c8b81614589565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b600181811c90821680614ea657607f821691505b6020821081141561392057634e487b7160e01b600052602260045260246000fd5b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601c908201527f4d757374206265207265676973746572656420657874656e73696f6e00000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614ff157614ff1614fc7565b5060010190565b6000808335601e1984360301811261500f57600080fd5b8301803591506001600160401b0382111561502957600080fd5b602001915036819003821315610e0d57600080fd5b600061ffff8083168181141561505657615056614fc7565b6001019392505050565b600082516150728184602087016145bb565b9190910192915050565b60006020828403121561508e57600080fd5b5051919050565b600082198211156150a8576150a8614fc7565b500190565b6040808252810184905260008560608301825b878110156150f05782356150d381614589565b6001600160a01b03168252602092830192909101906001016150c0565b5083810360208501528481526001600160fb1b0385111561511057600080fd5b8460051b915081866020830137600091016020019081529695505050505050565b60008282101561514357615143614fc7565b500390565b600081600019048311821515161561516257615162614fc7565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261518c5761518c615167565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b8054600090600181811c90808316806151fd57607f831692505b602080841082141561521f57634e487b7160e01b600052602260045260246000fd5b818015615233576001811461524457615271565b60ff19861689528489019650615271565b60008881526020902060005b868110156152695781548b820152908501908301615250565b505084890196505b50505050505092915050565b6000612c5461528c83866151e3565b846151e3565b6000602082840312156152a457600080fd5b81516001600160401b038111156152ba57600080fd5b8201601f810184136152cb57600080fd5b80516152d9614ad082614a9b565b8181528560208385010111156152ee57600080fd5b614e178260208301602086016145bb565b600061530b82856151e3565b835161531b8183602088016145bb565b01949350505050565b634e487b7160e01b600052603160045260246000fd5b60006020828403121561534c57600080fd5b81516126f3816149e0565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613ecf60808301846145e7565b60006020828403121561539b57600080fd5b81516126f381614556565b6000826153b5576153b5615167565b50069056fea2646970667358221220cb26a53cf3f76b3d6b50d0308f34b68f5cb46f625226462e087a8f0bbcd5d80b64736f6c63430008090033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061038e5760003560e01c8063715018a6116101de578063b0fe87c91161010f578063e00aab4b116100ad578063f0cdc4991161007c578063f0cdc49914610806578063f2fde38b14610819578063f528a6271461082c578063fe2e1f581461083457600080fd5b8063e00aab4b14610791578063e92a89f6146107a4578063e985e9c5146107b7578063ed42b0c1146107f357600080fd5b8063bb3bafd6116100e9578063bb3bafd61461074a578063c87b56dd1461076b578063ce8aee9d1461077e578063d5a06d4c1461074a57600080fd5b8063b0fe87c914610704578063b88d4fde14610717578063b9c4d9fb1461072a57600080fd5b80638da5cb5b1161017c578063a22cb46511610156578063a22cb465146106b8578063aafb2d44146106cb578063ac0c8cfa146106de578063ad2d0ddd146106f157600080fd5b80638da5cb5b1461068c57806395d89b411461069d57806399e0dd7c146106a557600080fd5b80637aa15f16116101b85780637aa15f161461065557806382dcc0c81461066857806383b7db631461067b57806385bb7d691461068357600080fd5b8063715018a61461062757806372ff03d31461062f5780637884af441461064257600080fd5b806330176e13116102c357806342842e0e116102615780636352211e116102305780636352211e146105db57806366d1e9d0146105ee5780636d73e6691461060157806370a082311461061457600080fd5b806342842e0e1461058f57806342966c68146105a257806356b1b300146105b557806361e5bc6b146105c857600080fd5b8063332dd1ae1161029d578063332dd1ae1461054357806338e52e78146105565780633e6134b8146105695780633f0f37f61461057c57600080fd5b806330176e13146105085780633071a0f91461051b57806331ae450b1461052e57600080fd5b806320e4afe21161033057806324d7806c1161030a57806324d7806c1461048f5780632928ca58146104a25780632a55205a146104c35780632d345670146104f557600080fd5b806320e4afe214610456578063239be3171461046957806323b872dd1461047c57600080fd5b8063081812fc1161036c578063081812fc146103e5578063095ea7b3146104105780630ebd4c7f14610423578063162094c41461044357600080fd5b806301ffc9a71461039357806302e7afb7146103bb57806306fdde03146103d0575b600080fd5b6103a66103a136600461456c565b610847565b60405190151581526020015b60405180910390f35b6103ce6103c936600461459e565b610876565b005b6103d86108d5565b6040516103b29190614613565b6103f86103f3366004614626565b610967565b6040516001600160a01b0390911681526020016103b2565b6103ce61041e36600461463f565b6109fc565b610436610431366004614626565b610b30565b6040516103b291906146a6565b6103ce6104513660046146fa565b610bc6565b6103ce610464366004614789565b610c1b565b6103f8610477366004614626565b610cad565b6103ce61048a366004614802565b610cea565b6103a661049d36600461459e565b610d1b565b6104b56104b036600461459e565b610d54565b6040519081526020016103b2565b6104d66104d1366004614843565b610dc8565b604080516001600160a01b0390931683526020830191909152016103b2565b6103ce61050336600461459e565b610e14565b6103ce610516366004614865565b610ec3565b6103ce6105293660046148a6565b610f4c565b610536610ffa565b6040516103b291906148e1565b6103ce61055136600461492e565b6110a8565b610436610564366004614999565b6110ff565b6103ce610577366004614865565b61123c565b6103ce61058a3660046149ee565b61126f565b6103ce61059d366004614802565b611316565b6103ce6105b0366004614626565b611331565b6103ce6105c3366004614b00565b6113d7565b6103ce6105d6366004614b48565b611434565b6103f86105e9366004614626565b6114ff565b6103ce6105fc366004614865565b611576565b6103ce61060f36600461459e565b6115a7565b6104b561062236600461459e565b611651565b6103ce6116d8565b6104b561063d36600461459e565b61177c565b6104b56106503660046148a6565b611809565b610436610663366004614999565b6118c9565b6103ce610676366004614c07565b611a1d565b610536611a4f565b6104b5601b5481565b6000546001600160a01b03166103f8565b6103d8611af9565b6103ce6106b3366004614865565b611b08565b6103ce6106c6366004614c5d565b611b5c565b6103ce6106d9366004614b48565b611c21565b6103ce6106ec366004614c96565b611d0f565b6104366106ff366004614cb3565b611e33565b6103ce610712366004614ce8565b611f59565b6103ce610725366004614d27565b611fb0565b61073d610738366004614626565b611fe2565b6040516103b29190614ddf565b61075d610758366004614626565b612081565b6040516103b2929190614df2565b6103d8610779366004614626565b61217d565b6103ce61078c36600461459e565b6121bd565b61043661079f366004614cb3565b612210565b6103ce6107b23660046146fa565b612308565b6103a66107c5366004614e20565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b6103a6610801366004614b00565b61233a565b6103ce610814366004614e20565b6123b3565b6103ce61082736600461459e565b612407565b6103d8612521565b6104b56108423660046148a6565b6125af565b600061085282612640565b80610861575061086182612665565b806108705750610870826126a0565b92915050565b336108896000546001600160a01b031690565b6001600160a01b031614806108a457506108a46002336126d5565b6108c95760405162461bcd60e51b81526004016108c090614e4e565b60405180910390fd5b6108d2816126fa565b50565b6060600480546108e490614e92565b80601f016020809104026020016040519081016040528092919081815260200182805461091090614e92565b801561095d5780601f106109325761010080835404028352916020019161095d565b820191906000526020600020905b81548152906001019060200180831161094057829003601f168201915b5050505050905090565b6000818152600660205260408120546001600160a01b03166109e05760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108c0565b506000908152600860205260409020546001600160a01b031690565b6000610a07826114ff565b9050806001600160a01b0316836001600160a01b03161415610a755760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016108c0565b336001600160a01b0382161480610aaf57506001600160a01b038116600090815260096020908152604080832033845290915290205460ff165b610b215760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016108c0565b610b2b83836127f6565b505050565b6000818152600660205260409020546060906001600160a01b0316610b675760405162461bcd60e51b81526004016108c090614ec7565b610b7082612864565b805480602002602001604051908101604052809291908181526020018280548015610bba57602002820191906000526020600020905b815481526020019060010190808311610ba6575b50505050509050919050565b33610bd96000546001600160a01b031690565b6001600160a01b03161480610bf45750610bf46002336126d5565b610c105760405162461bcd60e51b81526004016108c090614e4e565b610b2b8383836128f0565b33610c2e6000546001600160a01b031690565b6001600160a01b03161480610c495750610c496002336126d5565b610c655760405162461bcd60e51b81526004016108c090614e4e565b6000858152600660205260409020546001600160a01b0316610c995760405162461bcd60e51b81526004016108c090614ec7565b610ca6858585858561295f565b5050505050565b6000818152600660205260408120546001600160a01b0316610ce15760405162461bcd60e51b81526004016108c090614ec7565b61087082612aa8565b610cf43382612b65565b610d105760405162461bcd60e51b81526004016108c090614ef2565b610b2b838383612c5c565b6000816001600160a01b0316610d396000546001600160a01b031690565b6001600160a01b0316148061087057506108706002836126d5565b600060026001541415610d795760405162461bcd60e51b81526004016108c090614f43565b6002600155610d89600b336126d5565b610da55760405162461bcd60e51b81526004016108c090614f7a565b610dbe8260405180602001604052806000815250612e07565b6001805592915050565b60008281526006602052604081205481906001600160a01b0316610dfe5760405162461bcd60e51b81526004016108c090614ec7565b610e088484612e81565b915091505b9250929050565b6000546001600160a01b03163314610e6e5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b610e796002826126d5565b156108d25760405133906001600160a01b038316907f7c0c3c84c67c85fcac635147348bfe374c24a1a93d0366d1cfe9d8853cbf89d590600090a3610ebf600282612f69565b5050565b33610ed66000546001600160a01b031690565b6001600160a01b03161480610ef15750610ef16002336126d5565b610f0d5760405162461bcd60e51b81526004016108c090614e4e565b610ebf82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f7e92505050565b33610f5f6000546001600160a01b031690565b6001600160a01b03161480610f7a5750610f7a6002336126d5565b610f965760405162461bcd60e51b81526004016108c090614e4e565b82610fa2600d826126d5565b15610fe75760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b610ff48484846000612f9e565b50505050565b606061100660026130d9565b6001600160401b0381111561101d5761101d614a55565b604051908082528060200260200182016040528015611046578160200160208202803683370190505b50905060005b61105660026130d9565b8110156110a4576110686002826130e3565b82828151811061107a5761107a614fb1565b6001600160a01b03909216602092830291909101909101528061109c81614fdd565b91505061104c565b5090565b336110bb6000546001600160a01b031690565b6001600160a01b031614806110d657506110d66002336126d5565b6110f25760405162461bcd60e51b81526004016108c090614e4e565b610ff430858585856130ef565b6060600260015414156111245760405162461bcd60e51b81526004016108c090614f43565b6002600155611134600b336126d5565b6111505760405162461bcd60e51b81526004016108c090614f7a565b816001600160401b0381111561116857611168614a55565b604051908082528060200260200182016040528015611191578160200160208202803683370190505b50905060005b8281101561123057611201858585848181106111b5576111b5614fb1565b90506020028101906111c79190614ff8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e0792505050565b82828151811061121357611213614fb1565b60209081029190910101528061122881614fdd565b915050611197565b50600180559392505050565b611247600b336126d5565b6112635760405162461bcd60e51b81526004016108c090614f7a565b610ebf828260006132a0565b336112826000546001600160a01b031690565b6001600160a01b0316148061129d575061129d6002336126d5565b6112b95760405162461bcd60e51b81526004016108c090614e4e565b836112c5600d826126d5565b1561130a5760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b610ca685858585612f9e565b610b2b83838360405180602001604052806000815250611fb0565b600260015414156113545760405162461bcd60e51b81526004016108c090614f43565b60026001556113633382612b65565b6113af5760405162461bcd60e51b815260206004820181905260248201527f43616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656460448201526064016108c0565b60006113ba826114ff565b90506113c5826132dd565b6113cf8183613384565b505060018055565b336113ea6000546001600160a01b031690565b6001600160a01b0316148061140557506114056002336126d5565b6114215760405162461bcd60e51b81526004016108c090614e4e565b8051610ebf90601a90602084019061438a565b61143f600b336126d5565b61145b5760405162461bcd60e51b81526004016108c090614f7a565b8251811461149b5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b60005b8351811015610ff4576114ed8482815181106114bc576114bc614fb1565b60200260200101518484848181106114d6576114d6614fb1565b90506020028101906114e89190614ff8565b61349a565b806114f781614fdd565b91505061149e565b6000818152600660205260408120546001600160a01b0316806108705760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016108c0565b611581600b336126d5565b61159d5760405162461bcd60e51b81526004016108c090614f7a565b610ebf82826134f0565b6000546001600160a01b031633146116015760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b61160c6002826126d5565b6108d25760405133906001600160a01b038316907f7e1a1a08d52e4ba0e21554733d66165fd5151f99460116223d9e3a608eec5cb190600090a3610ebf60028261350a565b60006001600160a01b0382166116bc5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016108c0565b506001600160a01b031660009081526007602052604090205490565b6000546001600160a01b031633146117325760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000600260015414156117a15760405162461bcd60e51b81526004016108c090614f43565b6002600155336117b96000546001600160a01b031690565b6001600160a01b031614806117d457506117d46002336126d5565b6117f05760405162461bcd60e51b81526004016108c090614e4e565b610dbe826040518060200160405280600081525061351f565b60006002600154141561182e5760405162461bcd60e51b81526004016108c090614f43565b6002600155336118466000546001600160a01b031690565b6001600160a01b0316148061186157506118616002336126d5565b61187d5760405162461bcd60e51b81526004016108c090614e4e565b6118bd8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061351f92505050565b60018055949350505050565b6060600260015414156118ee5760405162461bcd60e51b81526004016108c090614f43565b6002600155336119066000546001600160a01b031690565b6001600160a01b0316148061192157506119216002336126d5565b61193d5760405162461bcd60e51b81526004016108c090614e4e565b816001600160401b0381111561195557611955614a55565b60405190808252806020026020018201604052801561197e578160200160208202803683370190505b50905060005b82811015611230576119ee858585848181106119a2576119a2614fb1565b90506020028101906119b49190614ff8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061351f92505050565b828281518110611a0057611a00614fb1565b602090810291909101015280611a1581614fdd565b915050611984565b611a28600b336126d5565b611a445760405162461bcd60e51b81526004016108c090614f7a565b610b2b8383836132a0565b6060611a5b600b6130d9565b6001600160401b03811115611a7257611a72614a55565b604051908082528060200260200182016040528015611a9b578160200160208202803683370190505b50905060005b611aab600b6130d9565b8110156110a457611abd600b826130e3565b828281518110611acf57611acf614fb1565b6001600160a01b039092166020928302919091019091015280611af181614fdd565b915050611aa1565b6060600580546108e490614e92565b33611b1b6000546001600160a01b031690565b6001600160a01b03161480611b365750611b366002336126d5565b611b525760405162461bcd60e51b81526004016108c090614e4e565b610ebf8282613562565b6001600160a01b038216331415611bb55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108c0565b3360008181526009602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b33611c346000546001600160a01b031690565b6001600160a01b03161480611c4f5750611c4f6002336126d5565b611c6b5760405162461bcd60e51b81526004016108c090614e4e565b82518114611cab5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b60005b8351811015610ff457611cfd848281518110611ccc57611ccc614fb1565b6020026020010151848484818110611ce657611ce6614fb1565b9050602002810190611cf89190614ff8565b6128f0565b80611d0781614fdd565b915050611cae565b611d1a600b336126d5565b611d365760405162461bcd60e51b81526004016108c090614f7a565b801580611d4f5750611d4f33634ce6d51160e11b61357c565b611dc15760405162461bcd60e51b815260206004820152603f60248201527f457874656e73696f6e206d75737420696d706c656d656e74204945524337323160448201527f43726561746f72457874656e73696f6e417070726f76655472616e736665720060648201526084016108c0565b3360009081526010602052604090205460ff161515811515146108d25733600081815260106020908152604091829020805460ff191685151590811790915591519182527f072a7592283e2c2d1d56d21517ff6013325e0f55483f4828373ff4d98b0a1a36910160405180910390a250565b606060026001541415611e585760405162461bcd60e51b81526004016108c090614f43565b600260015533611e706000546001600160a01b031690565b6001600160a01b03161480611e8b5750611e8b6002336126d5565b611ea75760405162461bcd60e51b81526004016108c090614e4e565b8161ffff166001600160401b03811115611ec357611ec3614a55565b604051908082528060200260200182016040528015611eec578160200160208202803683370190505b50905060005b8261ffff168161ffff161015611f4e57611f1b846040518060200160405280600081525061351f565b828261ffff1681518110611f3157611f31614fb1565b602090810291909101015280611f468161503e565b915050611ef2565b506001805592915050565b33611f6c6000546001600160a01b031690565b6001600160a01b03161480611f875750611f876002336126d5565b611fa35760405162461bcd60e51b81526004016108c090614e4e565b610ca685858585856130ef565b611fba3383612b65565b611fd65760405162461bcd60e51b81526004016108c090614ef2565b610ff484848484613598565b6000818152600660205260409020546060906001600160a01b03166120195760405162461bcd60e51b81526004016108c090614ec7565b612022826135cb565b805480602002602001604051908101604052809291908181526020018280548015610bba57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120585750505050509050919050565b6060806120a5836000908152600660205260409020546001600160a01b0316151590565b6120c15760405162461bcd60e51b81526004016108c090614ec7565b6120ca83613657565b81546040805160208084028201810190925282815291849183018282801561211b57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116120fd575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561216d57602002820191906000526020600020905b815481526020019060010190808311612159575b5050505050905091509150915091565b6000818152600660205260409020546060906001600160a01b03166121b45760405162461bcd60e51b81526004016108c090614ec7565b61087082613675565b336121d06000546001600160a01b031690565b6001600160a01b031614806121eb57506121eb6002336126d5565b6122075760405162461bcd60e51b81526004016108c090614e4e565b6108d281613926565b6060600260015414156122355760405162461bcd60e51b81526004016108c090614f43565b6002600155612245600b336126d5565b6122615760405162461bcd60e51b81526004016108c090614f7a565b8161ffff166001600160401b0381111561227d5761227d614a55565b6040519080825280602002602001820160405280156122a6578160200160208202803683370190505b50905060005b8261ffff168161ffff161015611f4e576122d58460405180602001604052806000815250612e07565b828261ffff16815181106122eb576122eb614fb1565b6020908102919091010152806123008161503e565b9150506122ac565b612313600b336126d5565b61232f5760405162461bcd60e51b81526004016108c090614f7a565b610b2b83838361349a565b600060028260405160200161234f9190615060565b60408051601f198184030181529082905261236991615060565b602060405180830381855afa158015612386573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906123a9919061507c565b601b541492915050565b336123c66000546001600160a01b031690565b6001600160a01b031614806123e157506123e16002336126d5565b6123fd5760405162461bcd60e51b81526004016108c090614e4e565b610ebf8282613977565b6000546001600160a01b031633146124615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c0565b6001600160a01b0381166124c65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c0565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b601a805461252e90614e92565b80601f016020809104026020016040519081016040528092919081815260200182805461255a90614e92565b80156125a75780601f1061257c576101008083540402835291602001916125a7565b820191906000526020600020905b81548152906001019060200180831161258a57829003601f168201915b505050505081565b6000600260015414156125d45760405162461bcd60e51b81526004016108c090614f43565b60026001556125e4600b336126d5565b6126005760405162461bcd60e51b81526004016108c090614f7a565b6118bd8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e0792505050565b60006001600160e01b03198216639088c20760e01b1480610870575061087082613aac565b60006001600160e01b031982166380ac58cd60e01b148061086157506001600160e01b03198216635b5e139f60e01b14806108705750610870825b60006001600160e01b03198216632a9f3abf60e11b148061087057506301ffc9a760e01b6001600160e01b0319831614610870565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6001600160a01b0381163014156127535760405162461bcd60e51b815260206004820152601960248201527f43616e6e6f7420626c61636b6c69737420796f757273656c660000000000000060448201526064016108c0565b61275e600b826126d5565b156127a65760405133906001600160a01b038316907fd19cf84cf0fec6bec9ddfa29c63adf83a55707c712f32c8285d6180a7890147990600090a36127a4600b82612f69565b505b6127b1600d826126d5565b6108d25760405133906001600160a01b038316907f05ac7bc5a606cd92a63365f9fda244499b9add0526b22d99937b6bd88181059c90600090a3610ebf600d8261350a565b600081815260086020526040902080546001600160a01b0319166001600160a01b038416908117909155819061282b826114ff565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152601960205260408120541561288a5750600090815260196020526040902090565b6000828152601160209081526040808320546001600160a01b031683526017909152902054156128dc57506000908152601160209081526040808320546001600160a01b031683526017909152902090565b505030600090815260176020526040902090565b6000838152601160205260409020546001600160a01b031630146129465760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016108c0565b6000838152601560205260409020610ff490838361440a565b82811461299e5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b6000805b828110156129e2578383828181106129bc576129bc614fb1565b90506020020135826129ce9190615095565b9150806129da81614fdd565b9150506129a2565b506127108110612a2e5760405162461bcd60e51b8152602060048201526017602482015276496e76616c696420746f74616c20726f79616c7469657360481b60448201526064016108c0565b6000868152601860205260409020612a4790868661447e565b506000868152601960205260409020612a619084846144d1565b50857fabb46fe0761d77584bde75697647804ffd8113abd4d8d06bc664150395eccdee86868686604051612a9894939291906150ad565b60405180910390a2505050505050565b6000818152601160205260409020546001600160a01b031630811415612b105760405162461bcd60e51b815260206004820152601660248201527f4e6f20657874656e73696f6e20666f7220746f6b656e0000000000000000000060448201526064016108c0565b612b1b600d826126d5565b15612b605760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b919050565b6000818152600660205260408120546001600160a01b0316612bde5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108c0565b6000612be9836114ff565b9050806001600160a01b0316846001600160a01b03161480612c245750836001600160a01b0316612c1984610967565b6001600160a01b0316145b80612c5457506001600160a01b0380821660009081526009602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612c6f826114ff565b6001600160a01b031614612cd75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016108c0565b6001600160a01b038216612d395760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108c0565b612d44838383613b42565b612d4f6000826127f6565b6001600160a01b0383166000908152600760205260408120805460019290612d78908490615131565b90915550506001600160a01b0382166000908152600760205260408120805460019290612da6908490615095565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805460009182612e1883614fdd565b9190505550600a549050612e2c8382613b4d565b600081815260116020526040902080546001600160a01b03191633179055612e548382613be1565b815115612e7c5760008181526015602090815260409091208351612e7a9285019061438a565b505b610870565b6000806000612e8f856135cb565b805490915060011015612ee45760405162461bcd60e51b815260206004820152601c60248201527f4d6f7265207468616e203120726f79616c74792072656365697665720000000060448201526064016108c0565b8054612ef7573060009250925050610e0d565b80600081548110612f0a57612f0a614fb1565b6000918252602090912001546001600160a01b031661271085612f2c88612864565b600081548110612f3e57612f3e614fb1565b9060005260206000200154612f539190615148565b612f5d919061517d565b92509250509250929050565b60006126f3836001600160a01b038416613bfb565b3060009081526012602090815260409091208251610ebf9284019061438a565b6001600160a01b038416301415612fea5760405162461bcd60e51b815260206004820152601060248201526f10dc99585d1bdc8e88125b9d985b1a5960821b60448201526064016108c0565b6001600160a01b0384163b61304f5760405162461bcd60e51b815260206004820152602560248201527f43726561746f723a20457874656e73696f6e206d757374206265206120636f6e6044820152641d1c9858dd60da1b60648201526084016108c0565b61305a600b856126d5565b610ff4576001600160a01b038416600090815260126020526040902061308190848461440a565b506001600160a01b038416600081815260136020526040808220805460ff1916851515179055513392917fd8cb8ba4086944eabf43c5535b7712015e4d4c714b24bf812c040ea5b7a3e42a91a3610ca6600b8561350a565b6000610870825490565b60006126f38383613ce8565b82811461312e5760405162461bcd60e51b815260206004820152600d60248201526c125b9d985b1a59081a5b9c1d5d609a1b60448201526064016108c0565b6000805b828110156131725783838281811061314c5761314c614fb1565b905060200201358261315e9190615095565b91508061316a81614fdd565b915050613132565b5061271081106131be5760405162461bcd60e51b8152602060048201526017602482015276496e76616c696420746f74616c20726f79616c7469657360481b60448201526064016108c0565b6001600160a01b03861660009081526016602052604090206131e190868661447e565b506001600160a01b03861660009081526017602052604090206132059084846144d1565b506001600160a01b038616301415613259577f2b6849d5976d799a5b0ca4dfd6b40a3d7afe9ea72c091fa01a958594f9a2659b8585858560405161324c94939291906150ad565b60405180910390a1613298565b856001600160a01b03167f535a93d2cb000582c0ebeaa9be4890ec6a287f98eb2df00c54c300612fd78d8f86868686604051612a9894939291906150ad565b505050505050565b3360009081526012602052604090206132ba90848461440a565b50336000908152601360205260409020805460ff19169115159190911790555050565b60006132e8826114ff565b90506132f681600084613b42565b6133016000836127f6565b6001600160a01b038116600090815260076020526040812080546001929061332a908490615131565b909155505060008281526006602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000818152601160205260409020546001600160a01b03163014613444576000818152601160205260409020546133cb906001600160a01b03166311686e4b60e21b61357c565b1561344457600081815260116020526040908190205490516311686e4b60e21b81526001600160a01b03848116600483015260248201849052909116906345a1b92c90604401600060405180830381600087803b15801561342b57600080fd5b505af115801561343f573d6000803e3d6000fd5b505050505b6000818152601560205260409020805461345d90614e92565b15905061347b57600081815260156020526040812061347b9161450b565b600090815260116020526040902080546001600160a01b031916905550565b6000838152601160205260409020546001600160a01b031633146129465760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b2103a37b5b2b760991b60448201526064016108c0565b336000908152601460205260409020610b2b90838361440a565b60006126f3836001600160a01b038416613d6e565b600a80546000918261353083614fdd565b9091555050600a54600081815260116020526040902080546001600160a01b031916301790559050612e548382613be1565b306000908152601460205260409020610b2b90838361440a565b600061358783613dbd565b80156126f357506126f38383613df0565b6135a3848484612c5c565b6135af84848484613ed9565b610ff45760405162461bcd60e51b81526004016108c090615191565b600081815260186020526040812054156135f15750600090815260186020526040902090565b6000828152601160209081526040808320546001600160a01b0316835260169091529020541561364357506000908152601160209081526040808320546001600160a01b031683526016909152902090565b505030600090815260166020526040902090565b600080613663836135cb565b61366c84612864565b91509150915091565b6000818152601160205260409020546060906001600160a01b031661369b600d826126d5565b156136e05760405162461bcd60e51b8152602060048201526015602482015274115e1d195b9cda5bdb88189b1858dadb1a5cdd1959605a1b60448201526064016108c0565b600083815260156020526040902080546136f990614e92565b159050613813576001600160a01b0381166000908152601460205260409020805461372390614e92565b159050613774576001600160a01b03811660009081526014602090815260408083208684526015835292819020905161375d93920161527d565b604051602081830303815290604052915050919050565b6000838152601560205260409020805461378d90614e92565b80601f01602080910402602001604051908101604052809291908181526020018280546137b990614e92565b80156138065780601f106137db57610100808354040283529160200191613806565b820191906000526020600020905b8154815290600101906020018083116137e957829003601f168201915b5050505050915050919050565b6138248163e9dc637560e01b61357c565b156138ab5760405163e9dc637560e01b8152306004820152602481018490526001600160a01b0382169063e9dc63759060440160006040518083038186803b15801561386f57600080fd5b505afa158015613883573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126f39190810190615292565b6001600160a01b03811660009081526013602052604090205460ff166138fd576001600160a01b03811660009081526012602052604090206138ec84613fe6565b60405160200161375d9291906152ff565b6001600160a01b0381166000908152601260205260409020805461378d90614e92565b50919050565b613931600b826126d5565b156108d25760405133906001600160a01b038316907fd19cf84cf0fec6bec9ddfa29c63adf83a55707c712f32c8285d6180a7890147990600090a3610ebf600b82612f69565b613982600b836126d5565b6139ce5760405162461bcd60e51b815260206004820152601e60248201527f43726561746f72436f72653a20496e76616c696420657874656e73696f6e000060448201526064016108c0565b6001600160a01b03811615806139f057506139f081631e05385b60e31b61357c565b613a2e5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016108c0565b6001600160a01b038281166000908152600f6020526040902054811690821614610ebf576001600160a01b038281166000818152600f602052604080822080546001600160a01b031916948616948517905551339392917f6a835c4fcf7e0d398db3762332fdaa1471814ad39f1e2d6d0b3fdabf8efee3e091a45050565b60006001600160e01b031982166328f10a2160e01b1480613ad15750613ad182612665565b80613aec57506001600160e01b03198216635d9dd7eb60e11b145b80613b0757506001600160e01b03198216632dde656160e21b145b80613b2257506001600160e01b031982166335681b5360e21b145b8061087057506001600160e01b0319821663152a902d60e11b1492915050565b610b2b8383836140e3565b336000908152600f60205260409020546001600160a01b031615610ebf57336000818152600f602052604090819020549051631e05385b60e31b815260048101929092526001600160a01b03848116602484015260448301849052169063f029c2d890606401600060405180830381600087803b158015613bcd57600080fd5b505af1158015613298573d6000803e3d6000fd5b610ebf828260405180602001604052806000815250614209565b60008181526001830160205260408120548015613cde576000613c1f600183615131565b8554909150600090613c3390600190615131565b90506000866000018281548110613c4c57613c4c614fb1565b9060005260206000200154905080876000018481548110613c6f57613c6f614fb1565b600091825260208083209091019290925582815260018901909152604090208490558654879080613ca257613ca2615324565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610870565b6000915050610870565b81546000908210613d465760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b60648201526084016108c0565b826000018281548110613d5b57613d5b614fb1565b9060005260206000200154905092915050565b6000818152600183016020526040812054613db557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610870565b506000610870565b6000613dd0826301ffc9a760e01b613df0565b80156108705750613de9826001600160e01b0319613df0565b1592915050565b604080516001600160e01b0319831660248083019190915282518083039091018152604490910182526020810180516001600160e01b03166301ffc9a760e01b179052905160009190829081906001600160a01b0387169061753090613e57908690615060565b6000604051808303818686fa925050503d8060008114613e93576040519150601f19603f3d011682016040523d82523d6000602084013e613e98565b606091505b5091509150602081511015613eb35760009350505050610870565b818015613ecf575080806020019051810190613ecf919061533a565b9695505050505050565b60006001600160a01b0384163b15613fdb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f1d903390899088908890600401615357565b602060405180830381600087803b158015613f3757600080fd5b505af1925050508015613f67575060408051601f3d908101601f19168201909252613f6491810190615389565b60015b613fc1573d808015613f95576040519150601f19603f3d011682016040523d82523d6000602084013e613f9a565b606091505b508051613fb95760405162461bcd60e51b81526004016108c090615191565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612c54565b506001949350505050565b60608161400a5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614034578061401e81614fdd565b915061402d9050600a8361517d565b915061400e565b6000816001600160401b0381111561404e5761404e614a55565b6040519080825280601f01601f191660200182016040528015614078576020820181803683370190505b5090505b8415612c545761408d600183615131565b915061409a600a866153a6565b6140a5906030615095565b60f81b8183815181106140ba576140ba614fb1565b60200101906001600160f81b031916908160001a9053506140dc600a8661517d565b945061407c565b6000818152601160209081526040808320546001600160a01b03168352601090915290205460ff1615610b2b5760008181526011602052604090819020549051638258080560e01b81526001600160a01b03858116600483015284811660248301526044820184905290911690638258080590606401602060405180830381600087803b15801561417357600080fd5b505af1158015614187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ab919061533a565b610b2b5760405162461bcd60e51b815260206004820152602960248201527f45524337323143726561746f723a20457874656e73696f6e20617070726f76616044820152686c206661696c75726560b81b60648201526084016108c0565b614213838361423c565b6142206000848484613ed9565b610b2b5760405162461bcd60e51b81526004016108c090615191565b6001600160a01b0382166142925760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108c0565b6000818152600660205260409020546001600160a01b0316156142f75760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108c0565b61430360008383613b42565b6001600160a01b038216600090815260076020526040812080546001929061432c908490615095565b909155505060008181526006602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b82805461439690614e92565b90600052602060002090601f0160209004810192826143b857600085556143fe565b82601f106143d157805160ff19168380011785556143fe565b828001600101855582156143fe579182015b828111156143fe5782518255916020019190600101906143e3565b506110a4929150614541565b82805461441690614e92565b90600052602060002090601f01602090048101928261443857600085556143fe565b82601f106144515782800160ff198235161785556143fe565b828001600101855582156143fe579182015b828111156143fe578235825591602001919060010190614463565b8280548282559060005260206000209081019282156143fe579160200282015b828111156143fe5781546001600160a01b0319166001600160a01b0384351617825560209092019160019091019061449e565b8280548282559060005260206000209081019282156143fe57916020028201828111156143fe578235825591602001919060010190614463565b50805461451790614e92565b6000825580601f10614527575050565b601f0160209004906000526020600020908101906108d291905b5b808211156110a45760008155600101614542565b6001600160e01b0319811681146108d257600080fd5b60006020828403121561457e57600080fd5b81356126f381614556565b6001600160a01b03811681146108d257600080fd5b6000602082840312156145b057600080fd5b81356126f381614589565b60005b838110156145d65781810151838201526020016145be565b83811115610ff45750506000910152565b600081518084526145ff8160208601602086016145bb565b601f01601f19169290920160200192915050565b6020815260006126f360208301846145e7565b60006020828403121561463857600080fd5b5035919050565b6000806040838503121561465257600080fd5b823561465d81614589565b946020939093013593505050565b600081518084526020808501945080840160005b8381101561469b5781518752958201959082019060010161467f565b509495945050505050565b6020815260006126f3602083018461466b565b60008083601f8401126146cb57600080fd5b5081356001600160401b038111156146e257600080fd5b602083019150836020828501011115610e0d57600080fd5b60008060006040848603121561470f57600080fd5b8335925060208401356001600160401b0381111561472c57600080fd5b614738868287016146b9565b9497909650939450505050565b60008083601f84011261475757600080fd5b5081356001600160401b0381111561476e57600080fd5b6020830191508360208260051b8501011115610e0d57600080fd5b6000806000806000606086880312156147a157600080fd5b8535945060208601356001600160401b03808211156147bf57600080fd5b6147cb89838a01614745565b909650945060408801359150808211156147e457600080fd5b506147f188828901614745565b969995985093965092949392505050565b60008060006060848603121561481757600080fd5b833561482281614589565b9250602084013561483281614589565b929592945050506040919091013590565b6000806040838503121561485657600080fd5b50508035926020909101359150565b6000806020838503121561487857600080fd5b82356001600160401b0381111561488e57600080fd5b61489a858286016146b9565b90969095509350505050565b6000806000604084860312156148bb57600080fd5b83356148c681614589565b925060208401356001600160401b0381111561472c57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156149225783516001600160a01b0316835292840192918401916001016148fd565b50909695505050505050565b6000806000806040858703121561494457600080fd5b84356001600160401b038082111561495b57600080fd5b61496788838901614745565b9096509450602087013591508082111561498057600080fd5b5061498d87828801614745565b95989497509550505050565b6000806000604084860312156149ae57600080fd5b83356149b981614589565b925060208401356001600160401b038111156149d457600080fd5b61473886828701614745565b80151581146108d257600080fd5b60008060008060608587031215614a0457600080fd5b8435614a0f81614589565b935060208501356001600160401b03811115614a2a57600080fd5b614a36878288016146b9565b9094509250506040850135614a4a816149e0565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715614a9357614a93614a55565b604052919050565b60006001600160401b03821115614ab457614ab4614a55565b50601f01601f191660200190565b6000614ad5614ad084614a9b565b614a6b565b9050828152838383011115614ae957600080fd5b828260208301376000602084830101529392505050565b600060208284031215614b1257600080fd5b81356001600160401b03811115614b2857600080fd5b8201601f81018413614b3957600080fd5b612c5484823560208401614ac2565b600080600060408486031215614b5d57600080fd5b83356001600160401b0380821115614b7457600080fd5b818601915086601f830112614b8857600080fd5b8135602082821115614b9c57614b9c614a55565b8160051b614bab828201614a6b565b928352848101820192828101908b851115614bc557600080fd5b958301955b84871015614be357863582529583019590830190614bca565b9850505087013592505080821115614bfa57600080fd5b5061473886828701614745565b600080600060408486031215614c1c57600080fd5b83356001600160401b03811115614c3257600080fd5b614c3e868287016146b9565b9094509250506020840135614c52816149e0565b809150509250925092565b60008060408385031215614c7057600080fd5b8235614c7b81614589565b91506020830135614c8b816149e0565b809150509250929050565b600060208284031215614ca857600080fd5b81356126f3816149e0565b60008060408385031215614cc657600080fd5b8235614cd181614589565b9150602083013561ffff81168114614c8b57600080fd5b600080600080600060608688031215614d0057600080fd5b8535614d0b81614589565b945060208601356001600160401b03808211156147bf57600080fd5b60008060008060808587031215614d3d57600080fd5b8435614d4881614589565b93506020850135614d5881614589565b92506040850135915060608501356001600160401b03811115614d7a57600080fd5b8501601f81018713614d8b57600080fd5b614d9a87823560208401614ac2565b91505092959194509250565b600081518084526020808501945080840160005b8381101561469b5781516001600160a01b031687529582019590820190600101614dba565b6020815260006126f36020830184614da6565b604081526000614e056040830185614da6565b8281036020840152614e17818561466b565b95945050505050565b60008060408385031215614e3357600080fd5b8235614e3e81614589565b91506020830135614c8b81614589565b60208082526024908201527f41646d696e436f6e74726f6c3a204d757374206265206f776e6572206f7220616040820152633236b4b760e11b606082015260800190565b600181811c90821680614ea657607f821691505b6020821081141561392057634e487b7160e01b600052602260045260246000fd5b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601c908201527f4d757374206265207265676973746572656420657874656e73696f6e00000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614ff157614ff1614fc7565b5060010190565b6000808335601e1984360301811261500f57600080fd5b8301803591506001600160401b0382111561502957600080fd5b602001915036819003821315610e0d57600080fd5b600061ffff8083168181141561505657615056614fc7565b6001019392505050565b600082516150728184602087016145bb565b9190910192915050565b60006020828403121561508e57600080fd5b5051919050565b600082198211156150a8576150a8614fc7565b500190565b6040808252810184905260008560608301825b878110156150f05782356150d381614589565b6001600160a01b03168252602092830192909101906001016150c0565b5083810360208501528481526001600160fb1b0385111561511057600080fd5b8460051b915081866020830137600091016020019081529695505050505050565b60008282101561514357615143614fc7565b500390565b600081600019048311821515161561516257615162614fc7565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261518c5761518c615167565b500490565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b8054600090600181811c90808316806151fd57607f831692505b602080841082141561521f57634e487b7160e01b600052602260045260246000fd5b818015615233576001811461524457615271565b60ff19861689528489019650615271565b60008881526020902060005b868110156152695781548b820152908501908301615250565b505084890196505b50505050505092915050565b6000612c5461528c83866151e3565b846151e3565b6000602082840312156152a457600080fd5b81516001600160401b038111156152ba57600080fd5b8201601f810184136152cb57600080fd5b80516152d9614ad082614a9b565b8181528560208385010111156152ee57600080fd5b614e178260208301602086016145bb565b600061530b82856151e3565b835161531b8183602088016145bb565b01949350505050565b634e487b7160e01b600052603160045260246000fd5b60006020828403121561534c57600080fd5b81516126f3816149e0565b60006001600160a01b03808716835280861660208401525083604083015260806060830152613ecf60808301846145e7565b60006020828403121561539b57600080fd5b81516126f381614556565b6000826153b5576153b5615167565b50069056fea2646970667358221220cb26a53cf3f76b3d6b50d0308f34b68f5cb46f625226462e087a8f0bbcd5d80b64736f6c63430008090033

Deployed Bytecode Sourcemap

108158:114:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97105:294;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;97105:294:0;;;;;;;;98441:128;;;;;;:::i;:::-;;:::i;:::-;;85453:100;;;:::i;:::-;;;;;;;:::i;86913:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2103:55:1;;;2085:74;;2073:2;2058:18;86913:221:0;1939:226:1;86450:397:0;;;;;;:::i;:::-;;:::i;107387:197::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;100401:136::-;;;;;;:::i;:::-;;:::i;105859:263::-;;;;;;:::i;:::-;;:::i;104971:195::-;;;;;;:::i;:::-;;:::i;87803:305::-;;;;;;:::i;:::-;;:::i;64719:139::-;;;;;;:::i;:::-;;:::i;103046:155::-;;;;;;:::i;:::-;;:::i;:::-;;;5890:25:1;;;5878:2;5863:18;103046:155:0;5744:177:1;107659:225:0;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6371:55:1;;;6353:74;;6458:2;6443:18;;6436:34;;;;6326:18;107659:225:0;6179:297:1;64441:210:0;;;;;;:::i;:::-;;:::i;100007:118::-;;;;;;:::i;:::-;;:::i;97643:199::-;;;;;;:::i;:::-;;:::i;63819:267::-;;;:::i;:::-;;;;;;;:::i;105583:204::-;;;;;;:::i;:::-;;:::i;103953:327::-;;;;;;:::i;:::-;;:::i;98653:147::-;;;;;;:::i;:::-;;:::i;97919:233::-;;;;;;:::i;:::-;;:::i;88179:151::-;;;;;;:::i;:::-;;:::i;105236:275::-;;;;;;:::i;:::-;;:::i;96868:165::-;;;;;;:::i;:::-;;:::i;99605:327::-;;;;;;:::i;:::-;;:::i;85147:239::-;;;;;;:::i;:::-;;:::i;99137:150::-;;;;;;:::i;:::-;;:::i;64159:210::-;;;;;;:::i;:::-;;:::i;84877:208::-;;;;;;:::i;:::-;;:::i;57821:148::-;;;:::i;101227:141::-;;;;;;:::i;:::-;;:::i;101442:163::-;;;;;;:::i;:::-;;:::i;102077:339::-;;;;;;:::i;:::-;;:::i;98884:167::-;;;;;;:::i;:::-;;:::i;68475:299::-;;;:::i;96586:90::-;;;;;;57170:87;57216:7;57243:6;-1:-1:-1;;;;;57243:6:0;57170:87;;85622:104;;;:::i;100202:128::-;;;;;;:::i;:::-;;:::i;87206:295::-;;;;;;:::i;:::-;;:::i;100608:305::-;;;;;;:::i;:::-;;:::i;80399:507::-;;;;;;:::i;:::-;;:::i;101684:314::-;;;;;;:::i;:::-;;:::i;106203:228::-;;;;;;:::i;:::-;;:::i;88401:285::-;;;;;;:::i;:::-;;:::i;107097:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;106503:228::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;107956:189::-;;;;;;:::i;:::-;;:::i;98233:130::-;;;;;;:::i;:::-;;:::i;103541:328::-;;;;;;:::i;:::-;;:::i;99367:158::-;;;;;;:::i;:::-;;:::i;87572:164::-;;;;;;:::i;:::-;-1:-1:-1;;;;;87693:25:0;;;87669:4;87693:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;87572:164;96691:159;;;;;;:::i;:::-;;:::i;100991:162::-;;;;;;:::i;:::-;;:::i;58124:244::-;;;;;;:::i;:::-;;:::i;96548:31::-;;;:::i;103280:177::-;;;;;;:::i;:::-;;:::i;97105:294::-;97231:4;97255:48;97291:11;97255:35;:48::i;:::-;:89;;;;97307:37;97332:11;97307:24;:37::i;:::-;97255:136;;;;97348:43;97379:11;97348:30;:43::i;:::-;97248:143;97105:294;-1:-1:-1;;97105:294:0:o;98441:128::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;;;;;;;;;98531:30:::1;98551:9;98531:19;:30::i;:::-;98441:128:::0;:::o;85453:100::-;85507:13;85540:5;85533:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85453:100;:::o;86913:221::-;86989:7;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;87009:73;;;;-1:-1:-1;;;87009:73:0;;19216:2:1;87009:73:0;;;19198:21:1;19255:2;19235:18;;;19228:30;19294:34;19274:18;;;19267:62;-1:-1:-1;;;19345:18:1;;;19338:42;19397:19;;87009:73:0;19014:408:1;87009:73:0;-1:-1:-1;87102:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;87102:24:0;;86913:221::o;86450:397::-;86531:13;86547:23;86562:7;86547:14;:23::i;:::-;86531:39;;86595:5;-1:-1:-1;;;;;86589:11:0;:2;-1:-1:-1;;;;;86589:11:0;;;86581:57;;;;-1:-1:-1;;;86581:57:0;;19629:2:1;86581:57:0;;;19611:21:1;19668:2;19648:18;;;19641:30;19707:34;19687:18;;;19680:62;-1:-1:-1;;;19758:18:1;;;19751:31;19799:19;;86581:57:0;19427:397:1;86581:57:0;42773:10;-1:-1:-1;;;;;86659:21:0;;;;:62;;-1:-1:-1;;;;;;87693:25:0;;87669:4;87693:25;;;:18;:25;;;;;;;;42773:10;87693:35;;;;;;;;;;86684:37;86651:154;;;;-1:-1:-1;;;86651:154:0;;20031:2:1;86651:154:0;;;20013:21:1;20070:2;20050:18;;;20043:30;20109:34;20089:18;;;20082:62;20180:26;20160:18;;;20153:54;20224:19;;86651:154:0;19829:420:1;86651:154:0;86818:21;86827:2;86831:7;86818:8;:21::i;:::-;86520:327;86450:397;;:::o;107387:197::-;90218:4;90242:16;;;:7;:16;;;;;;107463:13;;-1:-1:-1;;;;;90242:16:0;107489:46;;;;-1:-1:-1;;;107489:46:0;;;;;;;:::i;:::-;107553:23;107568:7;107553:14;:23::i;:::-;107546:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107387:197;;;:::o;100401:136::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;100503:26:::1;100516:7;100525:3;;100503:12;:26::i;105859:263::-:0;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;90218:4;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;106011:46:::1;;;;-1:-1:-1::0;;;106011:46:0::1;;;;;;;:::i;:::-;106068;106082:7;106091:9;;106102:11;;106068:13;:46::i;:::-;105859:263:::0;;;;;:::o;104971:195::-;105050:7;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;105070:46;;;;-1:-1:-1;;;105070:46:0;;;;;;;:::i;:::-;105134:24;105150:7;105134:15;:24::i;87803:305::-;87964:41;42773:10;87997:7;87964:18;:41::i;:::-;87956:103;;;;-1:-1:-1;;;87956:103:0;;;;;;;:::i;:::-;88072:28;88082:4;88088:2;88092:7;88072:9;:28::i;64719:139::-;64781:4;64817:5;-1:-1:-1;;;;;64806:16:0;:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;64806:7;-1:-1:-1;;;;;64806:16:0;;:43;;;-1:-1:-1;64826:23:0;:7;64843:5;64826:16;:23::i;103046:155::-;103144:7;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;68079:32:::1;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1::0;;;68071:73:0::1;;;;;;;:::i;:::-;103171:22:::2;103186:2;103171:22;;;;;;;;;;;::::0;:14:::2;:22::i;:::-;23432:1:::0;24385:22;;103164:29;103046:155;-1:-1:-1;;103046:155:0:o;107659:225::-;107752:7;90242:16;;;:7;:16;;;;;;107752:7;;-1:-1:-1;;;;;90242:16:0;107781:46;;;;-1:-1:-1;;;107781:46:0;;;;;;;:::i;:::-;107845:31;107861:7;107870:5;107845:15;:31::i;:::-;107838:38;;;;107659:225;;;;;;:::o;64441:210::-;57216:7;57243:6;-1:-1:-1;;;;;57243:6:0;42773:10;57390:23;57382:68;;;;-1:-1:-1;;;57382:68:0;;21937:2:1;57382:68:0;;;21919:21:1;;;21956:18;;;21949:30;22015:34;21995:18;;;21988:62;22067:18;;57382:68:0;21735:356:1;57382:68:0;64520:23:::1;:7;64537:5:::0;64520:16:::1;:23::i;:::-;64516:128;;;64565:31;::::0;64585:10:::1;::::0;-1:-1:-1;;;;;64565:31:0;::::1;::::0;::::1;::::0;;;::::1;64611:21;:7;64626:5:::0;64611:14:::1;:21::i;:::-;;64441:210:::0;:::o;100007:118::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;100096:21:::1;100113:3;;100096:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;100096:16:0::1;::::0;-1:-1:-1;;;100096:21:0:i:1;97643:199::-:0;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;97767:9;68311:42:::1;:22;97767:9:::0;68311:31:::1;:42::i;:::-;68310:43;68302:77;;;::::0;-1:-1:-1;;;68302:77:0;;22298:2:1;68302:77:0::1;::::0;::::1;22280:21:1::0;22337:2;22317:18;;;22310:30;-1:-1:-1;;;22356:18:1;;;22349:51;22417:18;;68302:77:0::1;22096:345:1::0;68302:77:0::1;97789:45:::2;97808:9;97819:7;;97828:5;97789:18;:45::i;:::-;63737:1:::1;97643:199:::0;;;:::o;63819:267::-;63872:23;63931:16;:7;:14;:16::i;:::-;-1:-1:-1;;;;;63917:31:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63917:31:0;;63908:40;;63964:6;63959:96;63980:16;:7;:14;:16::i;:::-;63976:1;:20;63959:96;;;64030:13;:7;64041:1;64030:10;:13::i;:::-;64018:6;64025:1;64018:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;64018:25:0;;;:9;;;;;;;;;;;:25;63998:3;;;;:::i;:::-;;;;63959:96;;;;63819:267;:::o;105583:204::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;105718:61:::1;105749:4;105756:9;;105767:11;;105718:22;:61::i;103953:327::-:0;104080:25;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;68079:32:::1;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1::0;;;68071:73:0::1;;;;;;;:::i;:::-;104143:4:::0;-1:-1:-1;;;;;104129:26:0;::::2;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;104129:26:0::2;;104118:37;;104171:6;104166:107;104183:15:::0;;::::2;104166:107;;;104234:27;104249:2;104253:4;;104258:1;104253:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;104234:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;104234:14:0::2;::::0;-1:-1:-1;;;104234:27:0:i:2;:::-;104220:8;104229:1;104220:11;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:41;104200:3;::::2;::::0;::::2;:::i;:::-;;;;104166:107;;;-1:-1:-1::0;23432:1:0;24385:22;;103953:327;;-1:-1:-1;;;103953:327:0:o;98653:147::-;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;98755:37:::1;98781:3;;98786:5;98755:25;:37::i;97919:233::-:0;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;98066:9;68311:42:::1;:22;98066:9:::0;68311:31:::1;:42::i;:::-;68310:43;68302:77;;;::::0;-1:-1:-1;;;68302:77:0;;22298:2:1;68302:77:0::1;::::0;::::1;22280:21:1::0;22337:2;22317:18;;;22310:30;-1:-1:-1;;;22356:18:1;;;22349:51;22417:18;;68302:77:0::1;22096:345:1::0;68302:77:0::1;98088:56:::2;98107:9;98118:7;;98127:16;98088:18;:56::i;88179:151::-:0;88283:39;88300:4;88306:2;88310:7;88283:39;;;;;;;;;;;;:16;:39::i;105236:275::-;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;105323:39:::1;105342:10;105354:7:::0;105323:18:::1;:39::i;:::-;105315:84;;;::::0;-1:-1:-1;;;105315:84:0;;23579:2:1;105315:84:0::1;::::0;::::1;23561:21:1::0;;;23598:18;;;23591:30;23657:34;23637:18;;;23630:62;23709:18;;105315:84:0::1;23377:356:1::0;105315:84:0::1;105410:13;105426:16;105434:7;105426;:16::i;:::-;105410:32;;105453:14;105459:7;105453:5;:14::i;:::-;105478:25;105488:5;105495:7;105478:9;:25::i;:::-;-1:-1:-1::0;;23432:1:0;24385:22;;105236:275::o;96868:165::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;96987:38;;::::1;::::0;:17:::1;::::0;:38:::1;::::0;::::1;::::0;::::1;:::i;99605:327::-:0;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;99741:15;;:30;::::1;99733:56;;;::::0;-1:-1:-1;;;99733:56:0;;23940:2:1;99733:56:0::1;::::0;::::1;23922:21:1::0;23979:2;23959:18;;;23952:30;-1:-1:-1;;;23998:18:1;;;23991:43;24051:18;;99733:56:0::1;23738:337:1::0;99733:56:0::1;99805:6;99800:125;99821:8;:15;99817:1;:19;99800:125;;;99858:43;99880:8;99889:1;99880:11;;;;;;;;:::i;:::-;;;;;;;99893:4;;99898:1;99893:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;99858:21;:43::i;:::-;99838:3:::0;::::1;::::0;::::1;:::i;:::-;;;;99800:125;;85147:239:::0;85219:7;85255:16;;;:7;:16;;;;;;-1:-1:-1;;;;;85255:16:0;85290:19;85282:73;;;;-1:-1:-1;;;85282:73:0;;24282:2:1;85282:73:0;;;24264:21:1;24321:2;24301:18;;;24294:30;24360:34;24340:18;;;24333:62;-1:-1:-1;;;24411:18:1;;;24404:39;24460:19;;85282:73:0;24080:405:1;99137:150:0;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;99244:35:::1;99272:6;;99244:27;:35::i;64159:210::-:0;57216:7;57243:6;-1:-1:-1;;;;;57243:6:0;42773:10;57390:23;57382:68;;;;-1:-1:-1;;;57382:68:0;;21937:2:1;57382:68:0;;;21919:21:1;;;21956:18;;;21949:30;22015:34;21995:18;;;21988:62;22067:18;;57382:68:0;21735:356:1;57382:68:0;64240:23:::1;:7;64257:5:::0;64240:16:::1;:23::i;:::-;64235:127;;64285:32;::::0;64306:10:::1;::::0;-1:-1:-1;;;;;64285:32:0;::::1;::::0;::::1;::::0;;;::::1;64332:18;:7;64344:5:::0;64332:11:::1;:18::i;84877:208::-:0;84949:7;-1:-1:-1;;;;;84977:19:0;;84969:74;;;;-1:-1:-1;;;84969:74:0;;24692:2:1;84969:74:0;;;24674:21:1;24731:2;24711:18;;;24704:30;24770:34;24750:18;;;24743:62;-1:-1:-1;;;24821:18:1;;;24814:40;24871:19;;84969:74:0;24490:406:1;84969:74:0;-1:-1:-1;;;;;;85061:16:0;;;;;:9;:16;;;;;;;84877:208::o;57821:148::-;57216:7;57243:6;-1:-1:-1;;;;;57243:6:0;42773:10;57390:23;57382:68;;;;-1:-1:-1;;;57382:68:0;;21937:2:1;57382:68:0;;;21919:21:1;;;21956:18;;;21949:30;22015:34;21995:18;;;21988:62;22067:18;;57382:68:0;21735:356:1;57382:68:0;57928:1:::1;57912:6:::0;;57891:40:::1;::::0;-1:-1:-1;;;;;57912:6:0;;::::1;::::0;57891:40:::1;::::0;57928:1;;57891:40:::1;57959:1;57942:19:::0;;-1:-1:-1;;;;;;57942:19:0::1;::::0;;57821:148::o;101227:141::-;101316:7;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;63643:10:::1;63632:7;57216::::0;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7:::1;-1:-1:-1::0;;;;;63632:21:0::1;;:53;;;-1:-1:-1::0;63657:28:0::1;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1::0;;;63624:102:0::1;;;;;;;:::i;:::-;101343:17:::2;101353:2;101343:17;;;;;;;;;;;::::0;:9:::2;:17::i;101442:163::-:0;101552:7;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;63643:10:::1;63632:7;57216::::0;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7:::1;-1:-1:-1::0;;;;;63632:21:0::1;;:53;;;-1:-1:-1::0;63657:28:0::1;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1::0;;;63624:102:0::1;;;;;;;:::i;:::-;101579:18:::2;101589:2;101593:3;;101579:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;101579:9:0::2;::::0;-1:-1:-1;;;101579:18:0:i:2;:::-;23432:1:::0;24385:22;;101572:25;101442:163;-1:-1:-1;;;;101442:163:0:o;102077:339::-;102195:25;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;63643:10:::1;63632:7;57216::::0;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7:::1;-1:-1:-1::0;;;;;63632:21:0::1;;:53;;;-1:-1:-1::0;63657:28:0::1;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1::0;;;63624:102:0::1;;;;;;;:::i;:::-;102258:4:::0;-1:-1:-1;;;;;102244:26:0;::::2;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;102244:26:0::2;;102233:37;;102286:6;102281:102;102298:15:::0;;::::2;102281:102;;;102349:22;102359:2;102363:4;;102368:1;102363:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;102349:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;102349:9:0::2;::::0;-1:-1:-1;;;102349:22:0:i:2;:::-;102335:8;102344:1;102335:11;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:36;102315:3;::::2;::::0;::::2;:::i;:::-;;;;102281:102;;98884:167:::0;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;99002:41:::1;99028:3;;99033:9;99002:25;:41::i;68475:299::-:0;68532:27;68599:20;:11;:18;:20::i;:::-;-1:-1:-1;;;;;68585:35:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68585:35:0;;68572:48;;68636:6;68631:108;68652:20;:11;:18;:20::i;:::-;68648:1;:24;68631:108;;;68710:17;:11;68725:1;68710:14;:17::i;:::-;68694:10;68705:1;68694:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;68694:33:0;;;:13;;;;;;;;;;;:33;68674:3;;;;:::i;:::-;;;;68631:108;;85622:104;85678:13;85711:7;85704:14;;;;;:::i;100202:128::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;100296:26:::1;100315:6;;100296:18;:26::i;87206:295::-:0;-1:-1:-1;;;;;87309:24:0;;42773:10;87309:24;;87301:62;;;;-1:-1:-1;;;87301:62:0;;25103:2:1;87301:62:0;;;25085:21:1;25142:2;25122:18;;;25115:30;25181:27;25161:18;;;25154:55;25226:18;;87301:62:0;24901:349:1;87301:62:0;42773:10;87376:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;87376:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;87376:53:0;;;;;;;;;;87445:48;;540:41:1;;;87376:42:0;;42773:10;87445:48;;513:18:1;87445:48:0;;;;;;;87206:295;;:::o;100608:305::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;100731:15;;:30;::::1;100723:56;;;::::0;-1:-1:-1;;;100723:56:0;;23940:2:1;100723:56:0::1;::::0;::::1;23922:21:1::0;23979:2;23959:18;;;23952:30;-1:-1:-1;;;23998:18:1;;;23991:43;24051:18;;100723:56:0::1;23738:337:1::0;100723:56:0::1;100795:6;100790:116;100811:8;:15;100807:1;:19;100790:116;;;100848:34;100861:8;100870:1;100861:11;;;;;;;;:::i;:::-;;;;;;;100874:4;;100879:1;100874:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;100848:12;:34::i;:::-;100828:3:::0;::::1;::::0;::::1;:::i;:::-;;;;100790:116;;80399:507:::0;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;80506:7:::1;80505:8;:113;;;;80517:101;80549:10;-1:-1:-1::0;;;80517:31:0::1;:101::i;:::-;80497:189;;;::::0;-1:-1:-1;;;80497:189:0;;25457:2:1;80497:189:0::1;::::0;::::1;25439:21:1::0;25496:2;25476:18;;;25469:30;25535:34;25515:18;;;25508:62;25606:33;25586:18;;;25579:61;25657:19;;80497:189:0::1;25255:427:1::0;80497:189:0::1;80728:10;80701:38;::::0;;;:26:::1;:38;::::0;;;;;::::1;;:49;;::::0;::::1;;;80697:202;;80794:10;80767:38;::::0;;;:26:::1;:38;::::0;;;;;;;;:48;;-1:-1:-1;;80767:48:0::1;::::0;::::1;;::::0;;::::1;::::0;;;80835:52;;540:41:1;;;80835:52:0::1;::::0;513:18:1;80835:52:0::1;;;;;;;80399:507:::0;:::o;101684:314::-;101792:25;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;63643:10:::1;63632:7;57216::::0;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7:::1;-1:-1:-1::0;;;;;63632:21:0::1;;:53;;;-1:-1:-1::0;63657:28:0::1;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1::0;;;63624:102:0::1;;;;;;;:::i;:::-;101855:5:::2;101841:20;;-1:-1:-1::0;;;;;101841:20:0::2;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;101841:20:0::2;;101830:31;;101877:8;101872:93;101895:5;101891:9;;:1;:9;;;101872:93;;;101936:17;101946:2;101936:17;;;;;;;;;;;::::0;:9:::2;:17::i;:::-;101922:8;101931:1;101922:11;;;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:31;101902:3;::::2;::::0;::::2;:::i;:::-;;;;101872:93;;;;23432:1:::0;24385:22;;101684:314;;-1:-1:-1;;101684:314:0:o;106203:228::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;106366:57:::1;106389:9;106400;;106411:11;;106366:22;:57::i;88401:285::-:0;88533:41;42773:10;88566:7;88533:18;:41::i;:::-;88525:103;;;;-1:-1:-1;;;88525:103:0;;;;;;;:::i;:::-;88639:39;88653:4;88659:2;88663:7;88672:5;88639:13;:39::i;107097:221::-;90218:4;90242:16;;;:7;:16;;;;;;107180:24;;-1:-1:-1;;;;;90242:16:0;107217:46;;;;-1:-1:-1;;;107217:46:0;;;;;;;:::i;:::-;107281:29;107302:7;107281:20;:29::i;:::-;107274:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;107274:36:0;;;;;;;;;;;;;;;;;;;;;;107097:221;;;:::o;106503:228::-;106582:24;106608:16;106645;106653:7;90218:4;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;:30;;;90153:127;106645:16;106637:46;;;;-1:-1:-1;;;106637:46:0;;;;;;;:::i;:::-;106701:22;106715:7;106701:13;:22::i;:::-;106694:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;106694:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106503:228;;;:::o;107956:189::-;90218:4;90242:16;;;:7;:16;;;;;;108029:13;;-1:-1:-1;;;;;90242:16:0;108055:46;;;;-1:-1:-1;;;108055:46:0;;;;;;;:::i;:::-;108119:18;108129:7;108119:9;:18::i;98233:130::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;98324:31:::1;98345:9;98324:20;:31::i;103541:328::-:0;103658:25;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;68079:32:::1;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1::0;;;68071:73:0::1;;;;;;;:::i;:::-;103721:5:::2;103707:20;;-1:-1:-1::0;;;;;103707:20:0::2;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;103707:20:0::2;;103696:31;;103743:8;103738:98;103761:5;103757:9;;:1;:9;;;103738:98;;;103802:22;103817:2;103802:22;;;;;;;;;;;::::0;:14:::2;:22::i;:::-;103788:8;103797:1;103788:11;;;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:36;103768:3;::::2;::::0;::::2;:::i;:::-;;;;103738:98;;99367:158:::0;68079:32;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1;;;68071:73:0;;;;;;;:::i;:::-;99482:35:::1;99504:7;99513:3;;99482:21;:35::i;96691:159::-:0;96772:4;96809:33;96833:7;96816:25;;;;;;;;:::i;:::-;;;;-1:-1:-1;;96816:25:0;;;;;;;;;;96809:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96799:6;;:43;;96691:159;-1:-1:-1;;96691:159:0:o;100991:162::-;63643:10;63632:7;57216;57243:6;-1:-1:-1;;;;;57243:6:0;;57170:87;63632:7;-1:-1:-1;;;;;63632:21:0;;:53;;;-1:-1:-1;63657:28:0;:7;63674:10;63657:16;:28::i;:::-;63624:102;;;;-1:-1:-1;;;63624:102:0;;;;;;;:::i;:::-;101102:43:::1;101122:9;101133:11;101102:19;:43::i;58124:244::-:0;57216:7;57243:6;-1:-1:-1;;;;;57243:6:0;42773:10;57390:23;57382:68;;;;-1:-1:-1;;;57382:68:0;;21937:2:1;57382:68:0;;;21919:21:1;;;21956:18;;;21949:30;22015:34;21995:18;;;21988:62;22067:18;;57382:68:0;21735:356:1;57382:68:0;-1:-1:-1;;;;;58213:22:0;::::1;58205:73;;;::::0;-1:-1:-1;;;58205:73:0;;26840:2:1;58205:73:0::1;::::0;::::1;26822:21:1::0;26879:2;26859:18;;;26852:30;26918:34;26898:18;;;26891:62;-1:-1:-1;;;26969:18:1;;;26962:36;27015:19;;58205:73:0::1;26638:402:1::0;58205:73:0::1;58315:6;::::0;;58294:38:::1;::::0;-1:-1:-1;;;;;58294:38:0;;::::1;::::0;58315:6;::::1;::::0;58294:38:::1;::::0;::::1;58343:6;:17:::0;;-1:-1:-1;;;;;;58343:17:0::1;-1:-1:-1::0;;;;;58343:17:0;;;::::1;::::0;;;::::1;::::0;;58124:244::o;96548:31::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;103280:177::-;103399:7;23476:1;24073:7;;:19;;24065:63;;;;-1:-1:-1;;;24065:63:0;;;;;;;:::i;:::-;23476:1;24206:7;:18;68079:32:::1;:11;68100:10;68079:20;:32::i;:::-;68071:73;;;;-1:-1:-1::0;;;68071:73:0::1;;;;;;;:::i;:::-;103426:23:::2;103441:2;103445:3;;103426:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;103426:14:0::2;::::0;-1:-1:-1;;;103426:23:0:i:2;80082:230::-:0;80189:4;-1:-1:-1;;;;;;80213:51:0;;-1:-1:-1;;;80213:51:0;;:91;;;80268:36;80292:11;80268:23;:36::i;84521:292::-;84623:4;-1:-1:-1;;;;;;84647:40:0;;-1:-1:-1;;;84647:40:0;;:105;;-1:-1:-1;;;;;;;84704:48:0;;-1:-1:-1;;;84704:48:0;84647:158;;;;84769:36;84793:11;63257:233;63359:4;-1:-1:-1;;;;;;63383:46:0;;-1:-1:-1;;;63383:46:0;;:99;;-1:-1:-1;;;;;;;;;;40116:40:0;;;63446:36;40007:157;19339:167;-1:-1:-1;;;;;19473:23:0;;19419:4;16148:19;;;:12;;;:19;;;;;;:24;;19443:55;19436:62;19339:167;-1:-1:-1;;;19339:167:0:o;69737:484::-;-1:-1:-1;;;;;69812:26:0;;69833:4;69812:26;;69804:64;;;;-1:-1:-1;;;69804:64:0;;27247:2:1;69804:64:0;;;27229:21:1;27286:2;27266:18;;;27259:30;27325:27;27305:18;;;27298:55;27370:18;;69804:64:0;27045:349:1;69804:64:0;69882:31;:11;69903:9;69882:20;:31::i;:::-;69878:154;;;69934:44;;69967:10;;-1:-1:-1;;;;;69934:44:0;;;;;;;;69992:29;:11;70011:9;69992:18;:29::i;:::-;;69878:154;70046:42;:22;70078:9;70046:31;:42::i;:::-;70041:173;;70109:43;;70141:10;;-1:-1:-1;;;;;70109:43:0;;;;;;;;70166:37;:22;70193:9;70166:26;:37::i;94030:174::-;94105:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;94105:29:0;-1:-1:-1;;;;;94105:29:0;;;;;;;;:24;;94159:23;94105:24;94159:14;:23::i;:::-;-1:-1:-1;;;;;94150:46:0;;;;;;;;;;;94030:174;;:::o;73951:414::-;74015:17;74049:25;;;:16;:25;;;;;:32;:36;74045:252;;-1:-1:-1;74109:25:0;;;;:16;:25;;;;;;73951:414::o;74045:252::-;74213:1;74177:25;;;:16;:25;;;;;;;;;-1:-1:-1;;;;;74177:25:0;74156:47;;:20;:47;;;;;:54;:58;74152:145;;-1:-1:-1;74238:47:0;74259:25;;;:16;:25;;;;;;;;;-1:-1:-1;;;;;74259:25:0;74238:47;;:20;:47;;;;;;73951:414::o;74152:145::-;-1:-1:-1;;74343:4:0;74314:35;;;;:20;:35;;;;;;73951:414::o;71472:192::-;71560:25;;;;:16;:25;;;;;;-1:-1:-1;;;;;71560:25:0;71597:4;71560:42;71552:68;;;;-1:-1:-1;;;71552:68:0;;27601:2:1;71552:68:0;;;27583:21:1;27640:2;27620:18;;;27613:30;-1:-1:-1;;;27659:18:1;;;27652:43;27712:18;;71552:68:0;27399:337:1;71552:68:0;71631:19;;;;:10;:19;;;;;:25;;71653:3;;71631:25;:::i;74876:594::-;75014:38;;;75006:64;;;;-1:-1:-1;;;75006:64:0;;23940:2:1;75006:64:0;;;23922:21:1;23979:2;23959:18;;;23952:30;-1:-1:-1;;;23998:18:1;;;23991:43;24051:18;;75006:64:0;23738:337:1;75006:64:0;75081:24;;75116:107;75133:22;;;75116:107;;;75197:11;;75209:1;75197:14;;;;;;;:::i;:::-;;;;;;;75177:34;;;;;:::i;:::-;;-1:-1:-1;75157:3:0;;;;:::i;:::-;;;;75116:107;;;;75260:5;75241:16;:24;75233:60;;;;-1:-1:-1;;;75233:60:0;;28076:2:1;75233:60:0;;;28058:21:1;28115:2;28095:18;;;28088:30;-1:-1:-1;;;28134:18:1;;;28127:53;28197:18;;75233:60:0;27874:347:1;75233:60:0;75304:31;;;;:22;:31;;;;;:43;;75338:9;;75304:43;:::i;:::-;-1:-1:-1;75358:25:0;;;;:16;:25;;;;;:39;;75386:11;;75358:39;:::i;:::-;;75430:7;75413:49;75439:9;;75450:11;;75413:49;;;;;;;;;:::i;:::-;;;;;;;;74995:475;74876:594;;;;;:::o;72742:331::-;72807:17;72849:25;;;:16;:25;;;;;;-1:-1:-1;;;;;72849:25:0;72916:4;72895:26;;;72887:61;;;;-1:-1:-1;;;72887:61:0;;29574:2:1;72887:61:0;;;29556:21:1;29613:2;29593:18;;;29586:30;29652:24;29632:18;;;29625:52;29694:18;;72887:61:0;29372:346:1;72887:61:0;72968:42;:22;73000:9;72968:31;:42::i;:::-;72967:43;72959:77;;;;-1:-1:-1;;;72959:77:0;;22298:2:1;72959:77:0;;;22280:21:1;22337:2;22317:18;;;22310:30;-1:-1:-1;;;22356:18:1;;;22349:51;22417:18;;72959:77:0;22096:345:1;72959:77:0;72742:331;;;:::o;90447:348::-;90540:4;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;90557:73;;;;-1:-1:-1;;;90557:73:0;;29925:2:1;90557:73:0;;;29907:21:1;29964:2;29944:18;;;29937:30;30003:34;29983:18;;;29976:62;-1:-1:-1;;;30054:18:1;;;30047:42;30106:19;;90557:73:0;29723:408:1;90557:73:0;90641:13;90657:23;90672:7;90657:14;:23::i;:::-;90641:39;;90710:5;-1:-1:-1;;;;;90699:16:0;:7;-1:-1:-1;;;;;90699:16:0;;:51;;;;90743:7;-1:-1:-1;;;;;90719:31:0;:20;90731:7;90719:11;:20::i;:::-;-1:-1:-1;;;;;90719:31:0;;90699:51;:87;;;-1:-1:-1;;;;;;87693:25:0;;;87669:4;87693:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;90754:32;90691:96;90447:348;-1:-1:-1;;;;90447:348:0:o;93368:544::-;93493:4;-1:-1:-1;;;;;93466:31:0;:23;93481:7;93466:14;:23::i;:::-;-1:-1:-1;;;;;93466:31:0;;93458:85;;;;-1:-1:-1;;;93458:85:0;;30338:2:1;93458:85:0;;;30320:21:1;30377:2;30357:18;;;30350:30;30416:34;30396:18;;;30389:62;-1:-1:-1;;;30467:18:1;;;30460:39;30516:19;;93458:85:0;30136:405:1;93458:85:0;-1:-1:-1;;;;;93562:16:0;;93554:65;;;;-1:-1:-1;;;93554:65:0;;30748:2:1;93554:65:0;;;30730:21:1;30787:2;30767:18;;;30760:30;30826:34;30806:18;;;30799:62;-1:-1:-1;;;30877:18:1;;;30870:34;30921:19;;93554:65:0;30546:400:1;93554:65:0;93632:39;93653:4;93659:2;93663:7;93632:20;:39::i;:::-;93736:29;93753:1;93757:7;93736:8;:29::i;:::-;-1:-1:-1;;;;;93778:15:0;;;;;;:9;:15;;;;;:20;;93797:1;;93778:15;:20;;93797:1;;93778:20;:::i;:::-;;;;-1:-1:-1;;;;;;;93809:13:0;;;;;;:9;:13;;;;;:18;;93826:1;;93809:13;:18;;93826:1;;93809:18;:::i;:::-;;;;-1:-1:-1;;93838:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;93838:21:0;-1:-1:-1;;;;;93838:21:0;;;;;;;;;93877:27;;93838:16;;93877:27;;;;;;;93368:544;;;:::o;104348:543::-;104456:11;:13;;104428:15;;;104456:13;;;:::i;:::-;;;;;;104490:11;;104480:21;;104514:34;104536:2;104540:7;104514:21;:34::i;:::-;104615:25;;;;:16;:25;;;;;:38;;-1:-1:-1;;;;;;104615:38:0;104643:10;104615:38;;;104666:22;104676:2;104632:7;104666:9;:22::i;:::-;104705:17;;:21;104701:79;;104743:19;;;;:10;:19;;;;;;;;:25;;;;;;;;:::i;:::-;;104701:79;104827:31;64441:210;74373:443;74453:16;74471:14;74497:35;74535:29;74556:7;74535:20;:29::i;:::-;74583:16;;74497:67;;-1:-1:-1;74603:1:0;-1:-1:-1;74583:21:0;74575:62;;;;-1:-1:-1;;;74575:62:0;;31283:2:1;74575:62:0;;;31265:21:1;31322:2;31302:18;;;31295:30;31361;31341:18;;;31334:58;31409:18;;74575:62:0;31081:352:1;74575:62:0;74662:16;;74658:79;;74716:4;74723:1;74700:25;;;;;;;74658:79;74755:9;74765:1;74755:12;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;74755:12:0;74802:5;74796;74769:23;74784:7;74769:14;:23::i;:::-;74793:1;74769:26;;;;;;;;:::i;:::-;;;;;;;;;:32;;;;:::i;:::-;:38;;;;:::i;:::-;74747:61;;;;;74373:443;;;;;:::o;19095:158::-;19168:4;19192:53;19200:3;-1:-1:-1;;;;;19220:23:0;;19192:7;:53::i;71064:111::-;71155:4;71129:32;;;;:17;:32;;;;;;;;:38;;;;;;;;:::i;68835:548::-;-1:-1:-1;;;;;68958:26:0;;68979:4;68958:26;;68950:55;;;;-1:-1:-1;;;68950:55:0;;32070:2:1;68950:55:0;;;32052:21:1;32109:2;32089:18;;;32082:30;-1:-1:-1;;;32128:18:1;;;32121:46;32184:18;;68950:55:0;31868:340:1;68950:55:0;-1:-1:-1;;;;;69024:20:0;;25483;69016:72;;;;-1:-1:-1;;;69016:72:0;;32415:2:1;69016:72:0;;;32397:21:1;32454:2;32434:18;;;32427:30;32493:34;32473:18;;;32466:62;-1:-1:-1;;;32544:18:1;;;32537:35;32589:19;;69016:72:0;32213:401:1;69016:72:0;69104:31;:11;69125:9;69104:20;:31::i;:::-;69099:277;;-1:-1:-1;;;;;69152:28:0;;;;;;:17;:28;;;;;:38;;69183:7;;69152:38;:::i;:::-;-1:-1:-1;;;;;;69205:37:0;;;;;;:26;:37;;;;;;:56;;-1:-1:-1;;69205:56:0;;;;;;;69281:42;69312:10;;69205:37;69281:42;;;69338:26;:11;69354:9;69338:15;:26::i;19592:117::-;19655:7;19682:19;19690:3;16349:18;;16266:109;20053:158;20127:7;20178:22;20182:3;20194:5;20178:3;:22::i;75549:771::-;75698:38;;;75690:64;;;;-1:-1:-1;;;75690:64:0;;23940:2:1;75690:64:0;;;23922:21:1;23979:2;23959:18;;;23952:30;-1:-1:-1;;;23998:18:1;;;23991:43;24051:18;;75690:64:0;23738:337:1;75690:64:0;75765:24;;75800:107;75817:22;;;75800:107;;;75881:11;;75893:1;75881:14;;;;;;;:::i;:::-;;;;;;;75861:34;;;;;:::i;:::-;;-1:-1:-1;75841:3:0;;;;:::i;:::-;;;;75800:107;;;;75944:5;75925:16;:24;75917:60;;;;-1:-1:-1;;;75917:60:0;;28076:2:1;75917:60:0;;;28058:21:1;28115:2;28095:18;;;28088:30;-1:-1:-1;;;28134:18:1;;;28127:53;28197:18;;75917:60:0;27874:347:1;75917:60:0;-1:-1:-1;;;;;75988:37:0;;;;;;:26;:37;;;;;:49;;76028:9;;75988:49;:::i;:::-;-1:-1:-1;;;;;;76048:31:0;;;;;;:20;:31;;;;;:45;;76082:11;;76048:45;:::i;:::-;-1:-1:-1;;;;;;76108:26:0;;76129:4;76108:26;76104:209;;;76156:47;76180:9;;76191:11;;76156:47;;;;;;;;;:::i;:::-;;;;;;;;76104:209;;;76267:9;-1:-1:-1;;;;;76241:60:0;;76278:9;;76289:11;;76241:60;;;;;;;;;:::i;76104:209::-;75679:641;75549:771;;;;;:::o;70296:196::-;70406:10;70388:29;;;;:17;:29;;;;;:35;;70420:3;;70388:35;:::i;:::-;-1:-1:-1;70461:10:0;70434:38;;;;:26;:38;;;;;:50;;-1:-1:-1;;70434:50:0;;;;;;;;;;-1:-1:-1;;70296:196:0:o;92671:360::-;92731:13;92747:23;92762:7;92747:14;:23::i;:::-;92731:39;;92783:48;92804:5;92819:1;92823:7;92783:20;:48::i;:::-;92872:29;92889:1;92893:7;92872:8;:29::i;:::-;-1:-1:-1;;;;;92914:16:0;;;;;;:9;:16;;;;;:21;;92934:1;;92914:16;:21;;92934:1;;92914:21;:::i;:::-;;;;-1:-1:-1;;92953:16:0;;;;:7;:16;;;;;;92946:23;;-1:-1:-1;;;;;;92946:23:0;;;92987:36;92961:7;;92953:16;-1:-1:-1;;;;;92987:36:0;;;;;92953:16;;92987:36;92720:311;92671:360;:::o;82204:689::-;82343:25;;;;:16;:25;;;;;;-1:-1:-1;;;;;82343:25:0;82380:4;82343:42;82339:302;;82437:25;;;;:16;:25;;;;;;82405:109;;-1:-1:-1;;;;;82437:25:0;-1:-1:-1;;;82405:31:0;:109::i;:::-;82401:229;;;82566:25;;;;:16;:25;;;;;;;;82534:81;;-1:-1:-1;;;82534:81:0;;-1:-1:-1;;;;;6371:55:1;;;82534:81:0;;;6353:74:1;6443:18;;;6436:34;;;82566:25:0;;;;82534:65;;6326:18:1;;82534:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82401:229;82697:19;;;;:10;:19;;;;;82691:33;;;;;:::i;:::-;:38;;-1:-1:-1;82687:97:0;;82753:19;;;;:10;:19;;;;;82746:26;;;:::i;:::-;82856:25;;;;:16;:25;;;;;82849:32;;-1:-1:-1;;;;;;82849:32:0;;;-1:-1:-1;82204:689:0:o;70779:198::-;70876:25;;;;:16;:25;;;;;;-1:-1:-1;;;;;70876:25:0;70905:10;70876:39;70868:65;;;;-1:-1:-1;;;70868:65:0;;27601:2:1;70868:65:0;;;27583:21:1;27640:2;27620:18;;;27613:30;-1:-1:-1;;;27659:18:1;;;27652:43;27712:18;;70868:65:0;27399:337:1;70569:129:0;70670:10;70650:31;;;;:19;:31;;;;;:40;;70684:6;;70650:40;:::i;18767:152::-;18837:4;18861:50;18866:3;-1:-1:-1;;;;;18886:23:0;;18861:4;:50::i;102484:481::-;102587:11;:13;;102559:15;;;102587:13;;;:::i;:::-;;;;-1:-1:-1;;102621:11:0;;102699:25;;;;:16;:25;;;;;:41;;-1:-1:-1;;;;;;102699:41:0;102735:4;102699:41;;;102621:11;-1:-1:-1;102753:22:0;102763:2;102621:11;102753:9;:22::i;71264:123::-;71364:4;71336:34;;;;:19;:34;;;;;:43;;71373:6;;71336:43;:::i;44527:290::-;44614:4;44723:23;44738:7;44723:14;:23::i;:::-;:86;;;;;44763:46;44788:7;44797:11;44763:24;:46::i;89568:272::-;89682:28;89692:4;89698:2;89702:7;89682:9;:28::i;:::-;89729:48;89752:4;89758:2;89762:7;89771:5;89729:22;:48::i;:::-;89721:111;;;;-1:-1:-1;;;89721:111:0;;;;;;;:::i;73412:458::-;73482:25;73524:31;;;:22;:31;;;;;:38;:42;73520:276;;-1:-1:-1;73590:31:0;;;;:22;:31;;;;;;73412:458::o;73520:276::-;73706:1;73670:25;;;:16;:25;;;;;;;;;-1:-1:-1;;;;;73670:25:0;73643:53;;:26;:53;;;;;:60;:64;73639:157;;-1:-1:-1;73731:53:0;73758:25;;;:16;:25;;;;;;;;;-1:-1:-1;;;;;73758:25:0;73731:53;;:26;:53;;;;;;73412:458::o;73639:157::-;-1:-1:-1;;73848:4:0;73813:41;;;;:26;:41;;;;;;73412:458::o;73143:191::-;73206:25;73233:17;73271:29;73292:7;73271:20;:29::i;:::-;73302:23;73317:7;73302:14;:23::i;:::-;73263:63;;;;73143:191;;;:::o;71726:962::-;71811:17;71831:25;;;:16;:25;;;;;;71785:13;;-1:-1:-1;;;;;71831:25:0;71876:42;:22;71831:25;71876:31;:42::i;:::-;71875:43;71867:77;;;;-1:-1:-1;;;71867:77:0;;22298:2:1;71867:77:0;;;22280:21:1;22337:2;22317:18;;;22310:30;-1:-1:-1;;;22356:18:1;;;22349:51;22417:18;;71867:77:0;22096:345:1;71867:77:0;71967:19;;;;:10;:19;;;;;71961:33;;;;;:::i;:::-;:38;;-1:-1:-1;71957:284:0;;-1:-1:-1;;;;;72026:30:0;;;;;;:19;:30;;;;;72020:44;;;;;:::i;:::-;:49;;-1:-1:-1;72016:173:0;;-1:-1:-1;;;;;72121:30:0;;;;;;:19;:30;;;;;;;;72152:19;;;:10;:19;;;;;;72104:68;;;;72121:30;72104:68;;:::i;:::-;;;;;;;;;;;;;72090:83;;;71726:962;;;:::o;72016:173::-;72210:19;;;;:10;:19;;;;;72203:26;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71726:962;;;:::o;71957:284::-;72257:87;72289:9;-1:-1:-1;;;72257:31:0;:87::i;:::-;72253:196;;;72368:69;;-1:-1:-1;;;72368:69:0;;72422:4;72368:69;;;6353:74:1;6443:18;;;6436:34;;;-1:-1:-1;;;;;72368:45:0;;;;;6326:18:1;;72368:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72368:69:0;;;;;;;;;;;;:::i;72253:196::-;-1:-1:-1;;;;;72466:37:0;;;;;;:26;:37;;;;;;;;72461:220;;-1:-1:-1;;;;;72551:28:0;;;;;;:17;:28;;;;;72581:18;:7;:16;:18::i;:::-;72534:66;;;;;;;;;:::i;72461:220::-;-1:-1:-1;;;;;72641:28:0;;;;;;:17;:28;;;;;72634:35;;;;;:::i;72461:220::-;71800:888;71726:962;;;:::o;69446:229::-;69518:31;:11;69539:9;69518:20;:31::i;:::-;69514:154;;;69570:44;;69603:10;;-1:-1:-1;;;;;69570:44:0;;;;;;;;69628:29;:11;69647:9;69628:18;:29::i;80983:548::-;81080:31;:11;81101:9;81080:20;:31::i;:::-;81072:74;;;;-1:-1:-1;;;81072:74:0;;35648:2:1;81072:74:0;;;35630:21:1;35687:2;35667:18;;;35660:30;35726:32;35706:18;;;35699:60;35776:18;;81072:74:0;35446:354:1;81072:74:0;-1:-1:-1;;;;;81165:27:0;;;;:124;;;81196:93;81228:11;-1:-1:-1;;;81196:31:0;:93::i;:::-;81157:152;;;;-1:-1:-1;;;81157:152:0;;36007:2:1;81157:152:0;;;35989:21:1;36046:2;36026:18;;;36019:30;-1:-1:-1;;;36065:18:1;;;36058:45;36120:18;;81157:152:0;35805:339:1;81157:152:0;-1:-1:-1;;;;;81324:32:0;;;;;;;:21;:32;;;;;;;;:47;;;;81320:204;;-1:-1:-1;;;;;81388:32:0;;;;;;;:21;:32;;;;;;:46;;-1:-1:-1;;;;;;81388:46:0;;;;;;;;;81454:58;81501:10;;81388:46;:32;81454:58;;;80983:548;;:::o;67475:452::-;67577:4;-1:-1:-1;;;;;;67601:45:0;;-1:-1:-1;;;67601:45:0;;:85;;;67650:36;67674:11;67650:23;:36::i;:::-;67601:152;;;-1:-1:-1;;;;;;;67703:50:0;;-1:-1:-1;;;67703:50:0;67601:152;:202;;;-1:-1:-1;;;;;;;67757:46:0;;-1:-1:-1;;;67757:46:0;67601:202;:268;;;-1:-1:-1;;;;;;;67820:49:0;;-1:-1:-1;;;67820:49:0;67601:268;:318;;;-1:-1:-1;;;;;;;67873:46:0;;-1:-1:-1;;;67873:46:0;67594:325;67475:452;-1:-1:-1;;67475:452:0:o;97409:157::-;97519:35;97536:4;97542:2;97546:7;97519:16;:35::i;81596:270::-;81702:10;81725:3;81680:33;;;:21;:33;;;;;;-1:-1:-1;;;;;81680:33:0;:49;81676:183;;81798:10;81776:33;;;;:21;:33;;;;;;;;81746:101;;-1:-1:-1;;;81746:101:0;;;;;36412:34:1;;;;-1:-1:-1;;;;;36482:15:1;;;36462:18;;;36455:43;36514:18;;;36507:34;;;81776:33:0;;81746:76;;36324:18:1;;81746:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91137:110;91213:26;91223:2;91227:7;91213:26;;;;;;;;;;;;:9;:26::i;14412:1553::-;14478:4;14617:19;;;:12;;;:19;;;;;;14653:15;;14649:1309;;15015:21;15039:14;15052:1;15039:10;:14;:::i;:::-;15088:18;;15015:38;;-1:-1:-1;15068:17:0;;15088:22;;15109:1;;15088:22;:::i;:::-;15068:42;;15355:17;15375:3;:11;;15387:9;15375:22;;;;;;;;:::i;:::-;;;;;;;;;15355:42;;15521:9;15492:3;:11;;15504:13;15492:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;15598:23;;;:12;;;:23;;;;;;:36;;;15759:17;;15598:3;;15759:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;15854:3;:12;;:19;15867:5;15854:19;;;;;;;;;;;15847:26;;;15897:4;15890:11;;;;;;;;14649:1309;15941:5;15934:12;;;;;16719:204;16814:18;;16786:7;;16814:26;-1:-1:-1;16806:73:0;;;;-1:-1:-1;;;16806:73:0;;36886:2:1;16806:73:0;;;36868:21:1;36925:2;36905:18;;;36898:30;36964:34;36944:18;;;36937:62;-1:-1:-1;;;37015:18:1;;;37008:32;37057:19;;16806:73:0;36684:398:1;16806:73:0;16897:3;:11;;16909:5;16897:18;;;;;;;;:::i;:::-;;;;;;;;;16890:25;;16719:204;;;;:::o;13822:414::-;13885:4;16148:19;;;:12;;;:19;;;;;;13902:327;;-1:-1:-1;13945:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;14128:18;;14106:19;;;:12;;;:19;;;;;;:40;;;;14161:11;;13902:327;-1:-1:-1;14212:5:0;14205:12;;43897:404;43961:4;44159:60;44184:7;-1:-1:-1;;;44159:24:0;:60::i;:::-;:134;;;;-1:-1:-1;44237:56:0;44262:7;-1:-1:-1;;;;;;44237:24:0;:56::i;:::-;44236:57;44152:141;43897:404;-1:-1:-1;;43897:404:0:o;47469:425::-;47608:80;;;-1:-1:-1;;;;;;37249:33:1;;47608:80:0;;;;37231:52:1;;;;47608:80:0;;;;;;;;;;37204:18:1;;;;47608:80:0;;;;;;;-1:-1:-1;;;;;47608:80:0;-1:-1:-1;;;47608:80:0;;;47737:47;;47562:4;;47608:80;47562:4;;;;-1:-1:-1;;;;;47737:18:0;;;47762:5;;47737:47;;47608:80;;47737:47;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47699:85;;;;47815:2;47799:6;:13;:18;47795:36;;;47826:5;47819:12;;;;;;;47795:36;47849:7;:37;;;;;47871:6;47860:26;;;;;;;;;;;;:::i;:::-;47842:44;47469:425;-1:-1:-1;;;;;;47469:425:0:o;94769:843::-;94890:4;-1:-1:-1;;;;;94916:13:0;;25483:20;25522:8;94912:693;;94952:72;;-1:-1:-1;;;94952:72:0;;-1:-1:-1;;;;;94952:36:0;;;;;:72;;42773:10;;95003:4;;95009:7;;95018:5;;94952:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94952:72:0;;;;;;;;-1:-1:-1;;94952:72:0;;;;;;;;;;;;:::i;:::-;;;94948:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;95198:13:0;;95194:341;;95241:60;;-1:-1:-1;;;95241:60:0;;;;;;;:::i;95194:341::-;95485:6;95479:13;95470:6;95466:2;95462:15;95455:38;94948:602;-1:-1:-1;;;;;;95075:55:0;-1:-1:-1;;;95075:55:0;;-1:-1:-1;95068:62:0;;94912:693;-1:-1:-1;95589:4:0;94769:843;;;;;;:::o;40395:723::-;40451:13;40672:10;40668:53;;-1:-1:-1;;40699:10:0;;;;;;;;;;;;-1:-1:-1;;;40699:10:0;;;;;40395:723::o;40668:53::-;40746:5;40731:12;40787:78;40794:9;;40787:78;;40820:8;;;;:::i;:::-;;-1:-1:-1;40843:10:0;;-1:-1:-1;40851:2:0;40843:10;;:::i;:::-;;;40787:78;;;40875:19;40907:6;-1:-1:-1;;;;;40897:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40897:17:0;;40875:39;;40925:154;40932:10;;40925:154;;40959:11;40969:1;40959:11;;:::i;:::-;;-1:-1:-1;41028:10:0;41036:2;41028:5;:10;:::i;:::-;41015:24;;:2;:24;:::i;:::-;41002:39;;40985:6;40992;40985:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;40985:56:0;;;;;;;;-1:-1:-1;41056:11:0;41065:2;41056:11;;:::i;:::-;;;40925:154;;82946:333;83038:53;83065:25;;;:16;:25;;;;;;;;;-1:-1:-1;;;;;83065:25:0;83038:53;;:26;:53;;;;;;;;83034:238;;;83154:25;;;;:16;:25;;;;;;;;83115:100;;-1:-1:-1;;;83115:100:0;;-1:-1:-1;;;;;36430:15:1;;;83115:100:0;;;36412:34:1;36482:15;;;36462:18;;;36455:43;36514:18;;;36507:34;;;83154:25:0;;;;83115:81;;36324:18:1;;83115:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;83107:154;;;;-1:-1:-1;;;83107:154:0;;38634:2:1;83107:154:0;;;38616:21:1;38673:2;38653:18;;;38646:30;38712:34;38692:18;;;38685:62;-1:-1:-1;;;38763:18:1;;;38756:39;38812:19;;83107:154:0;38432:405:1;91474:250:0;91570:18;91576:2;91580:7;91570:5;:18::i;:::-;91607:54;91638:1;91642:2;91646:7;91655:5;91607:22;:54::i;:::-;91599:117;;;;-1:-1:-1;;;91599:117:0;;;;;;;:::i;92060:382::-;-1:-1:-1;;;;;92140:16:0;;92132:61;;;;-1:-1:-1;;;92132:61:0;;39044:2:1;92132:61:0;;;39026:21:1;;;39063:18;;;39056:30;39122:34;39102:18;;;39095:62;39174:18;;92132:61:0;38842:356:1;92132:61:0;90218:4;90242:16;;;:7;:16;;;;;;-1:-1:-1;;;;;90242:16:0;:30;92204:58;;;;-1:-1:-1;;;92204:58:0;;39405:2:1;92204:58:0;;;39387:21:1;39444:2;39424:18;;;39417:30;39483;39463:18;;;39456:58;39531:18;;92204:58:0;39203:352:1;92204:58:0;92275:45;92304:1;92308:2;92312:7;92275:20;:45::i;:::-;-1:-1:-1;;;;;92333:13:0;;;;;;:9;:13;;;;;:18;;92350:1;;92333:13;:18;;92350:1;;92333:18;:::i;:::-;;;;-1:-1:-1;;92362:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;92362:21:0;-1:-1:-1;;;;;92362:21:0;;;;;;;;92401:33;;92362:16;;;92401:33;;92362:16;;92401:33;92060:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:154::-;-1:-1:-1;;;;;671:5:1;667:54;660:5;657:65;647:93;;736:1;733;726:12;751:247;810:6;863:2;851:9;842:7;838:23;834:32;831:52;;;879:1;876;869:12;831:52;918:9;905:23;937:31;962:5;937:31;:::i;1003:258::-;1075:1;1085:113;1099:6;1096:1;1093:13;1085:113;;;1175:11;;;1169:18;1156:11;;;1149:39;1121:2;1114:10;1085:113;;;1216:6;1213:1;1210:13;1207:48;;;-1:-1:-1;;1251:1:1;1233:16;;1226:27;1003:258::o;1266:::-;1308:3;1346:5;1340:12;1373:6;1368:3;1361:19;1389:63;1445:6;1438:4;1433:3;1429:14;1422:4;1415:5;1411:16;1389:63;:::i;:::-;1506:2;1485:15;-1:-1:-1;;1481:29:1;1472:39;;;;1513:4;1468:50;;1266:258;-1:-1:-1;;1266:258:1:o;1529:220::-;1678:2;1667:9;1660:21;1641:4;1698:45;1739:2;1728:9;1724:18;1716:6;1698:45;:::i;1754:180::-;1813:6;1866:2;1854:9;1845:7;1841:23;1837:32;1834:52;;;1882:1;1879;1872:12;1834:52;-1:-1:-1;1905:23:1;;1754:180;-1:-1:-1;1754:180:1:o;2170:315::-;2238:6;2246;2299:2;2287:9;2278:7;2274:23;2270:32;2267:52;;;2315:1;2312;2305:12;2267:52;2354:9;2341:23;2373:31;2398:5;2373:31;:::i;:::-;2423:5;2475:2;2460:18;;;;2447:32;;-1:-1:-1;;;2170:315:1:o;2490:435::-;2543:3;2581:5;2575:12;2608:6;2603:3;2596:19;2634:4;2663:2;2658:3;2654:12;2647:19;;2700:2;2693:5;2689:14;2721:1;2731:169;2745:6;2742:1;2739:13;2731:169;;;2806:13;;2794:26;;2840:12;;;;2875:15;;;;2767:1;2760:9;2731:169;;;-1:-1:-1;2916:3:1;;2490:435;-1:-1:-1;;;;;2490:435:1:o;2930:261::-;3109:2;3098:9;3091:21;3072:4;3129:56;3181:2;3170:9;3166:18;3158:6;3129:56;:::i;3196:348::-;3248:8;3258:6;3312:3;3305:4;3297:6;3293:17;3289:27;3279:55;;3330:1;3327;3320:12;3279:55;-1:-1:-1;3353:20:1;;-1:-1:-1;;;;;3385:30:1;;3382:50;;;3428:1;3425;3418:12;3382:50;3465:4;3457:6;3453:17;3441:29;;3517:3;3510:4;3501:6;3493;3489:19;3485:30;3482:39;3479:59;;;3534:1;3531;3524:12;3549:479;3629:6;3637;3645;3698:2;3686:9;3677:7;3673:23;3669:32;3666:52;;;3714:1;3711;3704:12;3666:52;3750:9;3737:23;3727:33;;3811:2;3800:9;3796:18;3783:32;-1:-1:-1;;;;;3830:6:1;3827:30;3824:50;;;3870:1;3867;3860:12;3824:50;3909:59;3960:7;3951:6;3940:9;3936:22;3909:59;:::i;:::-;3549:479;;3987:8;;-1:-1:-1;3883:85:1;;-1:-1:-1;;;;3549:479:1:o;4033:375::-;4104:8;4114:6;4168:3;4161:4;4153:6;4149:17;4145:27;4135:55;;4186:1;4183;4176:12;4135:55;-1:-1:-1;4209:20:1;;-1:-1:-1;;;;;4241:30:1;;4238:50;;;4284:1;4281;4274:12;4238:50;4321:4;4313:6;4309:17;4297:29;;4381:3;4374:4;4364:6;4361:1;4357:14;4349:6;4345:27;4341:38;4338:47;4335:67;;;4398:1;4395;4388:12;4413:865;4552:6;4560;4568;4576;4584;4637:2;4625:9;4616:7;4612:23;4608:32;4605:52;;;4653:1;4650;4643:12;4605:52;4689:9;4676:23;4666:33;;4750:2;4739:9;4735:18;4722:32;-1:-1:-1;;;;;4814:2:1;4806:6;4803:14;4800:34;;;4830:1;4827;4820:12;4800:34;4869:78;4939:7;4930:6;4919:9;4915:22;4869:78;:::i;:::-;4966:8;;-1:-1:-1;4843:104:1;-1:-1:-1;5054:2:1;5039:18;;5026:32;;-1:-1:-1;5070:16:1;;;5067:36;;;5099:1;5096;5089:12;5067:36;;5138:80;5210:7;5199:8;5188:9;5184:24;5138:80;:::i;:::-;4413:865;;;;-1:-1:-1;4413:865:1;;-1:-1:-1;5237:8:1;;5112:106;4413:865;-1:-1:-1;;;4413:865:1:o;5283:456::-;5360:6;5368;5376;5429:2;5417:9;5408:7;5404:23;5400:32;5397:52;;;5445:1;5442;5435:12;5397:52;5484:9;5471:23;5503:31;5528:5;5503:31;:::i;:::-;5553:5;-1:-1:-1;5610:2:1;5595:18;;5582:32;5623:33;5582:32;5623:33;:::i;:::-;5283:456;;5675:7;;-1:-1:-1;;;5729:2:1;5714:18;;;;5701:32;;5283:456::o;5926:248::-;5994:6;6002;6055:2;6043:9;6034:7;6030:23;6026:32;6023:52;;;6071:1;6068;6061:12;6023:52;-1:-1:-1;;6094:23:1;;;6164:2;6149:18;;;6136:32;;-1:-1:-1;5926:248:1:o;6481:411::-;6552:6;6560;6613:2;6601:9;6592:7;6588:23;6584:32;6581:52;;;6629:1;6626;6619:12;6581:52;6669:9;6656:23;-1:-1:-1;;;;;6694:6:1;6691:30;6688:50;;;6734:1;6731;6724:12;6688:50;6773:59;6824:7;6815:6;6804:9;6800:22;6773:59;:::i;:::-;6851:8;;6747:85;;-1:-1:-1;6481:411:1;-1:-1:-1;;;;6481:411:1:o;6897:546::-;6977:6;6985;6993;7046:2;7034:9;7025:7;7021:23;7017:32;7014:52;;;7062:1;7059;7052:12;7014:52;7101:9;7088:23;7120:31;7145:5;7120:31;:::i;:::-;7170:5;-1:-1:-1;7226:2:1;7211:18;;7198:32;-1:-1:-1;;;;;7242:30:1;;7239:50;;;7285:1;7282;7275:12;7448:681;7619:2;7671:21;;;7741:13;;7644:18;;;7763:22;;;7590:4;;7619:2;7842:15;;;;7816:2;7801:18;;;7590:4;7885:218;7899:6;7896:1;7893:13;7885:218;;;7964:13;;-1:-1:-1;;;;;7960:62:1;7948:75;;8078:15;;;;8043:12;;;;7921:1;7914:9;7885:218;;;-1:-1:-1;8120:3:1;;7448:681;-1:-1:-1;;;;;;7448:681:1:o;8134:797::-;8264:6;8272;8280;8288;8341:2;8329:9;8320:7;8316:23;8312:32;8309:52;;;8357:1;8354;8347:12;8309:52;8397:9;8384:23;-1:-1:-1;;;;;8467:2:1;8459:6;8456:14;8453:34;;;8483:1;8480;8473:12;8453:34;8522:78;8592:7;8583:6;8572:9;8568:22;8522:78;:::i;:::-;8619:8;;-1:-1:-1;8496:104:1;-1:-1:-1;8707:2:1;8692:18;;8679:32;;-1:-1:-1;8723:16:1;;;8720:36;;;8752:1;8749;8742:12;8720:36;;8791:80;8863:7;8852:8;8841:9;8837:24;8791:80;:::i;:::-;8134:797;;;;-1:-1:-1;8890:8:1;-1:-1:-1;;;;8134:797:1:o;8936:592::-;9043:6;9051;9059;9112:2;9100:9;9091:7;9087:23;9083:32;9080:52;;;9128:1;9125;9118:12;9080:52;9167:9;9154:23;9186:31;9211:5;9186:31;:::i;:::-;9236:5;-1:-1:-1;9292:2:1;9277:18;;9264:32;-1:-1:-1;;;;;9308:30:1;;9305:50;;;9351:1;9348;9341:12;9305:50;9390:78;9460:7;9451:6;9440:9;9436:22;9390:78;:::i;9533:118::-;9619:5;9612:13;9605:21;9598:5;9595:32;9585:60;;9641:1;9638;9631:12;9656:681;9742:6;9750;9758;9766;9819:2;9807:9;9798:7;9794:23;9790:32;9787:52;;;9835:1;9832;9825:12;9787:52;9874:9;9861:23;9893:31;9918:5;9893:31;:::i;:::-;9943:5;-1:-1:-1;9999:2:1;9984:18;;9971:32;-1:-1:-1;;;;;10015:30:1;;10012:50;;;10058:1;10055;10048:12;10012:50;10097:59;10148:7;10139:6;10128:9;10124:22;10097:59;:::i;:::-;10175:8;;-1:-1:-1;10071:85:1;-1:-1:-1;;10262:2:1;10247:18;;10234:32;10275:30;10234:32;10275:30;:::i;:::-;9656:681;;;;-1:-1:-1;9656:681:1;;-1:-1:-1;;9656:681:1:o;10342:127::-;10403:10;10398:3;10394:20;10391:1;10384:31;10434:4;10431:1;10424:15;10458:4;10455:1;10448:15;10474:275;10545:2;10539:9;10610:2;10591:13;;-1:-1:-1;;10587:27:1;10575:40;;-1:-1:-1;;;;;10630:34:1;;10666:22;;;10627:62;10624:88;;;10692:18;;:::i;:::-;10728:2;10721:22;10474:275;;-1:-1:-1;10474:275:1:o;10754:187::-;10803:4;-1:-1:-1;;;;;10828:6:1;10825:30;10822:56;;;10858:18;;:::i;:::-;-1:-1:-1;10924:2:1;10903:15;-1:-1:-1;;10899:29:1;10930:4;10895:40;;10754:187::o;10946:338::-;11011:5;11040:53;11056:36;11085:6;11056:36;:::i;:::-;11040:53;:::i;:::-;11031:62;;11116:6;11109:5;11102:21;11156:3;11147:6;11142:3;11138:16;11135:25;11132:45;;;11173:1;11170;11163:12;11132:45;11222:6;11217:3;11210:4;11203:5;11199:16;11186:43;11276:1;11269:4;11260:6;11253:5;11249:18;11245:29;11238:40;10946:338;;;;;:::o;11289:451::-;11358:6;11411:2;11399:9;11390:7;11386:23;11382:32;11379:52;;;11427:1;11424;11417:12;11379:52;11467:9;11454:23;-1:-1:-1;;;;;11492:6:1;11489:30;11486:50;;;11532:1;11529;11522:12;11486:50;11555:22;;11608:4;11600:13;;11596:27;-1:-1:-1;11586:55:1;;11637:1;11634;11627:12;11586:55;11660:74;11726:7;11721:2;11708:16;11703:2;11699;11695:11;11660:74;:::i;11745:1283::-;11877:6;11885;11893;11946:2;11934:9;11925:7;11921:23;11917:32;11914:52;;;11962:1;11959;11952:12;11914:52;12002:9;11989:23;-1:-1:-1;;;;;12072:2:1;12064:6;12061:14;12058:34;;;12088:1;12085;12078:12;12058:34;12126:6;12115:9;12111:22;12101:32;;12171:7;12164:4;12160:2;12156:13;12152:27;12142:55;;12193:1;12190;12183:12;12142:55;12229:2;12216:16;12251:4;12274:2;12270;12267:10;12264:36;;;12280:18;;:::i;:::-;12326:2;12323:1;12319:10;12349:28;12373:2;12369;12365:11;12349:28;:::i;:::-;12411:15;;;12481:11;;;12477:20;;;12442:12;;;;12509:19;;;12506:39;;;12541:1;12538;12531:12;12506:39;12565:11;;;;12585:142;12601:6;12596:3;12593:15;12585:142;;;12667:17;;12655:30;;12618:12;;;;12705;;;;12585:142;;;12746:5;-1:-1:-1;;;12789:18:1;;12776:32;;-1:-1:-1;;12820:16:1;;;12817:36;;;12849:1;12846;12839:12;12817:36;;12888:80;12960:7;12949:8;12938:9;12934:24;12888:80;:::i;13033:540::-;13110:6;13118;13126;13179:2;13167:9;13158:7;13154:23;13150:32;13147:52;;;13195:1;13192;13185:12;13147:52;13235:9;13222:23;-1:-1:-1;;;;;13260:6:1;13257:30;13254:50;;;13300:1;13297;13290:12;13254:50;13339:59;13390:7;13381:6;13370:9;13366:22;13339:59;:::i;:::-;13417:8;;-1:-1:-1;13313:85:1;-1:-1:-1;;13502:2:1;13487:18;;13474:32;13515:28;13474:32;13515:28;:::i;:::-;13562:5;13552:15;;;13033:540;;;;;:::o;13760:382::-;13825:6;13833;13886:2;13874:9;13865:7;13861:23;13857:32;13854:52;;;13902:1;13899;13892:12;13854:52;13941:9;13928:23;13960:31;13985:5;13960:31;:::i;:::-;14010:5;-1:-1:-1;14067:2:1;14052:18;;14039:32;14080:30;14039:32;14080:30;:::i;:::-;14129:7;14119:17;;;13760:382;;;;;:::o;14147:241::-;14203:6;14256:2;14244:9;14235:7;14231:23;14227:32;14224:52;;;14272:1;14269;14262:12;14224:52;14311:9;14298:23;14330:28;14352:5;14330:28;:::i;14393:415::-;14460:6;14468;14521:2;14509:9;14500:7;14496:23;14492:32;14489:52;;;14537:1;14534;14527:12;14489:52;14576:9;14563:23;14595:31;14620:5;14595:31;:::i;:::-;14645:5;-1:-1:-1;14702:2:1;14687:18;;14674:32;14750:6;14737:20;;14725:33;;14715:61;;14772:1;14769;14762:12;14813:932;14952:6;14960;14968;14976;14984;15037:2;15025:9;15016:7;15012:23;15008:32;15005:52;;;15053:1;15050;15043:12;15005:52;15092:9;15079:23;15111:31;15136:5;15111:31;:::i;:::-;15161:5;-1:-1:-1;15217:2:1;15202:18;;15189:32;-1:-1:-1;;;;;15270:14:1;;;15267:34;;;15297:1;15294;15287:12;15750:795;15845:6;15853;15861;15869;15922:3;15910:9;15901:7;15897:23;15893:33;15890:53;;;15939:1;15936;15929:12;15890:53;15978:9;15965:23;15997:31;16022:5;15997:31;:::i;:::-;16047:5;-1:-1:-1;16104:2:1;16089:18;;16076:32;16117:33;16076:32;16117:33;:::i;:::-;16169:7;-1:-1:-1;16223:2:1;16208:18;;16195:32;;-1:-1:-1;16278:2:1;16263:18;;16250:32;-1:-1:-1;;;;;16294:30:1;;16291:50;;;16337:1;16334;16327:12;16291:50;16360:22;;16413:4;16405:13;;16401:27;-1:-1:-1;16391:55:1;;16442:1;16439;16432:12;16391:55;16465:74;16531:7;16526:2;16513:16;16508:2;16504;16500:11;16465:74;:::i;:::-;16455:84;;;15750:795;;;;;;;:::o;16550:492::-;16611:3;16649:5;16643:12;16676:6;16671:3;16664:19;16702:4;16731:2;16726:3;16722:12;16715:19;;16768:2;16761:5;16757:14;16789:1;16799:218;16813:6;16810:1;16807:13;16799:218;;;16878:13;;-1:-1:-1;;;;;16874:62:1;16862:75;;16957:12;;;;16992:15;;;;16835:1;16828:9;16799:218;;17047:285;17242:2;17231:9;17224:21;17205:4;17262:64;17322:2;17311:9;17307:18;17299:6;17262:64;:::i;17337:489::-;17610:2;17599:9;17592:21;17573:4;17636:64;17696:2;17685:9;17681:18;17673:6;17636:64;:::i;:::-;17748:9;17740:6;17736:22;17731:2;17720:9;17716:18;17709:50;17776:44;17813:6;17805;17776:44;:::i;:::-;17768:52;17337:489;-1:-1:-1;;;;;17337:489:1:o;17831:388::-;17899:6;17907;17960:2;17948:9;17939:7;17935:23;17931:32;17928:52;;;17976:1;17973;17966:12;17928:52;18015:9;18002:23;18034:31;18059:5;18034:31;:::i;:::-;18084:5;-1:-1:-1;18141:2:1;18126:18;;18113:32;18154:33;18113:32;18154:33;:::i;18224:400::-;18426:2;18408:21;;;18465:2;18445:18;;;18438:30;18504:34;18499:2;18484:18;;18477:62;-1:-1:-1;;;18570:2:1;18555:18;;18548:34;18614:3;18599:19;;18224:400::o;18629:380::-;18708:1;18704:12;;;;18751;;;18772:61;;18826:4;18818:6;18814:17;18804:27;;18772:61;18879:2;18871:6;18868:14;18848:18;18845:38;18842:161;;;18925:10;18920:3;18916:20;18913:1;18906:31;18960:4;18957:1;18950:15;18988:4;18985:1;18978:15;20254:341;20456:2;20438:21;;;20495:2;20475:18;;;20468:30;-1:-1:-1;;;20529:2:1;20514:18;;20507:47;20586:2;20571:18;;20254:341::o;20600:413::-;20802:2;20784:21;;;20841:2;20821:18;;;20814:30;20880:34;20875:2;20860:18;;20853:62;-1:-1:-1;;;20946:2:1;20931:18;;20924:47;21003:3;20988:19;;20600:413::o;21018:355::-;21220:2;21202:21;;;21259:2;21239:18;;;21232:30;21298:33;21293:2;21278:18;;21271:61;21364:2;21349:18;;21018:355::o;21378:352::-;21580:2;21562:21;;;21619:2;21599:18;;;21592:30;21658;21653:2;21638:18;;21631:58;21721:2;21706:18;;21378:352::o;22446:127::-;22507:10;22502:3;22498:20;22495:1;22488:31;22538:4;22535:1;22528:15;22562:4;22559:1;22552:15;22578:127;22639:10;22634:3;22630:20;22627:1;22620:31;22670:4;22667:1;22660:15;22694:4;22691:1;22684:15;22710:135;22749:3;-1:-1:-1;;22770:17:1;;22767:43;;;22790:18;;:::i;:::-;-1:-1:-1;22837:1:1;22826:13;;22710:135::o;22850:522::-;22928:4;22934:6;22994:11;22981:25;23088:2;23084:7;23073:8;23057:14;23053:29;23049:43;23029:18;23025:68;23015:96;;23107:1;23104;23097:12;23015:96;23134:33;;23186:20;;;-1:-1:-1;;;;;;23218:30:1;;23215:50;;;23261:1;23258;23251:12;23215:50;23294:4;23282:17;;-1:-1:-1;23325:14:1;23321:27;;;23311:38;;23308:58;;;23362:1;23359;23352:12;25687:197;25725:3;25753:6;25794:2;25787:5;25783:14;25821:2;25812:7;25809:15;25806:41;;;25827:18;;:::i;:::-;25876:1;25863:15;;25687:197;-1:-1:-1;;;25687:197:1:o;25889:276::-;26020:3;26058:6;26052:13;26074:53;26120:6;26115:3;26108:4;26100:6;26096:17;26074:53;:::i;:::-;26143:16;;;;;25889:276;-1:-1:-1;;25889:276:1:o;26449:184::-;26519:6;26572:2;26560:9;26551:7;26547:23;26543:32;26540:52;;;26588:1;26585;26578:12;26540:52;-1:-1:-1;26611:16:1;;26449:184;-1:-1:-1;26449:184:1:o;27741:128::-;27781:3;27812:1;27808:6;27805:1;27802:13;27799:39;;;27818:18;;:::i;:::-;-1:-1:-1;27854:9:1;;27741:128::o;28226:1141::-;28530:2;28542:21;;;28515:18;;28598:22;;;28482:4;28677:6;28651:2;28636:18;;28482:4;28711:327;28725:6;28722:1;28719:13;28711:327;;;28800:6;28787:20;28820:31;28845:5;28820:31;:::i;:::-;-1:-1:-1;;;;;28876:54:1;28864:67;;28954:4;29013:15;;;;28978:12;;;;28747:1;28740:9;28711:327;;;-1:-1:-1;29076:19:1;;;29069:4;29054:20;;29047:49;29105:19;;;-1:-1:-1;;;;;29136:31:1;;29133:51;;;29180:1;29177;29170:12;29133:51;29214:6;29211:1;29207:14;29193:28;;29267:6;29259;29252:4;29247:3;29243:14;29230:44;29340:1;29297:16;;29315:4;29293:27;29329:13;;;29293:27;28226:1141;-1:-1:-1;;;;;;28226:1141:1:o;30951:125::-;30991:4;31019:1;31016;31013:8;31010:34;;;31024:18;;:::i;:::-;-1:-1:-1;31061:9:1;;30951:125::o;31438:168::-;31478:7;31544:1;31540;31536:6;31532:14;31529:1;31526:21;31521:1;31514:9;31507:17;31503:45;31500:71;;;31551:18;;:::i;:::-;-1:-1:-1;31591:9:1;;31438:168::o;31611:127::-;31672:10;31667:3;31663:20;31660:1;31653:31;31703:4;31700:1;31693:15;31727:4;31724:1;31717:15;31743:120;31783:1;31809;31799:35;;31814:18;;:::i;:::-;-1:-1:-1;31848:9:1;;31743:120::o;32619:414::-;32821:2;32803:21;;;32860:2;32840:18;;;32833:30;32899:34;32894:2;32879:18;;32872:62;-1:-1:-1;;;32965:2:1;32950:18;;32943:48;33023:3;33008:19;;32619:414::o;33164:973::-;33249:12;;33214:3;;33304:1;33324:18;;;;33377;;;;33404:61;;33458:4;33450:6;33446:17;33436:27;;33404:61;33484:2;33532;33524:6;33521:14;33501:18;33498:38;33495:161;;;33578:10;33573:3;33569:20;33566:1;33559:31;33613:4;33610:1;33603:15;33641:4;33638:1;33631:15;33495:161;33672:18;33699:104;;;;33817:1;33812:319;;;;33665:466;;33699:104;-1:-1:-1;;33732:24:1;;33720:37;;33777:16;;;;-1:-1:-1;33699:104:1;;33812:319;33111:1;33104:14;;;33148:4;33135:18;;33906:1;33920:165;33934:6;33931:1;33928:13;33920:165;;;34012:14;;33999:11;;;33992:35;34055:16;;;;33949:10;;33920:165;;;33924:3;;34114:6;34109:3;34105:16;34098:23;;33665:466;;;;;;;33164:973;;;;:::o;34142:277::-;34315:3;34340:73;34374:38;34408:3;34400:6;34374:38;:::i;:::-;34366:6;34340:73;:::i;34424:636::-;34504:6;34557:2;34545:9;34536:7;34532:23;34528:32;34525:52;;;34573:1;34570;34563:12;34525:52;34606:9;34600:16;-1:-1:-1;;;;;34631:6:1;34628:30;34625:50;;;34671:1;34668;34661:12;34625:50;34694:22;;34747:4;34739:13;;34735:27;-1:-1:-1;34725:55:1;;34776:1;34773;34766:12;34725:55;34805:2;34799:9;34830:49;34846:32;34875:2;34846:32;:::i;34830:49::-;34902:2;34895:5;34888:17;34942:7;34937:2;34932;34928;34924:11;34920:20;34917:33;34914:53;;;34963:1;34960;34953:12;34914:53;34976:54;35027:2;35022;35015:5;35011:14;35006:2;35002;34998:11;34976:54;:::i;35065:376::-;35241:3;35269:38;35303:3;35295:6;35269:38;:::i;:::-;35336:6;35330:13;35352:52;35397:6;35393:2;35386:4;35378:6;35374:17;35352:52;:::i;:::-;35420:15;;35065:376;-1:-1:-1;;;;35065:376:1:o;36552:127::-;36613:10;36608:3;36604:20;36601:1;36594:31;36644:4;36641:1;36634:15;36668:4;36665:1;36658:15;37294:245;37361:6;37414:2;37402:9;37393:7;37389:23;37385:32;37382:52;;;37430:1;37427;37420:12;37382:52;37462:9;37456:16;37481:28;37503:5;37481:28;:::i;37544:512::-;37738:4;-1:-1:-1;;;;;37848:2:1;37840:6;37836:15;37825:9;37818:34;37900:2;37892:6;37888:15;37883:2;37872:9;37868:18;37861:43;;37940:6;37935:2;37924:9;37920:18;37913:34;37983:3;37978:2;37967:9;37963:18;37956:31;38004:46;38045:3;38034:9;38030:19;38022:6;38004:46;:::i;38061:249::-;38130:6;38183:2;38171:9;38162:7;38158:23;38154:32;38151:52;;;38199:1;38196;38189:12;38151:52;38231:9;38225:16;38250:30;38274:5;38250:30;:::i;38315:112::-;38347:1;38373;38363:35;;38378:18;;:::i;:::-;-1:-1:-1;38412:9:1;;38315:112::o

Swarm Source

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