ETH Price: $3,359.15 (-2.76%)
Gas: 2 Gwei

Token

TinyBoxes ([#][#])
 

Overview

Max Total Supply

1,499 [#][#]

Holders

580

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
dirtwolf.eth
Balance
1 [#][#]
0x255EeFD8307B3878be1E620FBd6A0ffA193B1CC5
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

TinyBoxes is to Autoglyphs as Avastars is to CryptoPunks. TinyBoxes are animated patterns of shapes and colors generated and rendered 100% on-chain.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TinyBoxes

Compiler Version
v0.6.8+commit.0bbfe453

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-01-29
*/

// Sources flattened with hardhat v2.0.8 https://hardhat.org

// File @openzeppelin/contracts/math/[email protected]

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @title SignedSafeMath
 * @dev Signed math operations with safety checks that revert on error.
 */
library SignedSafeMath {
    int256 constant private _INT256_MIN = -2**255;

        /**
     * @dev Returns the multiplication of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");

        int256 c = a * b;
        require(c / a == b, "SignedSafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two signed integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "SignedSafeMath: division by zero");
        require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");

        int256 c = a / b;

        return c;
    }

    /**
     * @dev Returns the subtraction of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");

        return c;
    }
}


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

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

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

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

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

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

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

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

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

            MapEntry storage lastEntry = map._entries[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

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

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

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

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

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

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

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

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

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint256(_get(map._inner, bytes32(key), errorMessage)));
    }
}


// File @openzeppelin/contracts/GSN/[email protected]



pragma solidity ^0.6.0;

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

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


// File @openzeppelin/contracts/introspection/[email protected]



pragma solidity ^0.6.0;

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


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.6.2;

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.6.2;

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.6.2;

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.6.0;

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


// File @openzeppelin/contracts/introspection/[email protected]



pragma solidity ^0.6.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

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

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

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

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


// File @openzeppelin/contracts/math/[email protected]



pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

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

        return c;
    }

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

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


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.2;

/**
 * @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) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @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");
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.0;

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

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

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // 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(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(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(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(uint256(_at(set._inner, index)));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` 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);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = byte(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.6.0;











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

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

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

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

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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

    // Base URI
    string private _baseURI;

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

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

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

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

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

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

        return _holderTokens[owner].length();
    }

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

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

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

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

        string memory _tokenURI = _tokenURIs[tokenId];

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

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

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

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = 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 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 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 mecanisms 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 returns (bool) {
        return _tokenOwners.contains(tokenId);
    }

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

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

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

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

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

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

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

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

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

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

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

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        private returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

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


// File @openzeppelin/contracts/access/[email protected]



pragma solidity ^0.6.0;



/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context {
    using EnumerableSet for EnumerableSet.AddressSet;
    using Address for address;

    struct RoleData {
        EnumerableSet.AddressSet members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view returns (bool) {
        return _roles[role].members.contains(account);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view returns (uint256) {
        return _roles[role].members.length();
    }

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
        return _roles[role].members.at(index);
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");

        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual {
        require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");

        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (_roles[role].members.add(account)) {
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (_roles[role].members.remove(account)) {
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.6.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

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

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}


// File contracts/structs/TinyBox.sol


pragma solidity ^0.6.4;

struct TinyBox {
    uint128 randomness;
    uint16 hue;
    uint8 saturation;
    uint8 lightness;
    uint8 shapes;
    uint8 hatching;
    uint8 widthMin;
    uint8 widthMax;
    uint8 heightMin;
    uint8 heightMax;
    uint8 spread;
    uint8 grid;
    uint8 mirroring;
    uint8 bkg; // bkg shade/transparent setting default
    uint8 duration; // animation duration default
    uint8 options; // 8 boolean values packed - 0th is the animate flag
}


// File contracts/libraries/FixidityLib.sol


pragma solidity ^0.6.8;

/**
 * @title FixidityLib
 * @author Gadi Guy, Alberto Cuesta Canada
 * @notice This library provides fixed point arithmetic with protection against
 * overflow. 
 * All operations are done with int256 and the operands must have been created 
 * with any of the newFrom* functions, which shift the comma digits() to the 
 * right and check for limits.
 * When using this library be sure of using maxNewFixed() as the upper limit for
 * creation of fixed point numbers. Use maxFixedMul(), maxFixedDiv() and
 * maxFixedAdd() if you want to be certain that those operations don't 
 * overflow.
 */
    library FixidityLib {

    /**
     * @notice Number of positions that the comma is shifted to the right.
     */
    function digits() public pure returns(uint8) {
        return 24;
    }
    
    /**
     * @notice This is 1 in the fixed point units used in this library.
     * @dev Test fixed1() equals 10^digits()
     * Hardcoded to 24 digits.
     */
    function fixed1() public pure returns(int256) {
        return 1000000000000000000000000;
    }

    /**
     * @notice The amount of decimals lost on each multiplication operand.
     * @dev Test mulPrecision() equals sqrt(fixed1)
     * Hardcoded to 24 digits.
     */
    function mulPrecision() public pure returns(int256) {
        return 1000000000000;
    }

    /**
     * @notice Maximum value that can be represented in an int256
     * @dev Test maxInt256() equals 2^255 -1
     */
    function maxInt256() public pure returns(int256) {
        return 57896044618658097711785492504343953926634992332820282019728792003956564819967;
    }

    /**
     * @notice Minimum value that can be represented in an int256
     * @dev Test minInt256 equals (2^255) * (-1)
     */
    function minInt256() public pure returns(int256) {
        return -57896044618658097711785492504343953926634992332820282019728792003956564819968;
    }

    /**
     * @notice Maximum value that can be converted to fixed point. Optimize for
     * @dev deployment. 
     * Test maxNewFixed() equals maxInt256() / fixed1()
     * Hardcoded to 24 digits.
     */
    function maxNewFixed() public pure returns(int256) {
        return 57896044618658097711785492504343953926634992332820282;
    }

    /**
     * @notice Maximum value that can be converted to fixed point. Optimize for
     * deployment. 
     * @dev Test minNewFixed() equals -(maxInt256()) / fixed1()
     * Hardcoded to 24 digits.
     */
    function minNewFixed() public pure returns(int256) {
        return -57896044618658097711785492504343953926634992332820282;
    }

    /**
     * @notice Maximum value that can be safely used as an addition operator.
     * @dev Test maxFixedAdd() equals maxInt256()-1 / 2
     * Test add(maxFixedAdd(),maxFixedAdd()) equals maxFixedAdd() + maxFixedAdd()
     * Test add(maxFixedAdd()+1,maxFixedAdd()) throws 
     * Test add(-maxFixedAdd(),-maxFixedAdd()) equals -maxFixedAdd() - maxFixedAdd()
     * Test add(-maxFixedAdd(),-maxFixedAdd()-1) throws 
     */
    function maxFixedAdd() public pure returns(int256) {
        return 28948022309329048855892746252171976963317496166410141009864396001978282409983;
    }

    /**
     * @notice Maximum negative value that can be safely in a subtraction.
     * @dev Test maxFixedSub() equals minInt256() / 2
     */
    function maxFixedSub() public pure returns(int256) {
        return -28948022309329048855892746252171976963317496166410141009864396001978282409984;
    }

    /**
     * @notice Maximum value that can be safely used as a multiplication operator.
     * @dev Calculated as sqrt(maxInt256()*fixed1()). 
     * Be careful with your sqrt() implementation. I couldn't find a calculator
     * that would give the exact square root of maxInt256*fixed1 so this number
     * is below the real number by no more than 3*10**28. It is safe to use as
     * a limit for your multiplications, although powers of two of numbers over
     * this value might still work.
     * Test multiply(maxFixedMul(),maxFixedMul()) equals maxFixedMul() * maxFixedMul()
     * Test multiply(maxFixedMul(),maxFixedMul()+1) throws 
     * Test multiply(-maxFixedMul(),maxFixedMul()) equals -maxFixedMul() * maxFixedMul()
     * Test multiply(-maxFixedMul(),maxFixedMul()+1) throws 
     * Hardcoded to 24 digits.
     */
    function maxFixedMul() public pure returns(int256) {
        return 240615969168004498257251713877715648331380787511296;
    }

    /**
     * @notice Maximum value that can be safely used as a dividend.
     * @dev divide(maxFixedDiv,newFixedFraction(1,fixed1())) = maxInt256().
     * Test maxFixedDiv() equals maxInt256()/fixed1()
     * Test divide(maxFixedDiv(),multiply(mulPrecision(),mulPrecision())) = maxFixedDiv()*(10^digits())
     * Test divide(maxFixedDiv()+1,multiply(mulPrecision(),mulPrecision())) throws
     * Hardcoded to 24 digits.
     */
    function maxFixedDiv() public pure returns(int256) {
        return 57896044618658097711785492504343953926634992332820282;
    }

    /**
     * @notice Maximum value that can be safely used as a divisor.
     * @dev Test maxFixedDivisor() equals fixed1()*fixed1() - Or 10**(digits()*2)
     * Test divide(10**(digits()*2 + 1),10**(digits()*2)) = returns 10*fixed1()
     * Test divide(10**(digits()*2 + 1),10**(digits()*2 + 1)) = throws
     * Hardcoded to 24 digits.
     */
    function maxFixedDivisor() public pure returns(int256) {
        return 1000000000000000000000000000000000000000000000000;
    }

    /**
     * @notice Converts an int256 to fixed point units, equivalent to multiplying
     * by 10^digits().
     * @dev Test newFixed(0) returns 0
     * Test newFixed(1) returns fixed1()
     * Test newFixed(maxNewFixed()) returns maxNewFixed() * fixed1()
     * Test newFixed(maxNewFixed()+1) fails
     */
    function newFixed(int256 x)
        public
        pure
        returns (int256)
    {
        assert(x <= maxNewFixed());
        assert(x >= minNewFixed());
        return x * fixed1();
    }

    /**
     * @notice Converts an int256 in the fixed point representation of this 
     * library to a non decimal. All decimal digits will be truncated.
     */
    function fromFixed(int256 x)
        public
        pure
        returns (int256)
    {
        return x / fixed1();
    }

    /**
     * @notice Converts an int256 which is already in some fixed point 
     * representation to a different fixed precision representation.
     * Both the origin and destination precisions must be 38 or less digits.
     * Origin values with a precision higher than the destination precision
     * will be truncated accordingly.
     * @dev 
     * Test convertFixed(1,0,0) returns 1;
     * Test convertFixed(1,1,1) returns 1;
     * Test convertFixed(1,1,0) returns 0;
     * Test convertFixed(1,0,1) returns 10;
     * Test convertFixed(10,1,0) returns 1;
     * Test convertFixed(10,0,1) returns 100;
     * Test convertFixed(100,1,0) returns 10;
     * Test convertFixed(100,0,1) returns 1000;
     * Test convertFixed(1000,2,0) returns 10;
     * Test convertFixed(1000,0,2) returns 100000;
     * Test convertFixed(1000,2,1) returns 100;
     * Test convertFixed(1000,1,2) returns 10000;
     * Test convertFixed(maxInt256,1,0) returns maxInt256/10;
     * Test convertFixed(maxInt256,0,1) throws
     * Test convertFixed(maxInt256,38,0) returns maxInt256/(10**38);
     * Test convertFixed(1,0,38) returns 10**38;
     * Test convertFixed(maxInt256,39,0) throws
     * Test convertFixed(1,0,39) throws
     */
    function convertFixed(int256 x, uint8 _originDigits, uint8 _destinationDigits)
        public
        pure
        returns (int256)
    {
        assert(_originDigits <= 38 && _destinationDigits <= 38);
        
        uint8 decimalDifference;
        if ( _originDigits > _destinationDigits ){
            decimalDifference = _originDigits - _destinationDigits;
            return x/(uint128(10)**uint128(decimalDifference));
        }
        else if ( _originDigits < _destinationDigits ){
            decimalDifference = _destinationDigits - _originDigits;
            // Cast uint8 -> uint128 is safe
            // Exponentiation is safe:
            //     _originDigits and _destinationDigits limited to 38 or less
            //     decimalDifference = abs(_destinationDigits - _originDigits)
            //     decimalDifference < 38
            //     10**38 < 2**128-1
            assert(x <= maxInt256()/uint128(10)**uint128(decimalDifference));
            assert(x >= minInt256()/uint128(10)**uint128(decimalDifference));
            return x*(uint128(10)**uint128(decimalDifference));
        }
        // _originDigits == digits()) 
        return x;
    }

    /**
     * @notice Converts an int256 which is already in some fixed point 
     * representation to that of this library. The _originDigits parameter is the
     * precision of x. Values with a precision higher than FixidityLib.digits()
     * will be truncated accordingly.
     */
    function newFixed(int256 x, uint8 _originDigits)
        public
        pure
        returns (int256)
    {
        return convertFixed(x, _originDigits, digits());
    }

    /**
     * @notice Converts an int256 in the fixed point representation of this 
     * library to a different representation. The _destinationDigits parameter is the
     * precision of the output x. Values with a precision below than 
     * FixidityLib.digits() will be truncated accordingly.
     */
    function fromFixed(int256 x, uint8 _destinationDigits)
        public
        pure
        returns (int256)
    {
        return convertFixed(x, digits(), _destinationDigits);
    }

    /**
     * @notice Converts two int256 representing a fraction to fixed point units,
     * equivalent to multiplying dividend and divisor by 10^digits().
     * @dev 
     * Test newFixedFraction(maxFixedDiv()+1,1) fails
     * Test newFixedFraction(1,maxFixedDiv()+1) fails
     * Test newFixedFraction(1,0) fails     
     * Test newFixedFraction(0,1) returns 0
     * Test newFixedFraction(1,1) returns fixed1()
     * Test newFixedFraction(maxFixedDiv(),1) returns maxFixedDiv()*fixed1()
     * Test newFixedFraction(1,fixed1()) returns 1
     * Test newFixedFraction(1,fixed1()-1) returns 0
     */
    function newFixedFraction(
        int256 numerator, 
        int256 denominator
        )
        public
        pure
        returns (int256)
    {
        assert(numerator <= maxNewFixed());
        assert(denominator <= maxNewFixed());
        assert(denominator != 0);
        int256 convertedNumerator = newFixed(numerator);
        int256 convertedDenominator = newFixed(denominator);
        return divide(convertedNumerator, convertedDenominator);
    }

    /**
     * @notice Returns the integer part of a fixed point number.
     * @dev 
     * Test integer(0) returns 0
     * Test integer(fixed1()) returns fixed1()
     * Test integer(newFixed(maxNewFixed())) returns maxNewFixed()*fixed1()
     * Test integer(-fixed1()) returns -fixed1()
     * Test integer(newFixed(-maxNewFixed())) returns -maxNewFixed()*fixed1()
     */
    function integer(int256 x) public pure returns (int256) {
        return (x / fixed1()) * fixed1(); // Can't overflow
    }

    /**
     * @notice Returns the fractional part of a fixed point number. 
     * In the case of a negative number the fractional is also negative.
     * @dev 
     * Test fractional(0) returns 0
     * Test fractional(fixed1()) returns 0
     * Test fractional(fixed1()-1) returns 10^24-1
     * Test fractional(-fixed1()) returns 0
     * Test fractional(-fixed1()+1) returns -10^24-1
     */
    function fractional(int256 x) public pure returns (int256) {
        return x - (x / fixed1()) * fixed1(); // Can't overflow
    }

    /**
     * @notice Converts to positive if negative.
     * Due to int256 having one more negative number than positive numbers 
     * abs(minInt256) reverts.
     * @dev 
     * Test abs(0) returns 0
     * Test abs(fixed1()) returns -fixed1()
     * Test abs(-fixed1()) returns fixed1()
     * Test abs(newFixed(maxNewFixed())) returns maxNewFixed()*fixed1()
     * Test abs(newFixed(minNewFixed())) returns -minNewFixed()*fixed1()
     */
    function abs(int256 x) public pure returns (int256) {
        if (x >= 0) {
            return x;
        } else {
            int256 result = -x;
            assert (result > 0);
            return result;
        }
    }

    /**
     * @notice x+y. If any operator is higher than maxFixedAdd() it 
     * might overflow.
     * In solidity maxInt256 + 1 = minInt256 and viceversa.
     * @dev 
     * Test add(maxFixedAdd(),maxFixedAdd()) returns maxInt256()-1
     * Test add(maxFixedAdd()+1,maxFixedAdd()+1) fails
     * Test add(-maxFixedSub(),-maxFixedSub()) returns minInt256()
     * Test add(-maxFixedSub()-1,-maxFixedSub()-1) fails
     * Test add(maxInt256(),maxInt256()) fails
     * Test add(minInt256(),minInt256()) fails
     */
    function add(int256 x, int256 y) public pure returns (int256) {
        int256 z = x + y;
        if (x > 0 && y > 0) assert(z > x && z > y);
        if (x < 0 && y < 0) assert(z < x && z < y);
        return z;
    }

    /**
     * @notice x-y. You can use add(x,-y) instead. 
     * @dev Tests covered by add(x,y)
     */
    function subtract(int256 x, int256 y) public pure returns (int256) {
        return add(x,-y);
    }

    /**
     * @notice x*y. If any of the operators is higher than maxFixedMul() it 
     * might overflow.
     * @dev 
     * Test multiply(0,0) returns 0
     * Test multiply(maxFixedMul(),0) returns 0
     * Test multiply(0,maxFixedMul()) returns 0
     * Test multiply(maxFixedMul(),fixed1()) returns maxFixedMul()
     * Test multiply(fixed1(),maxFixedMul()) returns maxFixedMul()
     * Test all combinations of (2,-2), (2, 2.5), (2, -2.5) and (0.5, -0.5)
     * Test multiply(fixed1()/mulPrecision(),fixed1()*mulPrecision())
     * Test multiply(maxFixedMul()-1,maxFixedMul()) equals multiply(maxFixedMul(),maxFixedMul()-1)
     * Test multiply(maxFixedMul(),maxFixedMul()) returns maxInt256() // Probably not to the last digits
     * Test multiply(maxFixedMul()+1,maxFixedMul()) fails
     * Test multiply(maxFixedMul(),maxFixedMul()+1) fails
     */
    function multiply(int256 x, int256 y) public pure returns (int256) {
        if (x == 0 || y == 0) return 0;
        if (y == fixed1()) return x;
        if (x == fixed1()) return y;

        // Separate into integer and fractional parts
        // x = x1 + x2, y = y1 + y2
        int256 x1 = integer(x) / fixed1();
        int256 x2 = fractional(x);
        int256 y1 = integer(y) / fixed1();
        int256 y2 = fractional(y);
        
        // (x1 + x2) * (y1 + y2) = (x1 * y1) + (x1 * y2) + (x2 * y1) + (x2 * y2)
        int256 x1y1 = x1 * y1;
        if (x1 != 0) assert(x1y1 / x1 == y1); // Overflow x1y1
        
        // x1y1 needs to be multiplied back by fixed1
        // solium-disable-next-line mixedcase
        int256 fixed_x1y1 = x1y1 * fixed1();
        if (x1y1 != 0) assert(fixed_x1y1 / x1y1 == fixed1()); // Overflow x1y1 * fixed1
        x1y1 = fixed_x1y1;

        int256 x2y1 = x2 * y1;
        if (x2 != 0) assert(x2y1 / x2 == y1); // Overflow x2y1

        int256 x1y2 = x1 * y2;
        if (x1 != 0) assert(x1y2 / x1 == y2); // Overflow x1y2

        x2 = x2 / mulPrecision();
        y2 = y2 / mulPrecision();
        int256 x2y2 = x2 * y2;
        if (x2 != 0) assert(x2y2 / x2 == y2); // Overflow x2y2

        // result = fixed1() * x1 * y1 + x1 * y2 + x2 * y1 + x2 * y2 / fixed1();
        int256 result = x1y1;
        result = add(result, x2y1); // Add checks for overflow
        result = add(result, x1y2); // Add checks for overflow
        result = add(result, x2y2); // Add checks for overflow
        return result;
    }
    
    /**
     * @notice 1/x
     * @dev 
     * Test reciprocal(0) fails
     * Test reciprocal(fixed1()) returns fixed1()
     * Test reciprocal(fixed1()*fixed1()) returns 1 // Testing how the fractional is truncated
     * Test reciprocal(2*fixed1()*fixed1()) returns 0 // Testing how the fractional is truncated
     */
    function reciprocal(int256 x) public pure returns (int256) {
        assert(x != 0);
        return (fixed1()*fixed1()) / x; // Can't overflow
    }

    /**
     * @notice x/y. If the dividend is higher than maxFixedDiv() it 
     * might overflow. You can use multiply(x,reciprocal(y)) instead.
     * There is a loss of precision on division for the lower mulPrecision() decimals.
     * @dev 
     * Test divide(fixed1(),0) fails
     * Test divide(maxFixedDiv(),1) = maxFixedDiv()*(10^digits())
     * Test divide(maxFixedDiv()+1,1) throws
     * Test divide(maxFixedDiv(),maxFixedDiv()) returns fixed1()
     */
    function divide(int256 x, int256 y) public pure returns (int256) {
        if (y == fixed1()) return x;
        assert(y != 0);
        assert(y <= maxFixedDivisor());
        return multiply(x, reciprocal(y));
    }
}


// File contracts/libraries/Utils.sol


pragma solidity ^0.6.4;
library Utils {
    using SignedSafeMath for int256;
    using Strings for *;

    function stringToUint(string memory s)
        internal
        pure
        returns (uint256 result)
    {
        bytes memory b = bytes(s);
        uint256 i;
        result = 0;
        for (i = 0; i < b.length; i++) {
            uint256 c = uint256(uint8(b[i]));
            if (c >= 48 && c <= 57) {
                result = result * 10 + (c - 48);
            }
        }
    }

    // special toString for signed ints
    function toString(int256 val) public pure returns (string memory out) {
        out = (val < 0) ? 
            string(abi.encodePacked("-", uint256(val.mul(-1)).toString())) :
            uint256(val).toString();
    }

    function zeroPad(int256 value, uint256 places) internal pure returns (string memory out) {
        out = toString(value);
        for (uint i=(places-1); i>0; i--)
            if (value < int256(10**i))
                out = string(abi.encodePacked("0", out));
    }
}


// File contracts/libraries/Random.sol


pragma solidity ^0.6.4;
library Random {
    using SafeMath for uint256;
    using SignedSafeMath for int256;

    /**
     * Initialize the pool with the entropy of the blockhashes of the num of blocks starting from 0
     * The argument "seed" allows you to select a different sequence of random numbers for the same block range.
     */
    function init(
        uint256 seed
    ) internal view returns (bytes32[] memory) {
        uint256 blocks = 2;
        bytes32[] memory pool = new bytes32[](3);
        bytes32 salt = keccak256(abi.encodePacked(uint256(0), seed));
        for (uint256 i = 0; i < blocks; i++) {
            // Add some salt to each blockhash
            pool[i + 1] = keccak256(
                abi.encodePacked(blockhash(i), salt)
            );
        }
        return pool;
    }

    /**
     * Advances to the next 256-bit random number in the pool of hash chains.
     */
    function next(bytes32[] memory pool) internal pure returns (uint256) {
        require(pool.length > 1, "Random.next: invalid pool");
        uint256 roundRobinIdx = (uint256(pool[0]) % (pool.length - 1)) + 1;
        bytes32 hash = keccak256(abi.encodePacked(pool[roundRobinIdx]));
        pool[0] = bytes32(uint256(pool[0]) + 1);
        pool[roundRobinIdx] = hash;
        return uint256(hash);
    }

    /**
     * Produces random integer values, uniformly distributed on the closed interval [a, b]
     */
    function uniform(
        bytes32[] memory pool,
        int256 a,
        int256 b
    ) internal pure returns (int256) {
        require(a <= b, "Random.uniform: invalid interval");
        return int256(next(pool) % uint256(b - a + 1)) + a;
    }

    /**
     * Produces random integer values, with weighted distributions for values in a set
     */
    function weighted(
        bytes32[] memory pool,
        uint8[7] memory thresholds,
        uint16 total
    ) internal pure returns (uint8) {
        int256 p = uniform(pool, 1, total);
        int256 s = 0;
        for (uint8 i=0; i<7; i++) {
            s = s.add(thresholds[i]);
            if (p <= s) return i;
        }
    }

    /**
     * Produces random integer values, with weighted distributions for values in a set
     */
    function weighted(
        bytes32[] memory pool,
        uint8[24] memory thresholds,
        uint16 total
    ) internal pure returns (uint8) {
        int256 p = uniform(pool, 1, total);
        int256 s = 0;
        for (uint8 i=0; i<24; i++) {
            s = s.add(thresholds[i]);
            if (p <= s) return i;
        }
    }
}


// File contracts/TinyBoxesBase.sol


pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
interface RandomizerInt {
    function returnValue() external view returns (bytes32);
}

contract TinyBoxesBase is ERC721, AccessControl  {
    using Counters for Counters.Counter;
    using Random for bytes32[];

    Counters.Counter public _tokenIds;
    Counters.Counter public _tokenPromoIds;

    RandomizerInt entropySource;

    // set contract config constants

    address payable skyfly = 0x7A832c86002323a5de3a317b3281Eb88EC3b2C00;
    address payable natealex = 0x63a9dbCe75413036B2B778E670aaBd4493aAF9F3;

    uint256 public constant price = 100000000000000000; // in wei - 0.1 ETH
    uint256 public constant referalPercent = 10;
    uint256 public constant referalNewPercent = 15;
    uint256 UINT_MAX = uint256(-1);
    uint256 MAX_PROMOS = 100;

    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); // define the admin role identifier
    uint16 public constant TOKEN_LIMIT = 2222;
    uint8 public constant ANIMATION_COUNT = 24;
    uint8 public constant SCHEME_COUNT = 11;
    uint8 public constant avgBlockTime = 14; // avg time per block mined in seconds
    uint16 public constant phaseLen = TOKEN_LIMIT / SCHEME_COUNT; // token count per phase
    uint32 public constant phaseCountdownTime = 6 hours; // time to pause between phases
    
    // set dynamic contract config
    bool public paused = true;
    uint256 public blockStart; // next block that minting will start on, countdown end point
    uint256 public phaseCountdown = uint256(phaseCountdownTime / avgBlockTime); // blocks to pause between phases
    string public contractURI = "https://tinybox.shop/TinyBoxes.json";

    // mapping to store all the boxes info
    mapping(uint256 => TinyBox) internal boxes;

    event SettingsChanged(uint8[3] settings);

    /**
     * @dev Contract constructor.
     * @notice Constructor inherits ERC721
     */
    constructor(address entropySourceAddress) public ERC721("TinyBoxes", "[#][#]") {
        _setupRole(ADMIN_ROLE, msg.sender);
        entropySource = RandomizerInt(entropySourceAddress);
    }

    // Require Functions

    /**
     * @notice  only allow acounts of a specified role to call a function
     */
    function onlyRole(bytes32 _role) view internal {
        // Check that the calling account has the required role
        require(hasRole(_role, msg.sender), "DENIED");
    }

    /**
     * @notice check if tokens are sold out
     */
    function notSoldOut() view internal {
        require(_tokenIds.current() < TOKEN_LIMIT, "SOLD OUT");
    }

    /**
     * @notice check if minting is paused
     */
    function notPaused() view internal {
        require(!paused, "Paused");
    }

    /**
     * @notice check if minting is waiting for a countdown
     */
    function notCountdown() view internal {
        require(block.number >= blockStart, "WAIT");
    }

    // Store Mgmt. Functions

    /**
     * @dev pause minting
     */
    function setPause(bool state) external {
        onlyRole(ADMIN_ROLE);
        paused = state;
    }

    /**
     * @dev set start block for next phase
     */
    function startCountdown(uint256 startBlock) external {
        onlyRole(ADMIN_ROLE);
        require(startBlock > block.number,"Must be future block");
        blockStart = startBlock;
        paused = false;
    }

    // Randomizer functions

    /**
     * @dev set Randomizer
     */
    function setRandom(address rand) external {
        onlyRole(ADMIN_ROLE);
        entropySource = RandomizerInt(rand);
    }

    /**
     * @dev test Randomizer
     */
    function testRandom() external view returns (bytes32) {
        onlyRole(ADMIN_ROLE);
        return entropySource.returnValue();
    }

    /**
     * @dev Call the Randomizer and get some randomness
     */
    function getRandomness(uint256 id, uint256 seed)
        internal view returns (uint128 randomnesss)
    {
        uint256 randomness = uint256(keccak256(abi.encodePacked(
            entropySource.returnValue(),
            id,
            seed
        ))); // mix local and Randomizer entropy for the box randomness
        return uint128(randomness % (2**128)); // cut off half the bits
    }

    // Metadata URI Functions

    /**
     * @dev Set the tokens URI
     * @param _id of a token to update
     * @param _uri for the token
     * @dev Only the admin can call this
     */
    function setTokenURI(uint256 _id, string calldata _uri) external {
        onlyRole(ADMIN_ROLE);
        _setTokenURI(_id, _uri);
    }

    /**
     * @dev Update the base URI field
     * @param _uri base for all tokens 
     * @dev Only the admin can call this
     */
    function setBaseURI(string calldata _uri) external {
        onlyRole(ADMIN_ROLE);
        _setBaseURI(_uri);
    }

    /**
     * @dev Update the contract URI field
     * @dev Only the admin can call this
     */
    function setContractURI(string calldata _uri) external {
        onlyRole(ADMIN_ROLE);
        contractURI = _uri;
    }

    // Utility Functions

    /**
     * @dev check current phase
     */
    function currentPhase() public view returns (uint8) {
        return uint8(_tokenIds.current().div(phaseLen));
    }

    /**
     * @dev calculate the true id for the limited editions
     */
    function trueID(uint256 id) public pure returns (int8) {
        return int8(int256(id));
    }

    /**
     * @dev check if id is one of limited editions
     * @param id of token to check
     */
    function isTokenLE(uint256 id) public view returns (bool) {
        return id > UINT_MAX - MAX_PROMOS;
    }

    // Token Info - Data & Settings

    /**
     * @dev Lookup all token data in one call
     * @param _id for which we want token data
     * @return randomness of the token
     * @return animation of token
     * @return shapes of token
     * @return hatching of token
     * @return size of token
     * @return spacing of token
     * @return mirroring of token
     * @return color for palette root
     * @return contrast of the palette
     * @return shades for palette
     * @return scheme for palette
     */
    function tokenData(uint256 _id)
        external
        view
        returns (
            uint128 randomness,
            uint256 animation,
            uint8 shapes,
            uint8 hatching,
            uint8[4] memory size,
            uint8[2] memory spacing,
            uint8 mirroring,
            uint16[3] memory color,
            uint8 contrast,
            uint8 shades,
            uint8 scheme
        )
    {
        TinyBox memory box = boxes[_id];
        uint8[4] memory parts = calcedParts(box, _id);

        animation = parts[0];
        scheme = parts[1];
        shades = parts[2];
        contrast = parts[3];

        randomness = box.randomness;
        mirroring = box.mirroring;
        shapes = box.shapes;
        hatching = box.hatching;
        color = [box.hue, box.saturation, box.lightness];
        size = [box.widthMin, box.widthMax, box.heightMin, box.heightMax];
        spacing = [box.spread, box.grid];
    }

    /**
     * @dev read the dynamic rendering settings of a token
     * @param id of the token to fetch settings for
     */
    function readSettings(uint256 id) external view returns (uint8 bkg, uint8 duration, uint8 options) {
        TinyBox memory box = boxes[id];
        bkg = box.bkg;
        duration = box.duration;
        options = box.options;
    }

    /**
     * @dev set the dynamic rendering options of a token
     * @param id of the token to update
     * @param settings new settings values
     */
    function changeSettings(uint256 id, uint8[3] calldata settings) external {
        require(msg.sender == ownerOf(id) || msg.sender == getApproved(id), "Insuf. Permissions");
        require(settings[0] <= 101, "Invalid Bkg");
        require(settings[1] > 0, "Invalid Duration");
        boxes[id].bkg = settings[0];
        boxes[id].duration = settings[1];
        boxes[id].options = settings[2];
        emit SettingsChanged(settings);
    }

    /**
     * @dev Calculate the randomized and phased values
     */
    function calcedParts(TinyBox memory box, uint256 id) internal view returns (uint8[4] memory parts)
    {
        if (id < TOKEN_LIMIT) { // Normal Tokens
            bytes32[] memory pool = Random.init(box.randomness);
            uint8[7] memory shadesBins = [4,6,9,6,4,2,1];
            uint8[24] memory animationBins = [
                175, // Snap Spin 90
                200, // Snap Spin 180
                175, // Snap Spin 270
                160, // Snap Spin Tri
                150, // Snap Spin Quad
                140, // Snap Spin Tetra
                95, // Spin
                100, // Slow Mo
                90, // Clockwork
                20, // Spread
                10, // Staggered Spread
                80, // Jitter
                75, // Giggle
                85, // Jolt
                110, // Grow n Shrink
                105, // Squash n Stretch
                50, // Round
                90, // Glide
                70, // Wave
                40, // Fade
                140, // Skew X
                130, // Skew Y
                100, // Stretch
                110 // Jello
            ];
            // Generate Random parts from the tokens randomness
            parts[0] = uint8(pool.weighted(animationBins, 2500)); // animation
            parts[1] = uint8(id.div(phaseLen)); // scheme
            parts[2] = uint8(uint256(pool.weighted(shadesBins, 32)).add(1)); //, shades
            parts[3] = uint8(pool.uniform(0, box.lightness)); // contrast
        } else { // Limited Editions
            // Set the parts directly from packed values in the randomness
            // Anim(5), Scheme(4), Shades(3), Contrast(7) & Vanity Rand String(17xASCII(7))
            parts[0] = uint8(box.randomness / 2**123); // animation
            parts[1] = uint8((box.randomness / 2**119) % 2**4); // scheme
            parts[2] = uint8((box.randomness / 2**116) % 2**3); //, shades
            parts[3] = uint8((box.randomness / 2**109) % 2**7); // contrast
        }
    }

    /**
     * @dev Validate the parameters for the docs
     */
    function validateParams(uint8 shapes, uint8 hatching, uint16[3] memory color, uint8[4] memory size, uint8[2] memory position, bool exclusive) public pure {
        require(shapes > 0 && shapes < 31, "invalid shape count");
        require(hatching <= shapes, "invalid hatching");
        require(color[2] <= 360, "invalid color");
        require(color[1] <= 100, "invalid saturation");
        if (!exclusive) require(color[1] >= 20, "invalid saturation");
        require(color[2] <= 100, "invalid lightness");
        require(size[0] <= size[1], "invalid width range");
        require(size[2] <= size[3], "invalid height range");
        require(position[0] <= 100, "invalid spread");
    }
}


// File contracts/TinyBoxesStore.sol


pragma solidity ^0.6.8;

contract TinyBoxesStore is TinyBoxesBase {
    using SafeMath for uint256;
    using SignedSafeMath for int256;
    using Utils for *;

    event RedeemedLE(address by, uint256 id);

    /**
     * @dev Contract constructor.
     */
    constructor(address entropySourceAddress)
        public
        TinyBoxesBase(entropySourceAddress)
    {}

    // Payment Functions

    /**
     * @dev receive direct ETH transfers
     * @notice for splitting royalties
     */
    receive() external payable {
        _splitFunds(msg.value); 
    }

    /**
     * @dev withdraw any funds leftover in contract
     */
    function withdraw() external {
        onlyRole(ADMIN_ROLE);
        msg.sender.transfer(address(this).balance);
    }

    /**
     * @dev Split payments
     */
    function _splitFunds(uint256 amount) internal {
        if (amount > 0) {
            uint256 partA = amount.mul(60).div(100);
            skyfly.transfer(partA);
            natealex.transfer(amount.sub(partA));
        }
    }

    /**
     * @dev handle the payment for tokens
     */
    function handlePayment(uint256 referalID, address recipient) internal {
        // check for suficient payment
        require(msg.value >= price, "insuficient payment");
        // give the buyer change
        if (msg.value > price) msg.sender.transfer(msg.value.sub(price));
        // lookup the referer by the referal token id owner
        address payable referer = _exists(referalID) ? payable(ownerOf(referalID)) : tx.origin;
        // give a higher percent for refering a new user
        uint256 percent = (balanceOf(tx.origin) == 0) ? referalNewPercent : referalPercent;
        // referer can't be sender or reciever - no self referals
        uint256 referal = (referer != msg.sender && referer != tx.origin && referer != recipient) ? 
            price.mul(percent).div(100) : 0; 
        // pay referal percentage
        if (referal > 0) referer.transfer(referal);
        // split remaining payment
        _splitFunds(price.sub(referal));
    }

    /**
     * @dev Check if a TinyBox Promo Token is unredeemed
     * @param id of the token to check
     */
    function unredeemed(uint256 id) public view returns (bool) {
        return boxes[id].shapes == 0;
    }

    // Token Creation Functions

    /**
     * @dev Create a new LimitedEdition TinyBox Token
     * @param recipient of the new LE TinyBox token
     */
    function mintLE(address recipient) external {
        onlyRole(ADMIN_ROLE);
        require(_tokenPromoIds.current() < MAX_PROMOS, "NO MORE");
        uint256 id = UINT_MAX - _tokenPromoIds.current();
        _safeMint(recipient, id); // mint the new token to the recipient address
        _tokenPromoIds.increment();
    }

    /**
     * @dev Create a new TinyBox Token
     * @param _seed of token
     * @param shapes count and hatching mod value
     * @param color settings (hue, sat, light, contrast, shades)
     * @param size range for boxes
     * @param spacing grid and spread params
     * @param recipient of the token
     * @return id of the new token
     */
    function create(
        string calldata _seed,
        uint8[2] calldata shapes,
        uint16[3] calldata color,
        uint8[4] calldata size,
        uint8[2] calldata spacing,
        uint8 mirroring,
        address recipient,
        uint256 referalID
    ) external payable returns (uint256) {
        notSoldOut();
        notPaused();
        notCountdown();
        handlePayment(referalID, recipient);
        // check box parameters
        validateParams(shapes[0], shapes[1], color, size, spacing, false);
        // make sure caller is never the 0 address
        require(recipient != address(0), "0x00 Recipient Invalid");
        // check payment and give change
        (referalID, recipient);
        // get next id & increment the counter for the next callhandlePayment
        uint256 id = _tokenIds.current();
        _tokenIds.increment();
        // check if its time to pause for next phase countdown
        if (_tokenIds.current().mod(phaseLen) == 0)
            blockStart = block.number.add(phaseCountdown.mul(currentPhase()));
        // add block number and new token id to the seed value
        uint256 seed = _seed.stringToUint();
        // request randomness
        uint128 rand = getRandomness(id, seed);
        // create a new box object in storage
        boxes[id] = TinyBox({
            randomness: rand,
            hue: color[0],
            saturation: (rand % 200 == 0) ? uint8(0) : uint8(color[1]), // 0.5% chance of grayscale
            lightness: uint8(color[2]),
            shapes: shapes[0],
            hatching: shapes[1],
            widthMin: size[0],
            widthMax: size[1],
            heightMin: size[2],
            heightMax: size[3],
            spread: spacing[0],
            grid: spacing[1],
            mirroring: mirroring,
            bkg: 0,
            duration: 10,
            options: 1
        });
        _safeMint(recipient, id); // mint the new token to the recipient address
    }

    /**
     * @dev Create a Limited Edition TinyBox Token from a Promo token
     * @param seed for the token
     * @param shapes count and hatching mod value
     * @param color settings (hue, sat, light, contrast, shades)
     * @param size range for boxes
     * @param spacing grid and spread params
     */
    function redeemLE(
        uint128 seed,
        uint8[2] calldata shapes,
        uint16[3] calldata color,
        uint8[4] calldata size,
        uint8[2] calldata spacing,
        uint8 mirroring,
        uint256 id
    ) external {
        notPaused();
        //  check owner is caller
        require(ownerOf(id) == msg.sender, "NOPE");
        // check token is unredeemed
        require(unredeemed(id), "USED");
        // check box parameters are valid
        validateParams(shapes[0], shapes[1], color, size, spacing, true);
        // create a new box object
        boxes[id] = TinyBox({
            randomness: uint128(seed),
            hue: color[0],
            saturation: uint8(color[1]),
            lightness: uint8(color[2]),
            shapes: shapes[0],
            hatching: shapes[1],
            widthMin: size[0],
            widthMax: size[1],
            heightMin: size[2],
            heightMax: size[3],
            spread: spacing[0],
            grid: spacing[1],
            mirroring: mirroring,
            bkg: 0,
            duration: 10,
            options: 1
        });
        emit RedeemedLE(msg.sender, id);
    }
}


// File contracts/TinyBoxes.sol


pragma solidity ^0.6.8;

interface Renderer {
    function perpetualRenderer(
        TinyBox calldata box,
        uint256 id,
        address owner,
        uint8[4] calldata dVals,
        string calldata _slot
    ) external view returns (string memory);
}

contract TinyBoxes is TinyBoxesStore {
    Renderer renderer;

    /**
     * @dev Contract constructor.
     * @notice Constructor inherits from TinyBoxesStore
     */
    constructor(address rand, address _renderer)
        public
        TinyBoxesStore(rand)
    {
        renderer = Renderer(_renderer);
    }

    /**
     * @dev update the Renderer to a new contract
     */
    function updateRenderer(address _renderer) external {
        onlyRole(ADMIN_ROLE);
        renderer = Renderer(_renderer);
    }

    /**
     * @dev Generate the token SVG art
     * @param _id for which we want art
     * @return SVG art of token 
     */
    function tokenArt(uint256 _id)
        external
        view
        returns (string memory)
    {
        TinyBox memory box = boxes[_id];
        return renderer.perpetualRenderer(box, _id, ownerOf(_id), calcedParts(box, _id), "");
    }

    /**
     * @dev Generate the token SVG art with specific options
     * @param _id for which we want art
     * @param bkg for the token
     * @param duration animation duration modifier
     * @param options bits - 0th is the animate switch to turn on or off animation
     * @param slot string for embeding custom additions
     * @return animated SVG art of token
     */
    function tokenArt(uint256 _id, uint8 bkg, uint8 duration, uint8 options, string calldata slot)
        external
        view
        returns (string memory)
    {
        TinyBox memory box = boxes[_id];
        box.bkg = bkg;
        box.options = options;
        box.duration = duration;
        return renderer.perpetualRenderer(box ,_id, ownerOf(_id), calcedParts(box, _id), slot);
    }
    
    /**
     * @dev Generate the token SVG art preview for given parameters
     * @param seed for renderer RNG
     * @param shapes count and hatching mod
     * @param color settings (hue, sat, light, contrast, shades)
     * @param size for shapes
     * @param spacing grid and spread
     * @param traits mirroring, scheme, shades, animation
     * @param settings adjustable render options - bkg, duration, options
     * @param slot string to enter at end of SVG markup
     * @return preview SVG art
     */
    function renderPreview(
        string calldata seed,
        uint16[3] calldata color,
        uint8[2] calldata shapes,
        uint8[4] calldata size,
        uint8[2] calldata spacing,
        uint8 mirroring,
        uint8[3] calldata settings,
        uint8[4] calldata traits,
        string calldata slot
    ) external view returns (string memory) {
        validateParams(shapes[0], shapes[1], color, size, spacing, true);
        TinyBox memory box = TinyBox({
            randomness: uint128(seed.stringToUint()),
            hue: color[0],
            saturation: uint8(color[1]),
            lightness: uint8(color[2]),
            shapes: shapes[0],
            hatching: shapes[1],
            widthMin: size[0],
            widthMax: size[1],
            heightMin: size[2],
            heightMax: size[3],
            spread: spacing[0],
            mirroring: mirroring,
            grid: spacing[1],
            bkg: settings[0],
            duration: settings[1],
            options: settings[2]
        });
        return renderer.perpetualRenderer(box, 0, address(0), traits, slot);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"rand","type":"address"},{"internalType":"address","name":"_renderer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"by","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"RedeemedLE","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8[3]","name":"settings","type":"uint8[3]"}],"name":"SettingsChanged","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":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANIMATION_COUNT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SCHEME_COUNT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_LIMIT","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenIds","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenPromoIds","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"avgBlockTime","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8[3]","name":"settings","type":"uint8[3]"}],"name":"changeSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_seed","type":"string"},{"internalType":"uint8[2]","name":"shapes","type":"uint8[2]"},{"internalType":"uint16[3]","name":"color","type":"uint16[3]"},{"internalType":"uint8[4]","name":"size","type":"uint8[4]"},{"internalType":"uint8[2]","name":"spacing","type":"uint8[2]"},{"internalType":"uint8","name":"mirroring","type":"uint8"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"referalID","type":"uint256"}],"name":"create","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentPhase","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","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":"uint256","name":"id","type":"uint256"}],"name":"isTokenLE","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"mintLE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phaseCountdown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phaseCountdownTime","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phaseLen","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"readSettings","outputs":[{"internalType":"uint8","name":"bkg","type":"uint8"},{"internalType":"uint8","name":"duration","type":"uint8"},{"internalType":"uint8","name":"options","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"seed","type":"uint128"},{"internalType":"uint8[2]","name":"shapes","type":"uint8[2]"},{"internalType":"uint16[3]","name":"color","type":"uint16[3]"},{"internalType":"uint8[4]","name":"size","type":"uint8[4]"},{"internalType":"uint8[2]","name":"spacing","type":"uint8[2]"},{"internalType":"uint8","name":"mirroring","type":"uint8"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"redeemLE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"referalNewPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referalPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"seed","type":"string"},{"internalType":"uint16[3]","name":"color","type":"uint16[3]"},{"internalType":"uint8[2]","name":"shapes","type":"uint8[2]"},{"internalType":"uint8[4]","name":"size","type":"uint8[4]"},{"internalType":"uint8[2]","name":"spacing","type":"uint8[2]"},{"internalType":"uint8","name":"mirroring","type":"uint8"},{"internalType":"uint8[3]","name":"settings","type":"uint8[3]"},{"internalType":"uint8[4]","name":"traits","type":"uint8[4]"},{"internalType":"string","name":"slot","type":"string"}],"name":"renderPreview","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rand","type":"address"}],"name":"setRandom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startBlock","type":"uint256"}],"name":"startCountdown","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":[],"name":"testRandom","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint8","name":"bkg","type":"uint8"},{"internalType":"uint8","name":"duration","type":"uint8"},{"internalType":"uint8","name":"options","type":"uint8"},{"internalType":"string","name":"slot","type":"string"}],"name":"tokenArt","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"tokenArt","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"tokenData","outputs":[{"internalType":"uint128","name":"randomness","type":"uint128"},{"internalType":"uint256","name":"animation","type":"uint256"},{"internalType":"uint8","name":"shapes","type":"uint8"},{"internalType":"uint8","name":"hatching","type":"uint8"},{"internalType":"uint8[4]","name":"size","type":"uint8[4]"},{"internalType":"uint8[2]","name":"spacing","type":"uint8[2]"},{"internalType":"uint8","name":"mirroring","type":"uint8"},{"internalType":"uint16[3]","name":"color","type":"uint16[3]"},{"internalType":"uint8","name":"contrast","type":"uint8"},{"internalType":"uint8","name":"shades","type":"uint8"},{"internalType":"uint8","name":"scheme","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"trueID","outputs":[{"internalType":"int8","name":"","type":"int8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"unredeemed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_renderer","type":"address"}],"name":"updateRenderer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"shapes","type":"uint8"},{"internalType":"uint8","name":"hatching","type":"uint8"},{"internalType":"uint16[3]","name":"color","type":"uint16[3]"},{"internalType":"uint8[4]","name":"size","type":"uint8[4]"},{"internalType":"uint8[2]","name":"position","type":"uint8[2]"},{"internalType":"bool","name":"exclusive","type":"bool"}],"name":"validateParams","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

600e80546001600160a01b0319908116737a832c86002323a5de3a317b3281eb88ec3b2c0017909155600f80549091167363a9dbce75413036b2b778e670aabd4493aaf9f317905560001960105560646011556012805460ff1916600117905561060660145560e060405260236080818152906200648e60a03980516200008f9160159160209091019062000394565b503480156200009d57600080fd5b50604051620064b1380380620064b1833981016040819052620000c09162000436565b81806040518060400160405280600981526020016854696e79426f78657360b81b815250604051806040016040528060068152602001655b235d5b235d60d01b8152506200011b6301ffc9a760e01b620001fe60201b60201c565b81516200013090600690602085019062000394565b5080516200014690600790602084019062000394565b50620001626380ac58cd60e01b6001600160e01b03620001fe16565b6200017d635b5e139f60e01b6001600160e01b03620001fe16565b6200019863780e9d6360e01b6001600160e01b03620001fe16565b5050620001c5604051620001ac9062000474565b604051908190039020336001600160e01b036200025916565b600d80546001600160a01b039283166001600160a01b031991821617909155601780549490921693169290921790915550620004da9050565b6001600160e01b03198082161415620002345760405162461bcd60e51b81526004016200022b906200048a565b60405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b6200026e82826001600160e01b036200027216565b5050565b6000828152600a602090815260409091206200029991839062002eaa620002f6821b17901c565b156200026e57620002b26001600160e01b036200031f16565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600062000316836001600160a01b0384166001600160e01b036200032416565b90505b92915050565b335b90565b60006200033b83836001600160e01b036200037c16565b620003735750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000319565b50600062000319565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620003d757805160ff191683800117855562000407565b8280016001018555821562000407579182015b8281111562000407578251825591602001919060010190620003ea565b506200041592915062000419565b5090565b6200032191905b8082111562000415576000815560010162000420565b6000806040838503121562000449578182fd5b82516200045681620004c1565b60208401519092506200046981620004c1565b809150509250929050565b6941444d494e5f524f4c4560b01b8152600a0190565b6020808252601c908201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604082015260600190565b6001600160a01b0381168114620004d757600080fd5b50565b615fa480620004ea6000396000f3fe6080604052600436106103c75760003560e01c80639010d07c116101f2578063bedb86fb1161010d578063e8a3d485116100a0578063f7eaec7d1161006f578063f7eaec7d14610af2578063fbddd14b14610b07578063fc4ea93914610b1c578063fd05dd6a14610b31576103d7565b8063e8a3d48514610a93578063e985e9c514610aa8578063f19e148614610ac8578063f1d77baf14610add576103d7565b8063cf34719b116100dc578063cf34719b14610a13578063d547741f14610a33578063dac1109014610a53578063dbde522214610a73576103d7565b8063bedb86fb14610993578063c87b56dd146109b3578063ca15c873146109d3578063ca9c0bad146109f3576103d7565b8063a22cb46511610185578063b3174fa111610154578063b3174fa114610907578063b4b5b48f1461091c578063b88d4fde14610953578063be610c5914610973576103d7565b8063a22cb46514610892578063a2a87ffb146108b2578063aa46a400146108d2578063b059158c146108e7576103d7565b806395d89b41116101c157806395d89b411461083e57806397baac1e14610853578063a035b1fe14610868578063a217fddf1461087d576103d7565b80639010d07c146107af57806391d14854146107cf578063938e3d7b146107ef578063947e93d91461080f576103d7565b806336568abe116102e25780636352211e1161027557806375b238fc1161024457806375b238fc146107455780637b2feaaa1461075a578063835050961461076f57806387bd15ef1461078f576103d7565b80636352211e146106db5780636c0360eb146106fb57806370a082311461071057806371a0a01614610730576103d7565b80634f6ccce7116102b15780634f6ccce714610664578063524101971461068457806355f804b3146106a65780635c975abb146106c6576103d7565b806336568abe146105ef5780633c564cab1461060f5780633ccfd60b1461062f57806342842e0e14610644576103d7565b80631237c4181161035a57806323b872dd1161032957806323b872dd1461056f578063248a9ca31461058f5780632f2ff15d146105af5780632f745c59146105cf576103d7565b80631237c418146104fa578063162094c41461051a57806318160ddd1461053a5780631dd687821461054f576103d7565b806306fdde031161039657806306fdde0314610476578063081812fc14610498578063095ea7b3146104c55780630e1b9b0e146104e5576103d7565b806301ffc9a7146103dc578063031bd4c4146104125780630431e40514610434578063055ad42e14610454576103d7565b366103d7576103d534610b5e565b005b600080fd5b3480156103e857600080fd5b506103fc6103f736600461497e565b610c11565b6040516104099190615215565b60405180910390f35b34801561041e57600080fd5b50610427610c34565b6040516104099190615e09565b34801561044057600080fd5b506103fc61044f3660046148fe565b610c3a565b34801561046057600080fd5b50610469610c45565b6040516104099190615e29565b34801561048257600080fd5b5061048b610c5c565b604051610409919061522e565b3480156104a457600080fd5b506104b86104b33660046148fe565b610cf2565b6040516104099190615178565b3480156104d157600080fd5b506103d56104e03660046148b4565b610d3e565b3480156104f157600080fd5b50610469610dd1565b61050d610508366004614ae7565b610dd6565b6040516104099190615098565b34801561052657600080fd5b506103d5610535366004614cf2565b611345565b34801561054657600080fd5b5061050d6113a1565b34801561055b57600080fd5b5061048b61056a366004614d3c565b6113ad565b34801561057b57600080fd5b506103d561058a3660046147a0565b61155b565b34801561059b57600080fd5b5061050d6105aa3660046148fe565b611593565b3480156105bb57600080fd5b506103d56105ca36600461492e565b6115a8565b3480156105db57600080fd5b5061050d6105ea3660046148b4565b6115f0565b3480156105fb57600080fd5b506103d561060a36600461492e565b611621565b34801561061b57600080fd5b506103d561062a366004614ccf565b611663565b34801561063b57600080fd5b506103d561181b565b34801561065057600080fd5b506103d561065f3660046147a0565b611856565b34801561067057600080fd5b5061050d61067f3660046148fe565b611871565b34801561069057600080fd5b5061069961188d565b6040516104099190615e18565b3480156106b257600080fd5b506103d56106c13660046149b6565b611893565b3480156106d257600080fd5b506103fc6118e1565b3480156106e757600080fd5b506104b86106f63660046148fe565b6118ea565b34801561070757600080fd5b5061048b611918565b34801561071c57600080fd5b5061050d61072b366004614751565b611979565b34801561073c57600080fd5b506104696119c2565b34801561075157600080fd5b5061050d6119c7565b34801561076657600080fd5b5061050d6119de565b34801561077b57600080fd5b506103fc61078a3660046148fe565b6119e4565b34801561079b57600080fd5b506103d56107aa3660046148fe565b611a01565b3480156107bb57600080fd5b506104b86107ca36600461495d565b611a3e565b3480156107db57600080fd5b506103fc6107ea36600461492e565b611a5c565b3480156107fb57600080fd5b506103d561080a3660046149b6565b611a7a565b34801561081b57600080fd5b5061082f61082a3660046148fe565b611a95565b60405161040993929190615e37565b34801561084a57600080fd5b5061048b611bc1565b34801561085f57600080fd5b5061050d611c22565b34801561087457600080fd5b5061050d611c28565b34801561088957600080fd5b5061050d611c34565b34801561089e57600080fd5b506103d56108ad366004614889565b611c39565b3480156108be57600080fd5b5061048b6108cd3660046148fe565b611d07565b3480156108de57600080fd5b5061050d611ebf565b3480156108f357600080fd5b506103d5610902366004614751565b611ec5565b34801561091357600080fd5b50610427611f24565b34801561092857600080fd5b5061093c6109373660046148fe565b611f29565b6040516104099b9a99989796959493929190615d4a565b34801561095f57600080fd5b506103d561096e3660046147e0565b61218a565b34801561097f57600080fd5b506103d561098e366004614751565b6121c9565b34801561099f57600080fd5b506103d56109ae3660046148de565b6121fa565b3480156109bf57600080fd5b5061048b6109ce3660046148fe565b61221c565b3480156109df57600080fd5b5061050d6109ee3660046148fe565b612366565b3480156109ff57600080fd5b506103d5610a0e366004614751565b61237d565b348015610a1f57600080fd5b5061048b610a2e3660046149f6565b6123ae565b348015610a3f57600080fd5b506103d5610a4e36600461492e565b6126af565b348015610a5f57600080fd5b506103d5610a6e366004614c19565b6126e9565b348015610a7f57600080fd5b506103d5610a8e366004614dd7565b612baa565b348015610a9f57600080fd5b5061048b612d42565b348015610ab457600080fd5b506103fc610ac336600461476c565b612dd0565b348015610ad457600080fd5b50610469612dfe565b348015610ae957600080fd5b5061050d612e03565b348015610afe57600080fd5b5061050d612e08565b348015610b1357600080fd5b5061050d612e0d565b348015610b2857600080fd5b5061050d612ea4565b348015610b3d57600080fd5b50610b51610b4c3660046148fe565b610c59565b6040516104099190615220565b8015610c0e576000610b886064610b7c84603c63ffffffff612ebf16565b9063ffffffff612ef916565b600e546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015610bc3573d6000803e3d6000fd5b50600f546001600160a01b03166108fc610be3848463ffffffff612f3b16565b6040518115909202916000818181858888f19350505050158015610c0b573d6000803e3d6000fd5b50505b50565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b6108ae81565b601154601054031090565b6000610c5660ca610b7c600b612f7d565b90505b90565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b820191906000526020600020905b815481529060010190602001808311610ccb57829003601f168201915b5050505050905090565b6000610cfd82612f81565b610d225760405162461bcd60e51b8152600401610d19906157f0565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610d49826118ea565b9050806001600160a01b0316836001600160a01b03161415610d7d5760405162461bcd60e51b8152600401610d19906159a3565b806001600160a01b0316610d8f612f94565b6001600160a01b03161480610dab5750610dab81610ac3612f94565b610dc75760405162461bcd60e51b8152600401610d1990615638565b610c0b8383612f98565b601881565b6000610de0613006565b610de8613032565b610df0613055565b610dfa8284613077565b610e8c610e0a60208a018a614dbc565b610e1a60408b0160208c01614dbc565b604080516060818101909252908b9060039083908390808284376000920191909152505060408051608081810190925291508b9060049083908390808284376000920191909152505060408051808201825291508b90600290839083908082843760009201829052509150612baa9050565b6001600160a01b038316610eb25760405162461bcd60e51b8152600401610d1990615b61565b6000610ebe600b612f7d565b9050610eca600b613202565b610ee560ca610ed9600b612f7d565b9063ffffffff61320b16565b610f1a57610f16610f09610ef7610c45565b6014549060ff1663ffffffff612ebf16565b439063ffffffff61324d16565b6013555b6000610f5b8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327292505050565b90506000610f6983836132cb565b9050604051806102000160405280826001600160801b031681526020018b600060038110610f9357fe5b602002016020810190610fa69190614cad565b61ffff16815260200160c86001600160801b038416066001600160801b0316600014610fe157610fdc60408d0160208e01614cad565b610fe4565b60005b60ff168152602001610ffc60608d0160408e01614cad565b60ff168152602090810190611013908e018e614dbc565b60ff16815260209081019061102e9060408f01908f01614dbc565b60ff168152602090810190611045908c018c614dbc565b60ff1681526020908101906110609060408d01908d01614dbc565b60ff16815260200161107860608c0160408d01614dbc565b60ff16815260200161109060808c0160608d01614dbc565b60ff1681526020908101906110a7908b018b614dbc565b60ff1681526020908101906110c29060408c01908c01614dbc565b60ff1681526020018860ff168152602001600060ff168152602001600a60ff168152602001600160ff168152506016600085815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548161ffff021916908361ffff16021790555060408201518160000160126101000a81548160ff021916908360ff16021790555060608201518160000160136101000a81548160ff021916908360ff16021790555060808201518160000160146101000a81548160ff021916908360ff16021790555060a08201518160000160156101000a81548160ff021916908360ff16021790555060c08201518160000160166101000a81548160ff021916908360ff16021790555060e08201518160000160176101000a81548160ff021916908360ff1602179055506101008201518160000160186101000a81548160ff021916908360ff1602179055506101208201518160000160196101000a81548160ff021916908360ff16021790555061014082015181600001601a6101000a81548160ff021916908360ff16021790555061016082015181600001601b6101000a81548160ff021916908360ff16021790555061018082015181600001601c6101000a81548160ff021916908360ff1602179055506101a082015181600001601d6101000a81548160ff021916908360ff1602179055506101c082015181600001601e6101000a81548160ff021916908360ff1602179055506101e082015181600001601f6101000a81548160ff021916908360ff1602179055509050506113358684613391565b5050509998505050505050505050565b61136160405161135490615162565b60405180910390206133ab565b610c0b8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133d192505050565b6000610c566002613415565b60606113b76143a7565b5060008781526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b90910482166101808201528782166101a08201528582166101e08201529086166101c08201526017546001600160a01b03166301a28c5f828a6114ce816118ea565b6114d8868e613420565b89896040518763ffffffff1660e01b81526004016114fb96959493929190615cb5565b60006040518083038186803b15801561151357600080fd5b505afa158015611527573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154f9190810190614ba3565b98975050505050505050565b61156c611566612f94565b8261363d565b6115885760405162461bcd60e51b8152600401610d19906159e4565b610c0b8383836136c2565b6000908152600a602052604090206002015490565b6000828152600a60205260409020600201546115c6906107ea612f94565b6115e25760405162461bcd60e51b8152600401610d19906152a5565b6115ec82826137e2565b5050565b6001600160a01b0382166000908152600160205260408120611618908363ffffffff61385116565b90505b92915050565b611629612f94565b6001600160a01b0316816001600160a01b0316146116595760405162461bcd60e51b8152600401610d1990615b91565b6115ec828261385d565b61166c826118ea565b6001600160a01b0316336001600160a01b031614806116a4575061168f82610cf2565b6001600160a01b0316336001600160a01b0316145b6116c05760405162461bcd60e51b8152600401610d19906156df565b60656116cf6020830183614dbc565b60ff1611156116f05760405162461bcd60e51b8152600401610d1990615557565b60006117026040830160208401614dbc565b60ff16116117225760405162461bcd60e51b8152600401610d199061594d565b61172f6020820182614dbc565b6000838152601660205260409020805460ff92909216600160e81b0260ff60e81b199092169190911790558060016020020160208101906117709190614dbc565b6000838152601660205260409020805460ff92909216600160f01b0260ff60f01b199092169190911790558060026020020160208101906117b19190614dbc565b60008381526016602052604090819020805460ff93909316600160f81b026001600160f81b0390931692909217909155517fbd960691de2d71e309b1eea54deff5f167fbe6ce9c20bbea1daff6e2d16d202b9061180f9083906151e2565b60405180910390a15050565b61182a60405161135490615162565b60405133904780156108fc02916000818181858888f19350505050158015610c0e573d6000803e3d6000fd5b610c0b8383836040518060200160405280600081525061218a565b60008061188560028463ffffffff6138cc16565b509392505050565b61546081565b6118a260405161135490615162565b6115ec82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138ea92505050565b60125460ff1681565b600061161b82604051806060016040528060298152602001615f46602991396002919063ffffffff6138fd16565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b60006001600160a01b0382166119a15760405162461bcd60e51b8152600401610d1990615695565b6001600160a01b038216600090815260016020526040902061161b90613415565b600b81565b6040516119d390615162565b604051809103902081565b60135481565b600090815260166020526040902054600160a01b900460ff161590565b611a1060405161135490615162565b438111611a2f5760405162461bcd60e51b8152600401610d1990615ad0565b6013556012805460ff19169055565b6000828152600a60205260408120611618908363ffffffff61385116565b6000828152600a60205260408120611618908363ffffffff61390a16565b611a8960405161135490615162565b610c0b6015838361442b565b6000806000611aa26143a7565b5050506000918252506016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a08201819052600160f01b830484166101c08301819052600160f81b9093049093166101e09091018190529192909190565b60078054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b600c5481565b67016345785d8a000081565b600081565b611c41612f94565b6001600160a01b0316826001600160a01b03161415611c725760405162461bcd60e51b8152600401610d19906154df565b8060056000611c7f612f94565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611cc3612f94565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611cfb9190615215565b60405180910390a35050565b6060611d116143a7565b5060008281526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a0820152600160f01b820483166101c0820152600160f81b9091049091166101e08201526017546001600160a01b03166301a28c5f8285611e3b816118ea565b611e458689613420565b6040518563ffffffff1660e01b8152600401611e649493929190615cfe565b60006040518083038186803b158015611e7c57600080fd5b505afa158015611e90573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611eb89190810190614ba3565b9392505050565b600b5481565b611ed460405161135490615162565b601154611ee1600c612f7d565b10611efe5760405162461bcd60e51b8152600401610d1990615332565b6000611f0a600c612f7d565b601054039050611f1a8282613391565b6115ec600c613202565b60ca81565b600080600080611f376144a9565b611f3f6144c7565b6000611f496144e5565b6000806000611f566143a7565b5060008c81526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a0820152600160f01b820483166101c0820152600160f81b9091049091166101e082015261206c6144a9565b612076828f613420565b9050806000602002015160ff169b5080600160200201519250806002602002015193508060036020020151945081600001519c50816101800151965081608001519a508160a0015199506040518060600160405280836020015161ffff1661ffff168152602001836040015160ff1661ffff168152602001836060015160ff1661ffff16815250955060405180608001604052808360c0015160ff1660ff1681526020018360e0015160ff1660ff16815260200183610100015160ff1660ff16815260200183610120015160ff1660ff168152509850604051806040016040528083610140015160ff1660ff16815260200183610160015160ff1660ff168152509750505091939597999b90929496989a50565b61219b612195612f94565b8361363d565b6121b75760405162461bcd60e51b8152600401610d19906159e4565b6121c38484848461391f565b50505050565b6121d860405161135490615162565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b61220960405161135490615162565b6012805460ff1916911515919091179055565b606061222782612f81565b6122435760405162461bcd60e51b8152600401610d19906158fe565b60008281526008602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156122d85780601f106122ad576101008083540402835291602001916122d8565b820191906000526020600020905b8154815290600101906020018083116122bb57829003601f168201915b505060095493945050505060026000196101006001841615020190911604612301579050610c2f565b8051156123335760098160405160200161231c9291906150e1565b604051602081830303815290604052915050610c2f565b600961233e84613952565b60405160200161234f9291906150e1565b604051602081830303815290604052915050919050565b6000818152600a6020526040812061161b90613415565b61238c60405161135490615162565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60606124456123c060208b018b614dbc565b6123d060408c0160208d01614dbc565b604080516060818101909252908e9060039083908390808284376000920191909152505060408051608081810190925291508d9060049083908390808284376000920191909152505060408051808201825291508d90600290839083908082843760009201919091525060019150612baa9050565b61244d6143a7565b6040518061020001604052806124988f8f8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327292505050565b6001600160801b031681526020908101906124b5908e018e614cad565b61ffff1681526020908101906124d19060408f01908f01614cad565b60ff1681526020016124e960608e0160408f01614cad565b60ff168152602090810190612500908d018d614dbc565b60ff16815260209081019061251b9060408e01908e01614dbc565b60ff168152602090810190612532908c018c614dbc565b60ff16815260209081019061254d9060408d01908d01614dbc565b60ff16815260200161256560608c0160408d01614dbc565b60ff16815260200161257d60808c0160608d01614dbc565b60ff168152602090810190612594908b018b614dbc565b60ff1681526020908101906125af9060408c01908c01614dbc565b60ff9081168252891660208201526040018760006020020160208101906125d69190614dbc565b60ff1681526020908101906125f19060408a01908a01614dbc565b60ff1681526020016126096060890160408a01614dbc565b60ff1690526017546040516301a28c5f60e01b81529192506001600160a01b0316906301a28c5f9061264a90849060009081908b908b908b90600401615c38565b60006040518083038186803b15801561266257600080fd5b505afa158015612676573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261269e9190810190614ba3565b9d9c50505050505050505050505050565b6000828152600a60205260409020600201546126cd906107ea612f94565b6116595760405162461bcd60e51b8152600401610d19906155e8565b6126f1613032565b336126fb826118ea565b6001600160a01b0316146127215760405162461bcd60e51b8152600401610d1990615ab2565b61272a816119e4565b6127465760405162461bcd60e51b8152600401610d1990615a94565b6127db6127566020880188614dbc565b6127666040890160208a01614dbc565b6040805160608181019092529089906003908390839080828437600092019190915250506040805160808181019092529150899060049083908390808284376000920191909152505060408051808201825291508990600290839083908082843760009201919091525060019150612baa9050565b6040805161020081019091526001600160801b038816815260208082019061280590880188614cad565b61ffff1681526020908101906128219060408901908901614cad565b60ff1681526020016128396060880160408901614cad565b60ff16815260209081019061285090890189614dbc565b60ff16815260209081019061286b9060408a01908a01614dbc565b60ff16815260209081019061288290870187614dbc565b60ff16815260209081019061289d9060408801908801614dbc565b60ff1681526020016128b56060870160408801614dbc565b60ff1681526020016128cd6080870160608801614dbc565b60ff1681526020908101906128e490860186614dbc565b60ff1681526020908101906128ff9060408701908701614dbc565b60ff1681526020018360ff168152602001600060ff168152602001600a60ff168152602001600160ff168152506016600083815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548161ffff021916908361ffff16021790555060408201518160000160126101000a81548160ff021916908360ff16021790555060608201518160000160136101000a81548160ff021916908360ff16021790555060808201518160000160146101000a81548160ff021916908360ff16021790555060a08201518160000160156101000a81548160ff021916908360ff16021790555060c08201518160000160166101000a81548160ff021916908360ff16021790555060e08201518160000160176101000a81548160ff021916908360ff1602179055506101008201518160000160186101000a81548160ff021916908360ff1602179055506101208201518160000160196101000a81548160ff021916908360ff16021790555061014082015181600001601a6101000a81548160ff021916908360ff16021790555061016082015181600001601b6101000a81548160ff021916908360ff16021790555061018082015181600001601c6101000a81548160ff021916908360ff1602179055506101a082015181600001601d6101000a81548160ff021916908360ff1602179055506101c082015181600001601e6101000a81548160ff021916908360ff1602179055506101e082015181600001601f6101000a81548160ff021916908360ff1602179055509050507fdb892859243d286eeda9a2909a7f8816962b8033f5cd715b816286dff70f9e3c3382604051612b999291906151c9565b60405180910390a150505050505050565b60008660ff16118015612bc05750601f8660ff16105b612bdc5760405162461bcd60e51b8152600401610d1990615888565b8560ff168560ff161115612c025760405162461bcd60e51b8152600401610d1990615471565b610168846002602002015161ffff161115612c2f5760405162461bcd60e51b8152600401610d1990615353565b6064846001602002015161ffff161115612c5b5760405162461bcd60e51b8152600401610d1990615977565b80612c8c576014846001602002015161ffff161015612c8c5760405162461bcd60e51b8152600401610d1990615977565b6064846002602002015161ffff161115612cb85760405162461bcd60e51b8152600401610d1990615be0565b6020830151835160ff91821691161115612ce45760405162461bcd60e51b8152600401610d1990615c0b565b6060830151604084015160ff91821691161115612d135760405162461bcd60e51b8152600401610d1990615afe565b8151606460ff9091161115612d3a5760405162461bcd60e51b8152600401610d1990615a6c565b505050505050565b6015805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612dc85780601f10612d9d57610100808354040283529160200191612dc8565b820191906000526020600020905b815481529060010190602001808311612dab57829003601f168201915b505050505081565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600e81565b600f81565b600a81565b6000612e1e60405161135490615162565b600d60009054906101000a90046001600160a01b03166001600160a01b031663990c8f796040518163ffffffff1660e01b815260040160206040518083038186803b158015612e6c57600080fd5b505afa158015612e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c569190614916565b60145481565b6000611618836001600160a01b038416613a2d565b600082612ece5750600061161b565b82820282848281612edb57fe5b04146116185760405162461bcd60e51b8152600401610d19906157af565b600061161883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a77565b600061161883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613aae565b5490565b600061161b60028363ffffffff613ada16565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612fcd826118ea565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6108ae613013600b612f7d565b106130305760405162461bcd60e51b8152600401610d1990615283565b565b60125460ff16156130305760405162461bcd60e51b8152600401610d19906152f4565b6013544310156130305760405162461bcd60e51b8152600401610d1990615314565b67016345785d8a000034101561309f5760405162461bcd60e51b8152600401610d199061570b565b67016345785d8a00003411156130f557336108fc6130cb3467016345785d8a000063ffffffff612f3b16565b6040518115909202916000818181858888f193505050501580156130f3573d6000803e3d6000fd5b505b600061310083612f81565b61310a5732613113565b613113836118ea565b9050600061312032611979565b1561312c57600a61312f565b600f5b905060006001600160a01b038316331480159061315557506001600160a01b0383163214155b80156131735750836001600160a01b0316836001600160a01b031614155b61317e57600061319b565b61319b6064610b7c67016345785d8a00008563ffffffff612ebf16565b905080156131db576040516001600160a01b0384169082156108fc029083906000818181858888f193505050501580156131d9573d6000803e3d6000fd5b505b6131fb6131f667016345785d8a00008363ffffffff612f3b16565b610b5e565b5050505050565b80546001019055565b600061161883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613ae6565b6000828201838110156116185760405162461bcd60e51b8152600401610d1990615403565b600081815b81518110156132c457600082828151811061328e57fe5b016020015160f81c9050603081108015906132aa575060398111155b156132bb576030810384600a020193505b50600101613277565b5050919050565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663990c8f796040518163ffffffff1660e01b815260040160206040518083038186803b15801561331c57600080fd5b505afa158015613330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133549190614916565b8484604051602001613368939291906150af565b60408051808303601f1901815291905280516020909101206001600160801b0316949350505050565b6115ec828260405180602001604052806000815250613b1a565b6133b58133611a5c565b610c0e5760405162461bcd60e51b8152600401610d199061557c565b6133da82612f81565b6133f65760405162461bcd60e51b8152600401610d199061583c565b60008281526008602090815260409091208251610c0b92840190614503565b600061161b82612f7d565b6134286144a9565b6108ae8210156135e657606061344a84600001516001600160801b0316613b4d565b9050613454614571565b506040805160e081018252600480825260066020830181905260099383019390935260608201929092526080810191909152600260a0820152600160c082015261349c61458f565b50604080516103008101825260af80825260c860208301529181019190915260a06060820181905260966080830152608c908201819052605f60c0830152606460e08301819052605a61010084018190526014610120850152600a6101408501526050610160850152604b61018085015260556101a0850152606e6101c0850181905260696101e086015260326102008601526102208501919091526046610240850152602861026085015261028084019290925260826102a08401526102c08301526102e082015261357883826109c463ffffffff613c0416565b60ff1684526135888560ca612ef9565b60ff166020808601919091526135b7906001906135a89086908690613c75565b60ff169063ffffffff61324d16565b60ff908116604086015260608701516135d591859160009116613cc7565b60ff1660608501525061161b915050565b825160ff6001607b1b6001600160801b03928316041682528351600160771b90821604600f1660208301528351600160741b90821604600716604083015292516001606d1b931692909204607f1660608301525090565b600061364882612f81565b6136645760405162461bcd60e51b8152600401610d199061559c565b600061366f836118ea565b9050806001600160a01b0316846001600160a01b031614806136aa5750836001600160a01b031661369f84610cf2565b6001600160a01b0316145b806136ba57506136ba8185612dd0565b949350505050565b826001600160a01b03166136d5826118ea565b6001600160a01b0316146136fb5760405162461bcd60e51b8152600401610d19906158b5565b6001600160a01b0382166137215760405162461bcd60e51b8152600401610d199061549b565b61372c838383610c0b565b613737600082612f98565b6001600160a01b038316600090815260016020526040902061375f908263ffffffff613d0a16565b506001600160a01b0382166000908152600160205260409020613788908263ffffffff613d1616565b5061379b6002828463ffffffff613d2216565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000828152600a60205260409020613800908263ffffffff612eaa16565b156115ec5761380d612f94565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006116188383613d38565b6000828152600a6020526040902061387b908263ffffffff613d7d16565b156115ec57613888612f94565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008080806138db8686613d92565b909450925050505b9250929050565b80516115ec906009906020840190614503565b60006136ba848484613dee565b6000611618836001600160a01b038416613e4d565b61392a8484846136c2565b61393684848484613e65565b6121c35760405162461bcd60e51b8152600401610d199061537a565b60608161397757506040805180820190915260018152600360fc1b6020820152610c2f565b8160005b811561398f57600101600a8204915061397b565b60608167ffffffffffffffff811180156139a857600080fd5b506040519080825280601f01601f1916602001820160405280156139d3576020820181803683370190505b50859350905060001982015b8315613a2457600a840660300160f81b82828060019003935081518110613a0257fe5b60200101906001600160f81b031916908160001a905350600a840493506139df565b50949350505050565b6000613a398383613e4d565b613a6f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561161b565b50600061161b565b60008183613a985760405162461bcd60e51b8152600401610d19919061522e565b506000838581613aa457fe5b0495945050505050565b60008184841115613ad25760405162461bcd60e51b8152600401610d19919061522e565b505050900390565b60006116188383613e4d565b60008183613b075760405162461bcd60e51b8152600401610d19919061522e565b50828481613b1157fe5b06949350505050565b613b248383613f4a565b613b316000848484613e65565b610c0b5760405162461bcd60e51b8152600401610d199061537a565b60408051600380825260808201909252606091600291839160208201838036833701905050905060008085604051602001613b899291906150a1565b60408051601f198184030181529190528051602090910120905060005b83811015613bfa57804082604051602001613bc29291906150a1565b60405160208183030381529060405280519060200120838260010181518110613be757fe5b6020908102919091010152600101613ba6565b5090949350505050565b600080613c178560018561ffff16613cc7565b90506000805b60188160ff161015613c6b57613c50868260ff1660188110613c3b57fe5b6020020151839060ff1663ffffffff61401a16565b9150818313613c63579250611eb8915050565b600101613c1d565b5050509392505050565b600080613c888560018561ffff16613cc7565b90506000805b60078160ff161015613c6b57613cac868260ff1660078110613c3b57fe5b9150818313613cbf579250611eb8915050565b600101613c8e565b600081831315613ce95760405162461bcd60e51b8152600401610d1990615b2c565b82838303600101613cf986614060565b81613d0057fe5b0601949350505050565b60006116188383614143565b60006116188383613a2d565b60006136ba84846001600160a01b038516614209565b81546000908210613d5b5760405162461bcd60e51b8152600401610d1990615241565b826000018281548110613d6a57fe5b9060005260206000200154905092915050565b6000611618836001600160a01b038416614143565b815460009081908310613db75760405162461bcd60e51b8152600401610d1990615738565b6000846000018481548110613dc857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281613e1e5760405162461bcd60e51b8152600401610d19919061522e565b50846000016001820381548110613e3157fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b6000613e79846001600160a01b03166142a0565b613e85575060016136ba565b6060613f13630a85bd0160e11b613e9a612f94565b888787604051602401613eb0949392919061518c565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615f14603291396001600160a01b038816919063ffffffff6142d916565b9050600081806020019051810190613f2b919061499a565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160a01b038216613f705760405162461bcd60e51b8152600401610d199061577a565b613f7981612f81565b15613f965760405162461bcd60e51b8152600401610d19906153cc565b613fa260008383610c0b565b6001600160a01b0382166000908152600160205260409020613fca908263ffffffff613d1616565b50613fdd6002828463ffffffff613d2216565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082820181831280159061402f5750838112155b80614044575060008312801561404457508381125b6116185760405162461bcd60e51b8152600401610d1990615516565b600060018251116140835760405162461bcd60e51b8152600401610d199061543a565b600060018351038360008151811061409757fe5b602002602001015160001c816140a957fe5b06600101905060008382815181106140bd57fe5b60200260200101516040516020016140d59190615098565b604051602081830303815290604052805190602001209050836000815181106140fa57fe5b602002602001015160001c60010160001b8460008151811061411857fe5b6020026020010181815250508084838151811061413157fe5b60209081029190910101529392505050565b600081815260018301602052604081205480156141ff578354600019808301919081019060009087908390811061417657fe5b906000526020600020015490508087600001848154811061419357fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806141c357fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061161b565b600091505061161b565b60008281526001840160205260408120548061426e575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611eb8565b8285600001600183038154811061428157fe5b9060005260206000209060020201600101819055506000915050611eb8565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906136ba575050151592915050565b60606136ba848460008560606142ee856142a0565b61430a5760405162461bcd60e51b8152600401610d1990615a35565b60006060866001600160a01b0316858760405161432791906150c5565b60006040518083038185875af1925050503d8060008114614364576040519150601f19603f3d011682016040523d82523d6000602084013e614369565b606091505b5091509150811561437d5791506136ba9050565b80511561438d5780518082602001fd5b8360405162461bcd60e51b8152600401610d19919061522e565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061446c5782800160ff19823516178555614499565b82800160010185558215614499579182015b8281111561449957823582559160200191906001019061447e565b506144a59291506145ae565b5090565b60405180608001604052806004906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061454457805160ff1916838001178555614499565b82800160010185558215614499579182015b82811115614499578251825591602001919060010190614556565b6040518060e001604052806007906020820280368337509192915050565b6040518061030001604052806018906020820280368337509192915050565b610c5991905b808211156144a557600081556001016145b4565b80356001600160a01b038116811461161b57600080fd5b806060810183101561161b57600080fd5b806040810183101561161b57600080fd5b600082601f830112614611578081fd5b61461b6040615e54565b905080828460408501111561462f57600080fd5b6000805b600281101561466157823560ff8116811461464c578283fd5b84526020938401939290920191600101614633565b5050505092915050565b806080810183101561161b57600080fd5b600082601f83011261468c578081fd5b6146966080615e54565b90508082846080850111156146aa57600080fd5b60005b60048110156146d5576146c08683614740565b835260209283019291909101906001016146ad565b50505092915050565b8035801515811461161b57600080fd5b60008083601f8401126146ff578182fd5b50813567ffffffffffffffff811115614716578182fd5b6020830191508360208285010111156138e357600080fd5b803561ffff8116811461161b57600080fd5b803560ff8116811461161b57600080fd5b600060208284031215614762578081fd5b61161883836145c8565b6000806040838503121561477e578081fd5b61478884846145c8565b915061479784602085016145c8565b90509250929050565b6000806000606084860312156147b4578081fd5b83356147bf81615ee8565b925060208401356147cf81615ee8565b929592945050506040919091013590565b600080600080608085870312156147f5578081fd5b6147ff86866145c8565b935061480e86602087016145c8565b925060408501359150606085013567ffffffffffffffff811115614830578182fd5b80860187601f820112614841578283fd5b8035915061485661485183615e98565b615e54565b82815288602084840101111561486a578384fd5b8260208301602083013791820160200192909252939692955090935050565b6000806040838503121561489b578182fd5b6148a584846145c8565b915061479784602085016146de565b600080604083850312156148c6578182fd5b6148d084846145c8565b946020939093013593505050565b6000602082840312156148ef578081fd5b81358015158114611618578182fd5b60006020828403121561490f578081fd5b5035919050565b600060208284031215614927578081fd5b5051919050565b60008060408385031215614940578182fd5b82359150602083013561495281615ee8565b809150509250929050565b6000806040838503121561496f578182fd5b50508035926020909101359150565b60006020828403121561498f578081fd5b813561161881615efd565b6000602082840312156149ab578081fd5b815161161881615efd565b600080602083850312156149c8578182fd5b823567ffffffffffffffff8111156149de578283fd5b6149ea858286016146ee565b90969095509350505050565b60008060008060008060008060008060006102a08c8e031215614a17578889fd5b67ffffffffffffffff808d351115614a2d57898afd5b614a3a8e8e358f016146ee565b909c509a50614a4c8e60208f016145df565b9950614a5b8e60808f016145f0565b9850614a6a8e60c08f0161466b565b9750614a7a8e6101408f016145f0565b9650614a8a8e6101808f01614740565b9550614a9a8e6101a08f016145df565b9450614aaa8e6102008f0161466b565b9350806102808e01351115614abd578283fd5b50614acf8d6102808e01358e016146ee565b81935080925050509295989b509295989b9093969950565b60008060008060008060008060006101e08a8c031215614b05578283fd5b893567ffffffffffffffff811115614b1b578384fd5b614b278c828d016146ee565b909a509850614b3b90508b60208c016145f0565b9650614b4a8b60608c016145df565b9550614b598b60c08c0161466b565b9450614b698b6101408c016145f0565b9350614b798b6101808c01614740565b92506101a08a0135614b8a81615ee8565b809250506101c08a013590509295985092959850929598565b600060208284031215614bb4578081fd5b815167ffffffffffffffff811115614bca578182fd5b80830184601f820112614bdb578283fd5b80519150614beb61485183615e98565b828152856020848401011115614bff578384fd5b614c10836020830160208501615ebc565b95945050505050565b60008060008060008060006101c0888a031215614c34578081fd5b87356001600160801b0381168114614c4a578182fd5b9650614c598960208a016145f0565b9550614c688960608a016145df565b9450614c778960c08a0161466b565b9350614c87896101408a016145f0565b9250614c97896101808a01614740565b91506101a0880135905092959891949750929550565b600060208284031215614cbe578081fd5b813561ffff81168114611618578182fd5b60008060808385031215614ce1578182fd5b8235915061479784602085016145df565b600080600060408486031215614d06578081fd5b83359250602084013567ffffffffffffffff811115614d23578182fd5b614d2f868287016146ee565b9497909650939450505050565b60008060008060008060a08789031215614d54578384fd5b86359550614d658860208901614740565b9450614d748860408901614740565b9350614d838860608901614740565b9250608087013567ffffffffffffffff811115614d9e578283fd5b614daa89828a016146ee565b979a9699509497509295939492505050565b600060208284031215614dcd578081fd5b6116188383614740565b6000806000806000806101808789031215614df0578384fd5b614dfa8888614740565b95506020614e0a89828a01614740565b955088605f890112614e1a578485fd5b6003614e2861485182615e7b565b8060408b0160a08c018d811115614e3d57898afd5b895b85811015614e6357614e518f8461472e565b85529386019391860191600101614e3f565b50829950614e718e8261467c565b9850505050505050614e87886101208901614601565b9150614e978861016089016146de565b90509295509295509295565b8060005b60038110156121c357815161ffff16845260209384019390910190600101614ea7565b8060005b60048110156121c357815160ff16845260209384019390910190600101614ece565b60008151808452614f08816020860160208601615ebc565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b614f5182825161507c565b6020810151614f636020840182615089565b506040810151614f766040840182615091565b506060810151614f896060840182615091565b506080810151614f9c6080840182615091565b5060a0810151614faf60a0840182615091565b5060c0810151614fc260c0840182615091565b5060e0810151614fd560e0840182615091565b5061010080820151614fe982850182615091565b505061012080820151614ffe82850182615091565b50506101408082015161501382850182615091565b50506101608082015161502882850182615091565b50506101808082015161503d82850182615091565b50506101a08082015161505282850182615091565b50506101c08082015161506782850182615091565b50506101e0808201516121c382850182615091565b6001600160801b03169052565b61ffff169052565b60ff169052565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b600082516150d7818460208701615ebc565b9190910192915050565b6000808454600180821660008114615100576001811461511757615146565b60ff198316865260028304607f1686019350615146565b600283048886526020808720875b8381101561513e5781548a820152908501908201615125565b505050860193505b5050508351615159818360208801615ebc565b01949350505050565b6941444d494e5f524f4c4560b01b8152600a0190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906151bf90830184614ef0565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b60608101818360005b60038110156146d557602080830160ff6152058286614740565b16855293019291506001016151eb565b901515815260200190565b60009190910b815260200190565b6000602082526116186020830184614ef0565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526008908201526714d3d3110813d55560c21b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526006908201526514185d5cd95960d21b604082015260600190565b60208082526004908201526315d0525560e21b604082015260600190565b6020808252600790820152664e4f204d4f524560c81b604082015260600190565b6020808252600d908201526c34b73b30b634b21031b7b637b960991b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526019908201527f52616e646f6d2e6e6578743a20696e76616c696420706f6f6c00000000000000604082015260600190565b60208082526010908201526f696e76616c6964206861746368696e6760801b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526021908201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600b908201526a496e76616c696420426b6760a81b604082015260600190565b60208082526006908201526511115392515160d21b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b602080825260129082015271496e7375662e205065726d697373696f6e7360701b604082015260600190565b6020808252601390820152721a5b9cdd599a58da595b9d081c185e5b595b9d606a1b604082015260600190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601390820152721a5b9d985b1a59081cda185c194818dbdd5b9d606a1b604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526010908201526f24b73b30b634b210223ab930ba34b7b760811b604082015260600190565b60208082526012908201527134b73b30b634b21039b0ba3ab930ba34b7b760711b604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600e908201526d1a5b9d985b1a59081cdc1c99585960921b604082015260600190565b6020808252600490820152631554d15160e21b604082015260600190565b6020808252600490820152634e4f504560e01b604082015260600190565b6020808252601490820152734d7573742062652066757475726520626c6f636b60601b604082015260600190565b602080825260149082015273696e76616c6964206865696768742072616e676560601b604082015260600190565b6020808252818101527f52616e646f6d2e756e69666f726d3a20696e76616c696420696e74657276616c604082015260600190565b6020808252601690820152750c1e0c0c08149958da5c1a595b9d08125b9d985b1a5960521b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b602080825260119082015270696e76616c6964206c696768746e65737360781b604082015260600190565b602080825260139082015272696e76616c69642077696474682072616e676560681b604082015260600190565b60006102e0615c47838a614f46565b61020083018890526001600160a01b038716610220840152610240830186835b6004811015615c9157602080830160ff615c818286614740565b1685529301929150600101615c67565b505050806102c0840152615ca88184018587614f1c565b9998505050505050505050565b60006102e0615cc4838a614f46565b61020083018890526001600160a01b038716610220840152615cea610240840187614eca565b806102c0840152615ca88184018587614f1c565b60006102e0615d0d8388614f46565b61020083018690526001600160a01b038516610220840152615d33610240840185614eca565b6102c0830181905282015261030001949350505050565b6001600160801b038c16815260208082018c905260ff8b811660408401528a166060830152610220820190615d82608084018b614eca565b61010083018960005b6002811015615daf57615d9f838351615091565b9183019190830190600101615d8b565b50505050615dc1610140830188615091565b615dcf610160830187614ea3565b615ddd6101c0830186615091565b615deb6101e0830185615091565b615df9610200830184615091565b9c9b505050505050505050505050565b61ffff91909116815260200190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b60ff93841681529183166020830152909116604082015260600190565b60405181810167ffffffffffffffff81118282101715615e7357600080fd5b604052919050565b600067ffffffffffffffff821115615e91578081fd5b5060200290565b600067ffffffffffffffff821115615eae578081fd5b50601f01601f191660200190565b60005b83811015615ed7578181015183820152602001615ebf565b838111156121c35750506000910152565b6001600160a01b0381168114610c0e57600080fd5b6001600160e01b031981168114610c0e57600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212204ad04142d3aa89508b5d87d4db43b768b0d158419b2d73738c06487805a963a164736f6c6343000608003368747470733a2f2f74696e79626f782e73686f702f54696e79426f7865732e6a736f6e00000000000000000000000003d37ad26961d79e52c3daea840c0095fb4729a700000000000000000000000068f31617ef6491d4ed2e9463ecff084b1c21fadc

Deployed Bytecode

0x6080604052600436106103c75760003560e01c80639010d07c116101f2578063bedb86fb1161010d578063e8a3d485116100a0578063f7eaec7d1161006f578063f7eaec7d14610af2578063fbddd14b14610b07578063fc4ea93914610b1c578063fd05dd6a14610b31576103d7565b8063e8a3d48514610a93578063e985e9c514610aa8578063f19e148614610ac8578063f1d77baf14610add576103d7565b8063cf34719b116100dc578063cf34719b14610a13578063d547741f14610a33578063dac1109014610a53578063dbde522214610a73576103d7565b8063bedb86fb14610993578063c87b56dd146109b3578063ca15c873146109d3578063ca9c0bad146109f3576103d7565b8063a22cb46511610185578063b3174fa111610154578063b3174fa114610907578063b4b5b48f1461091c578063b88d4fde14610953578063be610c5914610973576103d7565b8063a22cb46514610892578063a2a87ffb146108b2578063aa46a400146108d2578063b059158c146108e7576103d7565b806395d89b41116101c157806395d89b411461083e57806397baac1e14610853578063a035b1fe14610868578063a217fddf1461087d576103d7565b80639010d07c146107af57806391d14854146107cf578063938e3d7b146107ef578063947e93d91461080f576103d7565b806336568abe116102e25780636352211e1161027557806375b238fc1161024457806375b238fc146107455780637b2feaaa1461075a578063835050961461076f57806387bd15ef1461078f576103d7565b80636352211e146106db5780636c0360eb146106fb57806370a082311461071057806371a0a01614610730576103d7565b80634f6ccce7116102b15780634f6ccce714610664578063524101971461068457806355f804b3146106a65780635c975abb146106c6576103d7565b806336568abe146105ef5780633c564cab1461060f5780633ccfd60b1461062f57806342842e0e14610644576103d7565b80631237c4181161035a57806323b872dd1161032957806323b872dd1461056f578063248a9ca31461058f5780632f2ff15d146105af5780632f745c59146105cf576103d7565b80631237c418146104fa578063162094c41461051a57806318160ddd1461053a5780631dd687821461054f576103d7565b806306fdde031161039657806306fdde0314610476578063081812fc14610498578063095ea7b3146104c55780630e1b9b0e146104e5576103d7565b806301ffc9a7146103dc578063031bd4c4146104125780630431e40514610434578063055ad42e14610454576103d7565b366103d7576103d534610b5e565b005b600080fd5b3480156103e857600080fd5b506103fc6103f736600461497e565b610c11565b6040516104099190615215565b60405180910390f35b34801561041e57600080fd5b50610427610c34565b6040516104099190615e09565b34801561044057600080fd5b506103fc61044f3660046148fe565b610c3a565b34801561046057600080fd5b50610469610c45565b6040516104099190615e29565b34801561048257600080fd5b5061048b610c5c565b604051610409919061522e565b3480156104a457600080fd5b506104b86104b33660046148fe565b610cf2565b6040516104099190615178565b3480156104d157600080fd5b506103d56104e03660046148b4565b610d3e565b3480156104f157600080fd5b50610469610dd1565b61050d610508366004614ae7565b610dd6565b6040516104099190615098565b34801561052657600080fd5b506103d5610535366004614cf2565b611345565b34801561054657600080fd5b5061050d6113a1565b34801561055b57600080fd5b5061048b61056a366004614d3c565b6113ad565b34801561057b57600080fd5b506103d561058a3660046147a0565b61155b565b34801561059b57600080fd5b5061050d6105aa3660046148fe565b611593565b3480156105bb57600080fd5b506103d56105ca36600461492e565b6115a8565b3480156105db57600080fd5b5061050d6105ea3660046148b4565b6115f0565b3480156105fb57600080fd5b506103d561060a36600461492e565b611621565b34801561061b57600080fd5b506103d561062a366004614ccf565b611663565b34801561063b57600080fd5b506103d561181b565b34801561065057600080fd5b506103d561065f3660046147a0565b611856565b34801561067057600080fd5b5061050d61067f3660046148fe565b611871565b34801561069057600080fd5b5061069961188d565b6040516104099190615e18565b3480156106b257600080fd5b506103d56106c13660046149b6565b611893565b3480156106d257600080fd5b506103fc6118e1565b3480156106e757600080fd5b506104b86106f63660046148fe565b6118ea565b34801561070757600080fd5b5061048b611918565b34801561071c57600080fd5b5061050d61072b366004614751565b611979565b34801561073c57600080fd5b506104696119c2565b34801561075157600080fd5b5061050d6119c7565b34801561076657600080fd5b5061050d6119de565b34801561077b57600080fd5b506103fc61078a3660046148fe565b6119e4565b34801561079b57600080fd5b506103d56107aa3660046148fe565b611a01565b3480156107bb57600080fd5b506104b86107ca36600461495d565b611a3e565b3480156107db57600080fd5b506103fc6107ea36600461492e565b611a5c565b3480156107fb57600080fd5b506103d561080a3660046149b6565b611a7a565b34801561081b57600080fd5b5061082f61082a3660046148fe565b611a95565b60405161040993929190615e37565b34801561084a57600080fd5b5061048b611bc1565b34801561085f57600080fd5b5061050d611c22565b34801561087457600080fd5b5061050d611c28565b34801561088957600080fd5b5061050d611c34565b34801561089e57600080fd5b506103d56108ad366004614889565b611c39565b3480156108be57600080fd5b5061048b6108cd3660046148fe565b611d07565b3480156108de57600080fd5b5061050d611ebf565b3480156108f357600080fd5b506103d5610902366004614751565b611ec5565b34801561091357600080fd5b50610427611f24565b34801561092857600080fd5b5061093c6109373660046148fe565b611f29565b6040516104099b9a99989796959493929190615d4a565b34801561095f57600080fd5b506103d561096e3660046147e0565b61218a565b34801561097f57600080fd5b506103d561098e366004614751565b6121c9565b34801561099f57600080fd5b506103d56109ae3660046148de565b6121fa565b3480156109bf57600080fd5b5061048b6109ce3660046148fe565b61221c565b3480156109df57600080fd5b5061050d6109ee3660046148fe565b612366565b3480156109ff57600080fd5b506103d5610a0e366004614751565b61237d565b348015610a1f57600080fd5b5061048b610a2e3660046149f6565b6123ae565b348015610a3f57600080fd5b506103d5610a4e36600461492e565b6126af565b348015610a5f57600080fd5b506103d5610a6e366004614c19565b6126e9565b348015610a7f57600080fd5b506103d5610a8e366004614dd7565b612baa565b348015610a9f57600080fd5b5061048b612d42565b348015610ab457600080fd5b506103fc610ac336600461476c565b612dd0565b348015610ad457600080fd5b50610469612dfe565b348015610ae957600080fd5b5061050d612e03565b348015610afe57600080fd5b5061050d612e08565b348015610b1357600080fd5b5061050d612e0d565b348015610b2857600080fd5b5061050d612ea4565b348015610b3d57600080fd5b50610b51610b4c3660046148fe565b610c59565b6040516104099190615220565b8015610c0e576000610b886064610b7c84603c63ffffffff612ebf16565b9063ffffffff612ef916565b600e546040519192506001600160a01b03169082156108fc029083906000818181858888f19350505050158015610bc3573d6000803e3d6000fd5b50600f546001600160a01b03166108fc610be3848463ffffffff612f3b16565b6040518115909202916000818181858888f19350505050158015610c0b573d6000803e3d6000fd5b50505b50565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b6108ae81565b601154601054031090565b6000610c5660ca610b7c600b612f7d565b90505b90565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b820191906000526020600020905b815481529060010190602001808311610ccb57829003601f168201915b5050505050905090565b6000610cfd82612f81565b610d225760405162461bcd60e51b8152600401610d19906157f0565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610d49826118ea565b9050806001600160a01b0316836001600160a01b03161415610d7d5760405162461bcd60e51b8152600401610d19906159a3565b806001600160a01b0316610d8f612f94565b6001600160a01b03161480610dab5750610dab81610ac3612f94565b610dc75760405162461bcd60e51b8152600401610d1990615638565b610c0b8383612f98565b601881565b6000610de0613006565b610de8613032565b610df0613055565b610dfa8284613077565b610e8c610e0a60208a018a614dbc565b610e1a60408b0160208c01614dbc565b604080516060818101909252908b9060039083908390808284376000920191909152505060408051608081810190925291508b9060049083908390808284376000920191909152505060408051808201825291508b90600290839083908082843760009201829052509150612baa9050565b6001600160a01b038316610eb25760405162461bcd60e51b8152600401610d1990615b61565b6000610ebe600b612f7d565b9050610eca600b613202565b610ee560ca610ed9600b612f7d565b9063ffffffff61320b16565b610f1a57610f16610f09610ef7610c45565b6014549060ff1663ffffffff612ebf16565b439063ffffffff61324d16565b6013555b6000610f5b8c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327292505050565b90506000610f6983836132cb565b9050604051806102000160405280826001600160801b031681526020018b600060038110610f9357fe5b602002016020810190610fa69190614cad565b61ffff16815260200160c86001600160801b038416066001600160801b0316600014610fe157610fdc60408d0160208e01614cad565b610fe4565b60005b60ff168152602001610ffc60608d0160408e01614cad565b60ff168152602090810190611013908e018e614dbc565b60ff16815260209081019061102e9060408f01908f01614dbc565b60ff168152602090810190611045908c018c614dbc565b60ff1681526020908101906110609060408d01908d01614dbc565b60ff16815260200161107860608c0160408d01614dbc565b60ff16815260200161109060808c0160608d01614dbc565b60ff1681526020908101906110a7908b018b614dbc565b60ff1681526020908101906110c29060408c01908c01614dbc565b60ff1681526020018860ff168152602001600060ff168152602001600a60ff168152602001600160ff168152506016600085815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548161ffff021916908361ffff16021790555060408201518160000160126101000a81548160ff021916908360ff16021790555060608201518160000160136101000a81548160ff021916908360ff16021790555060808201518160000160146101000a81548160ff021916908360ff16021790555060a08201518160000160156101000a81548160ff021916908360ff16021790555060c08201518160000160166101000a81548160ff021916908360ff16021790555060e08201518160000160176101000a81548160ff021916908360ff1602179055506101008201518160000160186101000a81548160ff021916908360ff1602179055506101208201518160000160196101000a81548160ff021916908360ff16021790555061014082015181600001601a6101000a81548160ff021916908360ff16021790555061016082015181600001601b6101000a81548160ff021916908360ff16021790555061018082015181600001601c6101000a81548160ff021916908360ff1602179055506101a082015181600001601d6101000a81548160ff021916908360ff1602179055506101c082015181600001601e6101000a81548160ff021916908360ff1602179055506101e082015181600001601f6101000a81548160ff021916908360ff1602179055509050506113358684613391565b5050509998505050505050505050565b61136160405161135490615162565b60405180910390206133ab565b610c0b8383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133d192505050565b6000610c566002613415565b60606113b76143a7565b5060008781526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b90910482166101808201528782166101a08201528582166101e08201529086166101c08201526017546001600160a01b03166301a28c5f828a6114ce816118ea565b6114d8868e613420565b89896040518763ffffffff1660e01b81526004016114fb96959493929190615cb5565b60006040518083038186803b15801561151357600080fd5b505afa158015611527573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261154f9190810190614ba3565b98975050505050505050565b61156c611566612f94565b8261363d565b6115885760405162461bcd60e51b8152600401610d19906159e4565b610c0b8383836136c2565b6000908152600a602052604090206002015490565b6000828152600a60205260409020600201546115c6906107ea612f94565b6115e25760405162461bcd60e51b8152600401610d19906152a5565b6115ec82826137e2565b5050565b6001600160a01b0382166000908152600160205260408120611618908363ffffffff61385116565b90505b92915050565b611629612f94565b6001600160a01b0316816001600160a01b0316146116595760405162461bcd60e51b8152600401610d1990615b91565b6115ec828261385d565b61166c826118ea565b6001600160a01b0316336001600160a01b031614806116a4575061168f82610cf2565b6001600160a01b0316336001600160a01b0316145b6116c05760405162461bcd60e51b8152600401610d19906156df565b60656116cf6020830183614dbc565b60ff1611156116f05760405162461bcd60e51b8152600401610d1990615557565b60006117026040830160208401614dbc565b60ff16116117225760405162461bcd60e51b8152600401610d199061594d565b61172f6020820182614dbc565b6000838152601660205260409020805460ff92909216600160e81b0260ff60e81b199092169190911790558060016020020160208101906117709190614dbc565b6000838152601660205260409020805460ff92909216600160f01b0260ff60f01b199092169190911790558060026020020160208101906117b19190614dbc565b60008381526016602052604090819020805460ff93909316600160f81b026001600160f81b0390931692909217909155517fbd960691de2d71e309b1eea54deff5f167fbe6ce9c20bbea1daff6e2d16d202b9061180f9083906151e2565b60405180910390a15050565b61182a60405161135490615162565b60405133904780156108fc02916000818181858888f19350505050158015610c0e573d6000803e3d6000fd5b610c0b8383836040518060200160405280600081525061218a565b60008061188560028463ffffffff6138cc16565b509392505050565b61546081565b6118a260405161135490615162565b6115ec82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138ea92505050565b60125460ff1681565b600061161b82604051806060016040528060298152602001615f46602991396002919063ffffffff6138fd16565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b60006001600160a01b0382166119a15760405162461bcd60e51b8152600401610d1990615695565b6001600160a01b038216600090815260016020526040902061161b90613415565b600b81565b6040516119d390615162565b604051809103902081565b60135481565b600090815260166020526040902054600160a01b900460ff161590565b611a1060405161135490615162565b438111611a2f5760405162461bcd60e51b8152600401610d1990615ad0565b6013556012805460ff19169055565b6000828152600a60205260408120611618908363ffffffff61385116565b6000828152600a60205260408120611618908363ffffffff61390a16565b611a8960405161135490615162565b610c0b6015838361442b565b6000806000611aa26143a7565b5050506000918252506016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a08201819052600160f01b830484166101c08301819052600160f81b9093049093166101e09091018190529192909190565b60078054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ce85780601f10610cbd57610100808354040283529160200191610ce8565b600c5481565b67016345785d8a000081565b600081565b611c41612f94565b6001600160a01b0316826001600160a01b03161415611c725760405162461bcd60e51b8152600401610d19906154df565b8060056000611c7f612f94565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611cc3612f94565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611cfb9190615215565b60405180910390a35050565b6060611d116143a7565b5060008281526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a0820152600160f01b820483166101c0820152600160f81b9091049091166101e08201526017546001600160a01b03166301a28c5f8285611e3b816118ea565b611e458689613420565b6040518563ffffffff1660e01b8152600401611e649493929190615cfe565b60006040518083038186803b158015611e7c57600080fd5b505afa158015611e90573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611eb89190810190614ba3565b9392505050565b600b5481565b611ed460405161135490615162565b601154611ee1600c612f7d565b10611efe5760405162461bcd60e51b8152600401610d1990615332565b6000611f0a600c612f7d565b601054039050611f1a8282613391565b6115ec600c613202565b60ca81565b600080600080611f376144a9565b611f3f6144c7565b6000611f496144e5565b6000806000611f566143a7565b5060008c81526016602090815260409182902082516102008101845290546001600160801b038116825261ffff600160801b8204169282019290925260ff600160901b8304811693820193909352600160981b820483166060820152600160a01b820483166080820152600160a81b8204831660a0820152600160b01b8204831660c0820152600160b81b8204831660e0820152600160c01b82048316610100820152600160c81b82048316610120820152600160d01b82048316610140820152600160d81b82048316610160820152600160e01b82048316610180820152600160e81b820483166101a0820152600160f01b820483166101c0820152600160f81b9091049091166101e082015261206c6144a9565b612076828f613420565b9050806000602002015160ff169b5080600160200201519250806002602002015193508060036020020151945081600001519c50816101800151965081608001519a508160a0015199506040518060600160405280836020015161ffff1661ffff168152602001836040015160ff1661ffff168152602001836060015160ff1661ffff16815250955060405180608001604052808360c0015160ff1660ff1681526020018360e0015160ff1660ff16815260200183610100015160ff1660ff16815260200183610120015160ff1660ff168152509850604051806040016040528083610140015160ff1660ff16815260200183610160015160ff1660ff168152509750505091939597999b90929496989a50565b61219b612195612f94565b8361363d565b6121b75760405162461bcd60e51b8152600401610d19906159e4565b6121c38484848461391f565b50505050565b6121d860405161135490615162565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b61220960405161135490615162565b6012805460ff1916911515919091179055565b606061222782612f81565b6122435760405162461bcd60e51b8152600401610d19906158fe565b60008281526008602090815260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452606093928301828280156122d85780601f106122ad576101008083540402835291602001916122d8565b820191906000526020600020905b8154815290600101906020018083116122bb57829003601f168201915b505060095493945050505060026000196101006001841615020190911604612301579050610c2f565b8051156123335760098160405160200161231c9291906150e1565b604051602081830303815290604052915050610c2f565b600961233e84613952565b60405160200161234f9291906150e1565b604051602081830303815290604052915050919050565b6000818152600a6020526040812061161b90613415565b61238c60405161135490615162565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60606124456123c060208b018b614dbc565b6123d060408c0160208d01614dbc565b604080516060818101909252908e9060039083908390808284376000920191909152505060408051608081810190925291508d9060049083908390808284376000920191909152505060408051808201825291508d90600290839083908082843760009201919091525060019150612baa9050565b61244d6143a7565b6040518061020001604052806124988f8f8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061327292505050565b6001600160801b031681526020908101906124b5908e018e614cad565b61ffff1681526020908101906124d19060408f01908f01614cad565b60ff1681526020016124e960608e0160408f01614cad565b60ff168152602090810190612500908d018d614dbc565b60ff16815260209081019061251b9060408e01908e01614dbc565b60ff168152602090810190612532908c018c614dbc565b60ff16815260209081019061254d9060408d01908d01614dbc565b60ff16815260200161256560608c0160408d01614dbc565b60ff16815260200161257d60808c0160608d01614dbc565b60ff168152602090810190612594908b018b614dbc565b60ff1681526020908101906125af9060408c01908c01614dbc565b60ff9081168252891660208201526040018760006020020160208101906125d69190614dbc565b60ff1681526020908101906125f19060408a01908a01614dbc565b60ff1681526020016126096060890160408a01614dbc565b60ff1690526017546040516301a28c5f60e01b81529192506001600160a01b0316906301a28c5f9061264a90849060009081908b908b908b90600401615c38565b60006040518083038186803b15801561266257600080fd5b505afa158015612676573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261269e9190810190614ba3565b9d9c50505050505050505050505050565b6000828152600a60205260409020600201546126cd906107ea612f94565b6116595760405162461bcd60e51b8152600401610d19906155e8565b6126f1613032565b336126fb826118ea565b6001600160a01b0316146127215760405162461bcd60e51b8152600401610d1990615ab2565b61272a816119e4565b6127465760405162461bcd60e51b8152600401610d1990615a94565b6127db6127566020880188614dbc565b6127666040890160208a01614dbc565b6040805160608181019092529089906003908390839080828437600092019190915250506040805160808181019092529150899060049083908390808284376000920191909152505060408051808201825291508990600290839083908082843760009201919091525060019150612baa9050565b6040805161020081019091526001600160801b038816815260208082019061280590880188614cad565b61ffff1681526020908101906128219060408901908901614cad565b60ff1681526020016128396060880160408901614cad565b60ff16815260209081019061285090890189614dbc565b60ff16815260209081019061286b9060408a01908a01614dbc565b60ff16815260209081019061288290870187614dbc565b60ff16815260209081019061289d9060408801908801614dbc565b60ff1681526020016128b56060870160408801614dbc565b60ff1681526020016128cd6080870160608801614dbc565b60ff1681526020908101906128e490860186614dbc565b60ff1681526020908101906128ff9060408701908701614dbc565b60ff1681526020018360ff168152602001600060ff168152602001600a60ff168152602001600160ff168152506016600083815260200190815260200160002060008201518160000160006101000a8154816001600160801b0302191690836001600160801b0316021790555060208201518160000160106101000a81548161ffff021916908361ffff16021790555060408201518160000160126101000a81548160ff021916908360ff16021790555060608201518160000160136101000a81548160ff021916908360ff16021790555060808201518160000160146101000a81548160ff021916908360ff16021790555060a08201518160000160156101000a81548160ff021916908360ff16021790555060c08201518160000160166101000a81548160ff021916908360ff16021790555060e08201518160000160176101000a81548160ff021916908360ff1602179055506101008201518160000160186101000a81548160ff021916908360ff1602179055506101208201518160000160196101000a81548160ff021916908360ff16021790555061014082015181600001601a6101000a81548160ff021916908360ff16021790555061016082015181600001601b6101000a81548160ff021916908360ff16021790555061018082015181600001601c6101000a81548160ff021916908360ff1602179055506101a082015181600001601d6101000a81548160ff021916908360ff1602179055506101c082015181600001601e6101000a81548160ff021916908360ff1602179055506101e082015181600001601f6101000a81548160ff021916908360ff1602179055509050507fdb892859243d286eeda9a2909a7f8816962b8033f5cd715b816286dff70f9e3c3382604051612b999291906151c9565b60405180910390a150505050505050565b60008660ff16118015612bc05750601f8660ff16105b612bdc5760405162461bcd60e51b8152600401610d1990615888565b8560ff168560ff161115612c025760405162461bcd60e51b8152600401610d1990615471565b610168846002602002015161ffff161115612c2f5760405162461bcd60e51b8152600401610d1990615353565b6064846001602002015161ffff161115612c5b5760405162461bcd60e51b8152600401610d1990615977565b80612c8c576014846001602002015161ffff161015612c8c5760405162461bcd60e51b8152600401610d1990615977565b6064846002602002015161ffff161115612cb85760405162461bcd60e51b8152600401610d1990615be0565b6020830151835160ff91821691161115612ce45760405162461bcd60e51b8152600401610d1990615c0b565b6060830151604084015160ff91821691161115612d135760405162461bcd60e51b8152600401610d1990615afe565b8151606460ff9091161115612d3a5760405162461bcd60e51b8152600401610d1990615a6c565b505050505050565b6015805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015612dc85780601f10612d9d57610100808354040283529160200191612dc8565b820191906000526020600020905b815481529060010190602001808311612dab57829003601f168201915b505050505081565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b600e81565b600f81565b600a81565b6000612e1e60405161135490615162565b600d60009054906101000a90046001600160a01b03166001600160a01b031663990c8f796040518163ffffffff1660e01b815260040160206040518083038186803b158015612e6c57600080fd5b505afa158015612e80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c569190614916565b60145481565b6000611618836001600160a01b038416613a2d565b600082612ece5750600061161b565b82820282848281612edb57fe5b04146116185760405162461bcd60e51b8152600401610d19906157af565b600061161883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613a77565b600061161883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613aae565b5490565b600061161b60028363ffffffff613ada16565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612fcd826118ea565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6108ae613013600b612f7d565b106130305760405162461bcd60e51b8152600401610d1990615283565b565b60125460ff16156130305760405162461bcd60e51b8152600401610d19906152f4565b6013544310156130305760405162461bcd60e51b8152600401610d1990615314565b67016345785d8a000034101561309f5760405162461bcd60e51b8152600401610d199061570b565b67016345785d8a00003411156130f557336108fc6130cb3467016345785d8a000063ffffffff612f3b16565b6040518115909202916000818181858888f193505050501580156130f3573d6000803e3d6000fd5b505b600061310083612f81565b61310a5732613113565b613113836118ea565b9050600061312032611979565b1561312c57600a61312f565b600f5b905060006001600160a01b038316331480159061315557506001600160a01b0383163214155b80156131735750836001600160a01b0316836001600160a01b031614155b61317e57600061319b565b61319b6064610b7c67016345785d8a00008563ffffffff612ebf16565b905080156131db576040516001600160a01b0384169082156108fc029083906000818181858888f193505050501580156131d9573d6000803e3d6000fd5b505b6131fb6131f667016345785d8a00008363ffffffff612f3b16565b610b5e565b5050505050565b80546001019055565b600061161883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613ae6565b6000828201838110156116185760405162461bcd60e51b8152600401610d1990615403565b600081815b81518110156132c457600082828151811061328e57fe5b016020015160f81c9050603081108015906132aa575060398111155b156132bb576030810384600a020193505b50600101613277565b5050919050565b600080600d60009054906101000a90046001600160a01b03166001600160a01b031663990c8f796040518163ffffffff1660e01b815260040160206040518083038186803b15801561331c57600080fd5b505afa158015613330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133549190614916565b8484604051602001613368939291906150af565b60408051808303601f1901815291905280516020909101206001600160801b0316949350505050565b6115ec828260405180602001604052806000815250613b1a565b6133b58133611a5c565b610c0e5760405162461bcd60e51b8152600401610d199061557c565b6133da82612f81565b6133f65760405162461bcd60e51b8152600401610d199061583c565b60008281526008602090815260409091208251610c0b92840190614503565b600061161b82612f7d565b6134286144a9565b6108ae8210156135e657606061344a84600001516001600160801b0316613b4d565b9050613454614571565b506040805160e081018252600480825260066020830181905260099383019390935260608201929092526080810191909152600260a0820152600160c082015261349c61458f565b50604080516103008101825260af80825260c860208301529181019190915260a06060820181905260966080830152608c908201819052605f60c0830152606460e08301819052605a61010084018190526014610120850152600a6101408501526050610160850152604b61018085015260556101a0850152606e6101c0850181905260696101e086015260326102008601526102208501919091526046610240850152602861026085015261028084019290925260826102a08401526102c08301526102e082015261357883826109c463ffffffff613c0416565b60ff1684526135888560ca612ef9565b60ff166020808601919091526135b7906001906135a89086908690613c75565b60ff169063ffffffff61324d16565b60ff908116604086015260608701516135d591859160009116613cc7565b60ff1660608501525061161b915050565b825160ff6001607b1b6001600160801b03928316041682528351600160771b90821604600f1660208301528351600160741b90821604600716604083015292516001606d1b931692909204607f1660608301525090565b600061364882612f81565b6136645760405162461bcd60e51b8152600401610d199061559c565b600061366f836118ea565b9050806001600160a01b0316846001600160a01b031614806136aa5750836001600160a01b031661369f84610cf2565b6001600160a01b0316145b806136ba57506136ba8185612dd0565b949350505050565b826001600160a01b03166136d5826118ea565b6001600160a01b0316146136fb5760405162461bcd60e51b8152600401610d19906158b5565b6001600160a01b0382166137215760405162461bcd60e51b8152600401610d199061549b565b61372c838383610c0b565b613737600082612f98565b6001600160a01b038316600090815260016020526040902061375f908263ffffffff613d0a16565b506001600160a01b0382166000908152600160205260409020613788908263ffffffff613d1616565b5061379b6002828463ffffffff613d2216565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000828152600a60205260409020613800908263ffffffff612eaa16565b156115ec5761380d612f94565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006116188383613d38565b6000828152600a6020526040902061387b908263ffffffff613d7d16565b156115ec57613888612f94565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b60008080806138db8686613d92565b909450925050505b9250929050565b80516115ec906009906020840190614503565b60006136ba848484613dee565b6000611618836001600160a01b038416613e4d565b61392a8484846136c2565b61393684848484613e65565b6121c35760405162461bcd60e51b8152600401610d199061537a565b60608161397757506040805180820190915260018152600360fc1b6020820152610c2f565b8160005b811561398f57600101600a8204915061397b565b60608167ffffffffffffffff811180156139a857600080fd5b506040519080825280601f01601f1916602001820160405280156139d3576020820181803683370190505b50859350905060001982015b8315613a2457600a840660300160f81b82828060019003935081518110613a0257fe5b60200101906001600160f81b031916908160001a905350600a840493506139df565b50949350505050565b6000613a398383613e4d565b613a6f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561161b565b50600061161b565b60008183613a985760405162461bcd60e51b8152600401610d19919061522e565b506000838581613aa457fe5b0495945050505050565b60008184841115613ad25760405162461bcd60e51b8152600401610d19919061522e565b505050900390565b60006116188383613e4d565b60008183613b075760405162461bcd60e51b8152600401610d19919061522e565b50828481613b1157fe5b06949350505050565b613b248383613f4a565b613b316000848484613e65565b610c0b5760405162461bcd60e51b8152600401610d199061537a565b60408051600380825260808201909252606091600291839160208201838036833701905050905060008085604051602001613b899291906150a1565b60408051601f198184030181529190528051602090910120905060005b83811015613bfa57804082604051602001613bc29291906150a1565b60405160208183030381529060405280519060200120838260010181518110613be757fe5b6020908102919091010152600101613ba6565b5090949350505050565b600080613c178560018561ffff16613cc7565b90506000805b60188160ff161015613c6b57613c50868260ff1660188110613c3b57fe5b6020020151839060ff1663ffffffff61401a16565b9150818313613c63579250611eb8915050565b600101613c1d565b5050509392505050565b600080613c888560018561ffff16613cc7565b90506000805b60078160ff161015613c6b57613cac868260ff1660078110613c3b57fe5b9150818313613cbf579250611eb8915050565b600101613c8e565b600081831315613ce95760405162461bcd60e51b8152600401610d1990615b2c565b82838303600101613cf986614060565b81613d0057fe5b0601949350505050565b60006116188383614143565b60006116188383613a2d565b60006136ba84846001600160a01b038516614209565b81546000908210613d5b5760405162461bcd60e51b8152600401610d1990615241565b826000018281548110613d6a57fe5b9060005260206000200154905092915050565b6000611618836001600160a01b038416614143565b815460009081908310613db75760405162461bcd60e51b8152600401610d1990615738565b6000846000018481548110613dc857fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008281526001840160205260408120548281613e1e5760405162461bcd60e51b8152600401610d19919061522e565b50846000016001820381548110613e3157fe5b9060005260206000209060020201600101549150509392505050565b60009081526001919091016020526040902054151590565b6000613e79846001600160a01b03166142a0565b613e85575060016136ba565b6060613f13630a85bd0160e11b613e9a612f94565b888787604051602401613eb0949392919061518c565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001615f14603291396001600160a01b038816919063ffffffff6142d916565b9050600081806020019051810190613f2b919061499a565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b6001600160a01b038216613f705760405162461bcd60e51b8152600401610d199061577a565b613f7981612f81565b15613f965760405162461bcd60e51b8152600401610d19906153cc565b613fa260008383610c0b565b6001600160a01b0382166000908152600160205260409020613fca908263ffffffff613d1616565b50613fdd6002828463ffffffff613d2216565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600082820181831280159061402f5750838112155b80614044575060008312801561404457508381125b6116185760405162461bcd60e51b8152600401610d1990615516565b600060018251116140835760405162461bcd60e51b8152600401610d199061543a565b600060018351038360008151811061409757fe5b602002602001015160001c816140a957fe5b06600101905060008382815181106140bd57fe5b60200260200101516040516020016140d59190615098565b604051602081830303815290604052805190602001209050836000815181106140fa57fe5b602002602001015160001c60010160001b8460008151811061411857fe5b6020026020010181815250508084838151811061413157fe5b60209081029190910101529392505050565b600081815260018301602052604081205480156141ff578354600019808301919081019060009087908390811061417657fe5b906000526020600020015490508087600001848154811061419357fe5b6000918252602080832090910192909255828152600189810190925260409020908401905586548790806141c357fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061161b565b600091505061161b565b60008281526001840160205260408120548061426e575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055611eb8565b8285600001600183038154811061428157fe5b9060005260206000209060020201600101819055506000915050611eb8565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906136ba575050151592915050565b60606136ba848460008560606142ee856142a0565b61430a5760405162461bcd60e51b8152600401610d1990615a35565b60006060866001600160a01b0316858760405161432791906150c5565b60006040518083038185875af1925050503d8060008114614364576040519150601f19603f3d011682016040523d82523d6000602084013e614369565b606091505b5091509150811561437d5791506136ba9050565b80511561438d5780518082602001fd5b8360405162461bcd60e51b8152600401610d19919061522e565b6040805161020081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061446c5782800160ff19823516178555614499565b82800160010185558215614499579182015b8281111561449957823582559160200191906001019061447e565b506144a59291506145ae565b5090565b60405180608001604052806004906020820280368337509192915050565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061454457805160ff1916838001178555614499565b82800160010185558215614499579182015b82811115614499578251825591602001919060010190614556565b6040518060e001604052806007906020820280368337509192915050565b6040518061030001604052806018906020820280368337509192915050565b610c5991905b808211156144a557600081556001016145b4565b80356001600160a01b038116811461161b57600080fd5b806060810183101561161b57600080fd5b806040810183101561161b57600080fd5b600082601f830112614611578081fd5b61461b6040615e54565b905080828460408501111561462f57600080fd5b6000805b600281101561466157823560ff8116811461464c578283fd5b84526020938401939290920191600101614633565b5050505092915050565b806080810183101561161b57600080fd5b600082601f83011261468c578081fd5b6146966080615e54565b90508082846080850111156146aa57600080fd5b60005b60048110156146d5576146c08683614740565b835260209283019291909101906001016146ad565b50505092915050565b8035801515811461161b57600080fd5b60008083601f8401126146ff578182fd5b50813567ffffffffffffffff811115614716578182fd5b6020830191508360208285010111156138e357600080fd5b803561ffff8116811461161b57600080fd5b803560ff8116811461161b57600080fd5b600060208284031215614762578081fd5b61161883836145c8565b6000806040838503121561477e578081fd5b61478884846145c8565b915061479784602085016145c8565b90509250929050565b6000806000606084860312156147b4578081fd5b83356147bf81615ee8565b925060208401356147cf81615ee8565b929592945050506040919091013590565b600080600080608085870312156147f5578081fd5b6147ff86866145c8565b935061480e86602087016145c8565b925060408501359150606085013567ffffffffffffffff811115614830578182fd5b80860187601f820112614841578283fd5b8035915061485661485183615e98565b615e54565b82815288602084840101111561486a578384fd5b8260208301602083013791820160200192909252939692955090935050565b6000806040838503121561489b578182fd5b6148a584846145c8565b915061479784602085016146de565b600080604083850312156148c6578182fd5b6148d084846145c8565b946020939093013593505050565b6000602082840312156148ef578081fd5b81358015158114611618578182fd5b60006020828403121561490f578081fd5b5035919050565b600060208284031215614927578081fd5b5051919050565b60008060408385031215614940578182fd5b82359150602083013561495281615ee8565b809150509250929050565b6000806040838503121561496f578182fd5b50508035926020909101359150565b60006020828403121561498f578081fd5b813561161881615efd565b6000602082840312156149ab578081fd5b815161161881615efd565b600080602083850312156149c8578182fd5b823567ffffffffffffffff8111156149de578283fd5b6149ea858286016146ee565b90969095509350505050565b60008060008060008060008060008060006102a08c8e031215614a17578889fd5b67ffffffffffffffff808d351115614a2d57898afd5b614a3a8e8e358f016146ee565b909c509a50614a4c8e60208f016145df565b9950614a5b8e60808f016145f0565b9850614a6a8e60c08f0161466b565b9750614a7a8e6101408f016145f0565b9650614a8a8e6101808f01614740565b9550614a9a8e6101a08f016145df565b9450614aaa8e6102008f0161466b565b9350806102808e01351115614abd578283fd5b50614acf8d6102808e01358e016146ee565b81935080925050509295989b509295989b9093969950565b60008060008060008060008060006101e08a8c031215614b05578283fd5b893567ffffffffffffffff811115614b1b578384fd5b614b278c828d016146ee565b909a509850614b3b90508b60208c016145f0565b9650614b4a8b60608c016145df565b9550614b598b60c08c0161466b565b9450614b698b6101408c016145f0565b9350614b798b6101808c01614740565b92506101a08a0135614b8a81615ee8565b809250506101c08a013590509295985092959850929598565b600060208284031215614bb4578081fd5b815167ffffffffffffffff811115614bca578182fd5b80830184601f820112614bdb578283fd5b80519150614beb61485183615e98565b828152856020848401011115614bff578384fd5b614c10836020830160208501615ebc565b95945050505050565b60008060008060008060006101c0888a031215614c34578081fd5b87356001600160801b0381168114614c4a578182fd5b9650614c598960208a016145f0565b9550614c688960608a016145df565b9450614c778960c08a0161466b565b9350614c87896101408a016145f0565b9250614c97896101808a01614740565b91506101a0880135905092959891949750929550565b600060208284031215614cbe578081fd5b813561ffff81168114611618578182fd5b60008060808385031215614ce1578182fd5b8235915061479784602085016145df565b600080600060408486031215614d06578081fd5b83359250602084013567ffffffffffffffff811115614d23578182fd5b614d2f868287016146ee565b9497909650939450505050565b60008060008060008060a08789031215614d54578384fd5b86359550614d658860208901614740565b9450614d748860408901614740565b9350614d838860608901614740565b9250608087013567ffffffffffffffff811115614d9e578283fd5b614daa89828a016146ee565b979a9699509497509295939492505050565b600060208284031215614dcd578081fd5b6116188383614740565b6000806000806000806101808789031215614df0578384fd5b614dfa8888614740565b95506020614e0a89828a01614740565b955088605f890112614e1a578485fd5b6003614e2861485182615e7b565b8060408b0160a08c018d811115614e3d57898afd5b895b85811015614e6357614e518f8461472e565b85529386019391860191600101614e3f565b50829950614e718e8261467c565b9850505050505050614e87886101208901614601565b9150614e978861016089016146de565b90509295509295509295565b8060005b60038110156121c357815161ffff16845260209384019390910190600101614ea7565b8060005b60048110156121c357815160ff16845260209384019390910190600101614ece565b60008151808452614f08816020860160208601615ebc565b601f01601f19169290920160200192915050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b614f5182825161507c565b6020810151614f636020840182615089565b506040810151614f766040840182615091565b506060810151614f896060840182615091565b506080810151614f9c6080840182615091565b5060a0810151614faf60a0840182615091565b5060c0810151614fc260c0840182615091565b5060e0810151614fd560e0840182615091565b5061010080820151614fe982850182615091565b505061012080820151614ffe82850182615091565b50506101408082015161501382850182615091565b50506101608082015161502882850182615091565b50506101808082015161503d82850182615091565b50506101a08082015161505282850182615091565b50506101c08082015161506782850182615091565b50506101e0808201516121c382850182615091565b6001600160801b03169052565b61ffff169052565b60ff169052565b90815260200190565b918252602082015260400190565b9283526020830191909152604082015260600190565b600082516150d7818460208701615ebc565b9190910192915050565b6000808454600180821660008114615100576001811461511757615146565b60ff198316865260028304607f1686019350615146565b600283048886526020808720875b8381101561513e5781548a820152908501908201615125565b505050860193505b5050508351615159818360208801615ebc565b01949350505050565b6941444d494e5f524f4c4560b01b8152600a0190565b6001600160a01b0391909116815260200190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906151bf90830184614ef0565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b60608101818360005b60038110156146d557602080830160ff6152058286614740565b16855293019291506001016151eb565b901515815260200190565b60009190910b815260200190565b6000602082526116186020830184614ef0565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b60208082526008908201526714d3d3110813d55560c21b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b60208082526006908201526514185d5cd95960d21b604082015260600190565b60208082526004908201526315d0525560e21b604082015260600190565b6020808252600790820152664e4f204d4f524560c81b604082015260600190565b6020808252600d908201526c34b73b30b634b21031b7b637b960991b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526019908201527f52616e646f6d2e6e6578743a20696e76616c696420706f6f6c00000000000000604082015260600190565b60208082526010908201526f696e76616c6964206861746368696e6760801b604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b60208082526021908201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252600b908201526a496e76616c696420426b6760a81b604082015260600190565b60208082526006908201526511115392515160d21b604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b602080825260129082015271496e7375662e205065726d697373696f6e7360701b604082015260600190565b6020808252601390820152721a5b9cdd599a58da595b9d081c185e5b595b9d606a1b604082015260600190565b60208082526022908201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252602c908201527f4552433732314d657461646174613a2055524920736574206f66206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601390820152721a5b9d985b1a59081cda185c194818dbdd5b9d606a1b604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526010908201526f24b73b30b634b210223ab930ba34b7b760811b604082015260600190565b60208082526012908201527134b73b30b634b21039b0ba3ab930ba34b7b760711b604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252600e908201526d1a5b9d985b1a59081cdc1c99585960921b604082015260600190565b6020808252600490820152631554d15160e21b604082015260600190565b6020808252600490820152634e4f504560e01b604082015260600190565b6020808252601490820152734d7573742062652066757475726520626c6f636b60601b604082015260600190565b602080825260149082015273696e76616c6964206865696768742072616e676560601b604082015260600190565b6020808252818101527f52616e646f6d2e756e69666f726d3a20696e76616c696420696e74657276616c604082015260600190565b6020808252601690820152750c1e0c0c08149958da5c1a595b9d08125b9d985b1a5960521b604082015260600190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b602080825260119082015270696e76616c6964206c696768746e65737360781b604082015260600190565b602080825260139082015272696e76616c69642077696474682072616e676560681b604082015260600190565b60006102e0615c47838a614f46565b61020083018890526001600160a01b038716610220840152610240830186835b6004811015615c9157602080830160ff615c818286614740565b1685529301929150600101615c67565b505050806102c0840152615ca88184018587614f1c565b9998505050505050505050565b60006102e0615cc4838a614f46565b61020083018890526001600160a01b038716610220840152615cea610240840187614eca565b806102c0840152615ca88184018587614f1c565b60006102e0615d0d8388614f46565b61020083018690526001600160a01b038516610220840152615d33610240840185614eca565b6102c0830181905282015261030001949350505050565b6001600160801b038c16815260208082018c905260ff8b811660408401528a166060830152610220820190615d82608084018b614eca565b61010083018960005b6002811015615daf57615d9f838351615091565b9183019190830190600101615d8b565b50505050615dc1610140830188615091565b615dcf610160830187614ea3565b615ddd6101c0830186615091565b615deb6101e0830185615091565b615df9610200830184615091565b9c9b505050505050505050505050565b61ffff91909116815260200190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b60ff93841681529183166020830152909116604082015260600190565b60405181810167ffffffffffffffff81118282101715615e7357600080fd5b604052919050565b600067ffffffffffffffff821115615e91578081fd5b5060200290565b600067ffffffffffffffff821115615eae578081fd5b50601f01601f191660200190565b60005b83811015615ed7578181015183820152602001615ebf565b838111156121c35750506000910152565b6001600160a01b0381168114610c0e57600080fd5b6001600160e01b031981168114610c0e57600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea26469706673582212204ad04142d3aa89508b5d87d4db43b768b0d158419b2d73738c06487805a963a164736f6c63430006080033

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

00000000000000000000000003d37ad26961d79e52c3daea840c0095fb4729a700000000000000000000000068f31617ef6491d4ed2e9463ecff084b1c21fadc

-----Decoded View---------------
Arg [0] : rand (address): 0x03D37AD26961D79E52c3dAEa840C0095Fb4729a7
Arg [1] : _renderer (address): 0x68f31617ef6491D4ed2E9463Ecff084b1C21fADc

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000003d37ad26961d79e52c3daea840c0095fb4729a7
Arg [1] : 00000000000000000000000068f31617ef6491d4ed2e9463ecff084b1c21fadc


Deployed Bytecode Sourcemap

109456:3406:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102921:22;102933:9;102921:11;:22::i;:::-;109456:3406;;12:1:-1;9;2:12;21670:142:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;21670:142:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;92015:41;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92015:41:0;;;:::i;:::-;;;;;;;;96753:110;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;96753:110:0;;;;;;;;:::i;96338:118::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;96338:118:0;;;:::i;:::-;;;;;;;;47410:92;;5:9:-1;2:2;;;27:1;24;17:12;2:2;47410:92:0;;;:::i;:::-;;;;;;;;50097:213;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;50097:213:0;;;;;;;;:::i;:::-;;;;;;;;49641:390;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;49641:390:0;;;;;;;;:::i;92063:42::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92063:42:0;;;:::i;105585:2022::-;;;;;;;;;:::i;:::-;;;;;;;;95613:138;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;95613:138:0;;;;;;;;:::i;49135:203::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;49135:203:0;;;:::i;110774:402::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;110774:402:0;;;;;;;;:::i;50971:305::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;50971:305:0;;;;;;;;:::i;64350:114::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;64350:114:0;;;;;;;;:::i;64726:227::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;64726:227:0;;;;;;;;:::i;48905:154::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;48905:154:0;;;;;;;;:::i;65935:209::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;65935:209:0;;;;;;;;:::i;98942:453::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;98942:453:0;;;;;;;;:::i;103031:121::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;103031:121:0;;;:::i;51347:151::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;51347:151:0;;;;;;;;:::i;49415:164::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;49415:164:0;;;;;;;;:::i;92335:51::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92335:51:0;;;:::i;:::-;;;;;;;;95899:118;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;95899:118:0;;;;;;;;:::i;92467:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92467:25:0;;;:::i;47174:169::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;47174:169:0;;;;;;;;:::i;48732:89::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;48732:89:0;;;:::i;46897:215::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;46897:215:0;;;;;;;;:::i;92112:39::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92112:39:0;;;:::i;91912:60::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91912:60:0;;;:::i;92499:25::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92499:25:0;;;:::i;104612:106::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;104612:106:0;;;;;;;;:::i;94295:219::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;94295:219:0;;;;;;;;:::i;64023:138::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;64023:138:0;;;;;;;;:::i;62984:139::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;62984:139:0;;;;;;;;:::i;96128:123::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;96128:123:0;;;;;;;;:::i;98535:238::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;98535:238:0;;;;;;;;:::i;:::-;;;;;;;;;;47571:96;;5:9:-1;2:2;;;27:1;24;17:12;2:2;47571:96:0;;;:::i;91387:38::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91387:38:0;;;:::i;91662:50::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91662:50:0;;;:::i;61729:49::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;61729:49:0;;;:::i;50382:295::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;50382:295:0;;;;;;;;:::i;110131:246::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;110131:246:0;;;;;;;;:::i;91347:33::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91347:33:0;;;:::i;104887:329::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;104887:329:0;;;;;;;;:::i;92243:60::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92243:60:0;;;:::i;97411:985::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;97411:985:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;51569:285;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;51569:285:0;;;;;;;;:::i;109858:132::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;109858:132:0;;;;;;;;:::i;94122:103::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;94122:103:0;;;;;;;;:::i;47738:755::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;47738:755:0;;;;;;;;:::i;63297:127::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;63297:127:0;;;;;;;;:::i;94599:::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;94599:127:0;;;;;;;;:::i;111716:1143::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;111716:1143:0;;;;;;;;:::i;65198:230::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;65198:230:0;;;;;;;;:::i;107937:1199::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;107937:1199:0;;;;;;;;:::i;101608:704::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;101608:704:0;;;;;;;;:::i;92708:65::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92708:65:0;;;:::i;50748:156::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;50748:156:0;;;;;;;;:::i;92158:39::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92158:39:0;;;:::i;91789:46::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91789:46:0;;;:::i;91739:43::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;91739:43:0;;;:::i;94781:138::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;94781:138:0;;;:::i;92593:74::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92593:74:0;;;:::i;96542:97::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;96542:97:0;;;;;;;;:::i;:::-;;;;;;;;103206:234;103267:10;;103263:170;;103294:13;103310:23;103329:3;103310:14;:6;103321:2;103310:14;:10;:14;:::i;:::-;:18;:23;:18;:23;:::i;:::-;103348:6;;:22;;103294:39;;-1:-1:-1;;;;;;103348:6:0;;:22;;;;;103294:39;;103348:6;:22;:6;:22;103294:39;103348:6;:22;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;103385:8:0;;-1:-1:-1;;;;;103385:8:0;:36;103403:17;:6;103414:5;103403:17;:10;:17;:::i;:::-;103385:36;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;103385:36:0;103263:170;;103206:234;:::o;21670:142::-;-1:-1:-1;;;;;;21771:33:0;;21747:4;21771:33;;;;;;;;;;;;;21670:142;;;;:::o;92015:41::-;92052:4;92015:41;:::o;96753:110::-;96845:10;;96834:8;;:21;-1:-1:-1;96829:26:0;96753:110::o;96338:118::-;96383:5;96414:33;92277:26;96414:19;92149:2;96414:17;:19::i;:33::-;96401:47;;96338:118;;:::o;47410:92::-;47489:5;47482:12;;;;;;;;-1:-1:-1;;47482:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47456:13;;47482:12;;47489:5;;47482:12;;47489:5;47482:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47410:92;:::o;50097:213::-;50165:7;50193:16;50201:7;50193;:16::i;:::-;50185:73;;;;-1:-1:-1;;;50185:73:0;;;;;;;;;;;;;;;;;-1:-1:-1;50278:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;50278:24:0;;50097:213::o;49641:390::-;49722:13;49738:16;49746:7;49738;:16::i;:::-;49722:32;;49779:5;-1:-1:-1;;;;;49773:11:0;:2;-1:-1:-1;;;;;49773:11:0;;;49765:57;;;;-1:-1:-1;;;49765:57:0;;;;;;;;;49859:5;-1:-1:-1;;;;;49843:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;49843:21:0;;:62;;;;49868:37;49885:5;49892:12;:10;:12::i;49868:37::-;49835:154;;;;-1:-1:-1;;;49835:154:0;;;;;;;;;50002:21;50011:2;50015:7;50002:8;:21::i;92063:42::-;92103:2;92063:42;:::o;105585:2022::-;105887:7;105907:12;:10;:12::i;:::-;105930:11;:9;:11::i;:::-;105952:14;:12;:14::i;:::-;105977:35;105991:9;106002;105977:13;:35::i;:::-;106056:65;106071:9;;;;:6;:9;;;106082;;;;;;;;;;106056:65;;;;;;;;;;;106093:5;;106056:65;;;;106093:5;;106056:65;106093:5;106056:65;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;106056:65:0;;;;;;;;;;;-1:-1:-1;106100:4:0;;106056:65;;;;106100:4;;106056:65;106100:4;106056:65;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;106056:65:0;;;;;;;;;-1:-1:-1;106106:7:0;;106056:65;;;;106106:7;;106056:65;106106:7;106056:65;1:33:-1;99:1;81:16;;74:27;;;-1:-1;99:1;-1:-1;106056:14:0;;-1:-1:-1;106056:65:0:i;:::-;-1:-1:-1;;;;;106192:23:0;;106184:58;;;;-1:-1:-1;;;106184:58:0;;;;;;;;;106407:10;106420:19;:9;:17;:19::i;:::-;106407:32;;106450:21;:9;:19;:21::i;:::-;106550:33;92277:26;106550:19;92149:2;106550:17;:19::i;:::-;:23;:33;:23;:33;:::i;:::-;106546:122;;106616:52;106633:34;106652:14;:12;:14::i;:::-;106633;;;:34;;;:18;:34;:::i;:::-;106616:12;;:52;:16;:52;:::i;:::-;106603:10;:65;106546:122;106743:12;106758:20;:5;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;106758:18:0;;-1:-1:-1;;;106758:20:0:i;:::-;106743:35;;106820:12;106835:23;106849:2;106853:4;106835:13;:23::i;:::-;106820:38;;106928:589;;;;;;;;106963:4;-1:-1:-1;;;;;106928:589:0;;;;;106987:5;106993:1;106987:8;;;;;;;;;;;;;;;;;;;;106928:589;;;;;;107030:3;-1:-1:-1;;;;;107023:10:0;;;-1:-1:-1;;;;;107023:15:0;107037:1;107023:15;107022:46;;107059:8;;;;;;;;;;107022:46;;;107048:1;107022:46;106928:589;;;;;;107128:8;;;;;;;;;;106928:589;;;;;;;;;107160:9;;;;:6;:9;;;106928:589;;;;;;;;;107194:9;;;;;;;;;;;106928:589;;;;;;;;;107228:7;;;;:4;:7;;;106928:589;;;;;;;;;107260:7;;;;;;;;;;;106928:589;;;;;;107293:7;;;;;;;;;;106928:589;;;;;;107326:7;;;;;;;;;;106928:589;;;;;;;;;107356:10;;;;:7;:10;;;106928:589;;;;;;;;;107387:10;;;;;;;;;;;106928:589;;;;;;107423:9;106928:589;;;;;;107452:1;106928:589;;;;;;107478:2;106928:589;;;;;;107504:1;106928:589;;;;;106916:5;:9;106922:2;106916:9;;;;;;;;;;;:601;;;;;;;;;;;;;-1:-1:-1;;;;;106916:601:0;;;;;-1:-1:-1;;;;;106916:601:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107528:24;107538:9;107549:2;107528:9;:24::i;:::-;105585:2022;;;;;;;;;;;;;;:::o;95613:138::-;95689:20;91949:23;;;;;;;;;;;;;;95689:8;:20::i;:::-;95720:23;95733:3;95738:4;;95720:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95720:12:0;;-1:-1:-1;;;95720:23:0:i;49135:203::-;49188:7;49309:21;:12;:19;:21::i;110774:402::-;110919:13;110950:18;;:::i;:::-;-1:-1:-1;110971:10:0;;;;:5;:10;;;;;;;;;110950:31;;;;;;;;;-1:-1:-1;;;;;110950:31:0;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;-1:-1:-1;;;110950:31:0;;;;;;;;;110992:13;;;110950:31;;;110992:13;111016:21;;;110950:31;;;111016:21;111048:23;;;110950:31;;;111048:23;110950:31;111089:8;-1:-1:-1;;;;;111089:8:0;:26;110950:31;110977:3;111126:12;110977:3;111126:7;:12::i;:::-;111140:21;111152:3;111157;111140:11;:21::i;:::-;111163:4;;111089:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;111089:79:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;111089:79:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;111089:79:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;111089:79:0;;;;;;;;;111082:86;110774:402;-1:-1:-1;;;;;;;;110774:402:0:o;50971:305::-;51132:41;51151:12;:10;:12::i;:::-;51165:7;51132:18;:41::i;:::-;51124:103;;;;-1:-1:-1;;;51124:103:0;;;;;;;;;51240:28;51250:4;51256:2;51260:7;51240:9;:28::i;64350:114::-;64407:7;64434:12;;;:6;:12;;;;;:22;;;;64350:114::o;64726:227::-;64818:12;;;;:6;:12;;;;;:22;;;64810:45;;64842:12;:10;:12::i;64810:45::-;64802:105;;;;-1:-1:-1;;;64802:105:0;;;;;;;;;64920:25;64931:4;64937:7;64920:10;:25::i;:::-;64726:227;;:::o;48905:154::-;-1:-1:-1;;;;;49021:20:0;;48994:7;49021:20;;;:13;:20;;;;;:30;;49045:5;49021:30;:23;:30;:::i;:::-;49014:37;;48905:154;;;;;:::o;65935:209::-;66033:12;:10;:12::i;:::-;-1:-1:-1;;;;;66022:23:0;:7;-1:-1:-1;;;;;66022:23:0;;66014:83;;;;-1:-1:-1;;;66014:83:0;;;;;;;;;66110:26;66122:4;66128:7;66110:11;:26::i;98942:453::-;99048:11;99056:2;99048:7;:11::i;:::-;-1:-1:-1;;;;;99034:25:0;:10;-1:-1:-1;;;;;99034:25:0;;:58;;;;99077:15;99089:2;99077:11;:15::i;:::-;-1:-1:-1;;;;;99063:29:0;:10;-1:-1:-1;;;;;99063:29:0;;99034:58;99026:89;;;;-1:-1:-1;;;99026:89:0;;;;;;;;;99149:3;99134:11;;;;:8;:11;;;:18;;;;99126:42;;;;-1:-1:-1;;;99126:42:0;;;;;;;;;99201:1;99187:11;;;;;;;;;;:15;;;99179:44;;;;-1:-1:-1;;;99179:44:0;;;;;;;;;99250:11;;;;:8;:11;;;99234:9;;;;:5;:9;;;;;:27;;;;;;;-1:-1:-1;;;99234:27:0;-1:-1:-1;;;;99234:27:0;;;;;;;;;99293:8;-1:-1:-1;99293:11:0;;;;;;;;;;;;;99272:9;;;;:5;:9;;;;;:32;;;;;;;-1:-1:-1;;;99272:32:0;-1:-1:-1;;;;99272:32:0;;;;;;;;;99335:8;99344:1;99335:11;;;;;;;;;;;;;99315:9;;;;:5;:9;;;;;;;:31;;;;;;;-1:-1:-1;;;99315:31:0;-1:-1:-1;;;;;99315:31:0;;;;;;;;;;99362:25;;;;;99378:8;;99362:25;;;;;;;;;;98942:453;;:::o;103031:121::-;103071:20;91949:23;;;;;;103071:20;103102:42;;:10;;103122:21;103102:42;;;;;;;;;103122:21;103102:10;:42;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;51347:151:0;51451:39;51468:4;51474:2;51478:7;51451:39;;;;;;;;;;;;:16;:39::i;49415:164::-;49482:7;;49524:22;:12;49540:5;49524:22;:15;:22;:::i;:::-;-1:-1:-1;49502:44:0;49415:164;-1:-1:-1;;;49415:164:0:o;92335:51::-;92379:7;92335:51;:::o;95899:118::-;95961:20;91949:23;;;;;;95961:20;95992:17;96004:4;;95992:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;95992:11:0;;-1:-1:-1;;;95992:17:0:i;92467:25::-;;;;;;:::o;47174:169::-;47238:7;47265:70;47282:7;47265:70;;;;;;;;;;;;;;;;;:12;;:70;;:16;:70;:::i;48732:89::-;48805:8;48798:15;;;;;;;;-1:-1:-1;;48798:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48772:13;;48798:15;;48805:8;;48798:15;;48805:8;48798:15;;;;;;;;;;;;;;;;;;;;;;;;46897:215;46961:7;-1:-1:-1;;;;;46989:19:0;;46981:74;;;;-1:-1:-1;;;46981:74:0;;;;;;;;;-1:-1:-1;;;;;47075:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;92112:39::-;92149:2;92112:39;:::o;91912:60::-;91949:23;;;;;;;;;;;;;;91912:60;:::o;92499:25::-;;;;:::o;104612:106::-;104665:4;104689:9;;;:5;:9;;;;;:16;-1:-1:-1;;;104689:16:0;;;;:21;;104612:106::o;94295:219::-;94359:20;91949:23;;;;;;94359:20;94411:12;94398:10;:25;94390:57;;;;-1:-1:-1;;;94390:57:0;;;;;;;;;94458:10;:23;94492:6;:14;;-1:-1:-1;;94492:14:0;;;94295:219::o;64023:138::-;64096:7;64123:12;;;:6;:12;;;;;:30;;64147:5;64123:30;:23;:30;:::i;62984:139::-;63053:4;63077:12;;;:6;:12;;;;;:38;;63107:7;63077:38;:29;:38;:::i;96128:123::-;96194:20;91949:23;;;;;;96194:20;96225:18;:11;96239:4;;96225:18;:::i;98535:238::-;98592:9;98603:14;98619:13;98645:18;;:::i;:::-;-1:-1:-1;;;98666:9:0;;;;-1:-1:-1;98666:5:0;:9;;;;;;;;;98645:30;;;;;;;;;-1:-1:-1;;;;;98645:30:0;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;;;-1:-1:-1;;;98645:30:0;;;;;;;;;;;;;;;;;;98535:238::o;47571:96::-;47652:7;47645:14;;;;;;;;-1:-1:-1;;47645:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47619:13;;47645:14;;47652:7;;47645:14;;47652:7;47645:14;;;;;;;;;;;;;;;;;;;;;;;;91387:38;;;;:::o;91662:50::-;91694:18;91662:50;:::o;61729:49::-;61774:4;61729:49;:::o;50382:295::-;50497:12;:10;:12::i;:::-;-1:-1:-1;;;;;50485:24:0;:8;-1:-1:-1;;;;;50485:24:0;;;50477:62;;;;-1:-1:-1;;;50477:62:0;;;;;;;;;50597:8;50552:18;:32;50571:12;:10;:12::i;:::-;-1:-1:-1;;;;;50552:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;50552:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;50552:53:0;;;;;;;;;;;50636:12;:10;:12::i;:::-;-1:-1:-1;;;;;50621:48:0;;50660:8;50621:48;;;;;;;;;;;;;;;50382:295;;:::o;110131:246::-;110212:13;110243:18;;:::i;:::-;-1:-1:-1;110264:10:0;;;;:5;:10;;;;;;;;;110243:31;;;;;;;;;-1:-1:-1;;;;;110243:31:0;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;-1:-1:-1;;;110243:31:0;;;;;;;;;;;110292:8;-1:-1:-1;;;;;110292:8:0;:26;110243:31;110270:3;110329:12;110270:3;110329:7;:12::i;:::-;110343:21;110355:3;110360;110343:11;:21::i;:::-;110292:77;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;110292:77:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;110292:77:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;110292:77:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;110292:77:0;;;;;;;;;110285:84;110131:246;-1:-1:-1;;;110131:246:0:o;91347:33::-;;;;:::o;104887:329::-;104942:20;91949:23;;;;;;104942:20;105008:10;;104981:24;:14;:22;:24::i;:::-;:37;104973:57;;;;-1:-1:-1;;;104973:57:0;;;;;;;;;105041:10;105065:24;:14;:22;:24::i;:::-;105054:8;;:35;105041:48;;105100:24;105110:9;105121:2;105100:9;:24::i;:::-;105182:26;:14;:24;:26::i;92243:60::-;92277:26;92243:60;:::o;97411:985::-;97507:18;97540:17;97572:12;97599:14;97628:20;;:::i;:::-;97663:23;;:::i;:::-;97701:15;97731:22;;:::i;:::-;97768:14;97797:12;97824;97864:18;;:::i;:::-;-1:-1:-1;97885:10:0;;;;:5;:10;;;;;;;;;97864:31;;;;;;;;;-1:-1:-1;;;;;97864:31:0;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;-1:-1:-1;;;97864:31:0;;;;;;;;;;97906:21;;:::i;:::-;97930;97942:3;97947;97930:11;:21::i;:::-;97906:45;-1:-1:-1;97906:45:0;97982:1;97976:8;;;;97964:20;;;-1:-1:-1;98004:5:0;98010:1;98004:8;;;;;-1:-1:-1;98032:5:0;98038:1;98032:8;;;;;-1:-1:-1;98062:5:0;98068:1;98062:8;;;;98051:19;;98096:3;:14;;;98083:27;;98133:3;:13;;;98121:25;;98166:3;:10;;;98157:19;;98198:3;:12;;;98187:23;;98221:48;;;;;;;;98230:3;:7;;;98221:48;;;;;;;;98239:3;:14;;;98221:48;;;;;;;;98255:3;:13;;;98221:48;;;;;;;;;98280:65;;;;;;;;98288:3;:12;;;98280:65;;;;;;;;98302:3;:12;;;98280:65;;;;;;;;98316:3;:13;;;98280:65;;;;;;;;98331:3;:13;;;98280:65;;;;;;;;;98356:32;;;;;;;;98367:3;:10;;;98356:32;;;;;;;;98379:3;:8;;;98356:32;;;;;;;;;97411:985;;;;;;;;;;;;;;;:::o;51569:285::-;51701:41;51720:12;:10;:12::i;:::-;51734:7;51701:18;:41::i;:::-;51693:103;;;;-1:-1:-1;;;51693:103:0;;;;;;;;;51807:39;51821:4;51827:2;51831:7;51840:5;51807:13;:39::i;:::-;51569:285;;;;:::o;109858:132::-;109921:20;91949:23;;;;;;109921:20;109952:8;:30;;-1:-1:-1;;;;;;109952:30:0;-1:-1:-1;;;;;109952:30:0;;;;;;;;;;109858:132::o;94122:103::-;94172:20;91949:23;;;;;;94172:20;94203:6;:14;;-1:-1:-1;;94203:14:0;;;;;;;;;;94122:103::o;47738:755::-;47803:13;47837:16;47845:7;47837;:16::i;:::-;47829:76;;;;-1:-1:-1;;;47829:76:0;;;;;;;;;47944:19;;;;:10;:19;;;;;;;;;47918:45;;;;;;-1:-1:-1;;47918:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:23;;:45;;;47944:19;47918:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;48045:8:0;48039:22;47918:45;;-1:-1:-1;;;;48039:22:0;-1:-1:-1;;48039:22:0;;;;;;;;;;;48035:76;;48090:9;-1:-1:-1;48083:16:0;;48035:76;48215:23;;:27;48211:112;;48290:8;48300:9;48273:37;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;48273:37:0;;;48259:52;;;;;48211:112;48455:8;48465:18;:7;:16;:18::i;:::-;48438:46;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;48438:46:0;;;48424:61;;;47738:755;;;:::o;63297:127::-;63360:7;63387:12;;;:6;:12;;;;;:29;;:27;:29::i;94599:127::-;94652:20;91949:23;;;;;;94652:20;94683:13;:35;;-1:-1:-1;;;;;;94683:35:0;-1:-1:-1;;;;;94683:35:0;;;;;;;;;;94599:127::o;111716:1143::-;112068:13;112094:64;112109:9;;;;:6;:9;;;112120;;;;;;;;;;112094:64;;;;;;;;;;;112131:5;;112094:64;;;;112131:5;;112094:64;112131:5;112094:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;112094:64:0;;;;;;;;;;;-1:-1:-1;112138:4:0;;112094:64;;;;112138:4;;112094:64;112138:4;112094:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;112094:64:0;;;;;;;;;-1:-1:-1;112144:7:0;;112094:64;;;;112144:7;;112094:64;112144:7;112094:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;112153:4:0;;-1:-1:-1;112094:14:0;;-1:-1:-1;112094:64:0:i;:::-;112169:18;;:::i;:::-;112190:583;;;;;;;;112233:19;:4;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;112233:17:0;;-1:-1:-1;;;112233:19:0:i;:::-;-1:-1:-1;;;;;112190:583:0;;;;;;;;112273:8;;;;:5;:8;;;112190:583;;;;;;;;;112314:8;;;;;;;;;;;112190:583;;;;;;112355:8;;;;;;;;;;112190:583;;;;;;;;;112387:9;;;;:6;:9;;;112190:583;;;;;;;;;112421:9;;;;;;;;;;;112190:583;;;;;;;;;112455:7;;;;:4;:7;;;112190:583;;;;;;;;;112487:7;;;;;;;;;;;112190:583;;;;;;112520:7;;;;;;;;;;112190:583;;;;;;112553:7;;;;;;;;;;112190:583;;;;;;;;;112583:10;;;;:7;:10;;;112190:583;;;;;;;;;112649:10;;;;;;;;;;;112190:583;;;;;;;;;;;;;;112679:8;-1:-1:-1;112679:11:0;;;;;;;;;;;;;112190:583;;;;;;;;;112715:11;;;;;;;;;;;112190:583;;;;;;112750:11;;;;;;;;;;112190:583;;;;112791:8;;:60;;-1:-1:-1;;;112791:60:0;;112169:604;;-1:-1:-1;;;;;;112791:8:0;;:26;;:60;;112169:604;;112791:8;;;;112838:6;;112846:4;;;;112791:60;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;112791:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;112791:60:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;112791:60:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;112791:60:0;;;;;;;;;112784:67;111716:1143;-1:-1:-1;;;;;;;;;;;;;111716:1143:0:o;65198:230::-;65291:12;;;;:6;:12;;;;;:22;;;65283:45;;65315:12;:10;:12::i;65283:45::-;65275:106;;;;-1:-1:-1;;;65275:106:0;;;;;;;;107937:1199;108191:11;:9;:11::i;:::-;108271:10;108256:11;108264:2;108256:7;:11::i;:::-;-1:-1:-1;;;;;108256:25:0;;108248:42;;;;-1:-1:-1;;;108248:42:0;;;;;;;;;108347:14;108358:2;108347:10;:14::i;:::-;108339:31;;;;-1:-1:-1;;;108339:31:0;;;;;;;;;108424:64;108439:9;;;;:6;:9;;;108450;;;;;;;;;;108424:64;;;;;;;;;;;108461:5;;108424:64;;;;108461:5;;108424:64;108461:5;108424:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;108424:64:0;;;;;;;;;;;-1:-1:-1;108468:4:0;;108424:64;;;;108468:4;;108424:64;108468:4;108424:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;108424:64:0;;;;;;;;;-1:-1:-1;108474:7:0;;108424:64;;;;108474:7;;108424:64;108474:7;108424:64;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;108483:4:0;;-1:-1:-1;108424:14:0;;-1:-1:-1;108424:64:0:i;:::-;108547:539;;;;;;;;;-1:-1:-1;;;;;108547:539:0;;;;;;;;;108615:8;;;;:5;:8;;;108547:539;;;;;;;;;108656:8;;;;;;;;;;;108547:539;;;;;;108697:8;;;;;;;;;;108547:539;;;;;;;;;108729:9;;;;:6;:9;;;108547:539;;;;;;;;;108763:9;;;;;;;;;;;108547:539;;;;;;;;;108797:7;;;;:4;:7;;;108547:539;;;;;;;;;108829:7;;;;;;;;;;;108547:539;;;;;;108862:7;;;;;;;;;;108547:539;;;;;;108895:7;;;;;;;;;;108547:539;;;;;;;;;108925:10;;;;:7;:10;;;108547:539;;;;;;;;;108956:10;;;;;;;;;;;108547:539;;;;;;108992:9;108547:539;;;;;;109021:1;108547:539;;;;;;109047:2;108547:539;;;;;;109073:1;108547:539;;;;;108535:5;:9;108541:2;108535:9;;;;;;;;;;;:551;;;;;;;;;;;;;-1:-1:-1;;;;;108535:551:0;;;;;-1:-1:-1;;;;;108535:551:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109102:26;109113:10;109125:2;109102:26;;;;;;;;;;;;;;;;107937:1199;;;;;;;:::o;101608:704::-;101790:1;101781:6;:10;;;:25;;;;;101804:2;101795:6;:11;;;101781:25;101773:57;;;;-1:-1:-1;;;101773:57:0;;;;;;;;;101861:6;101849:18;;:8;:18;;;;101841:47;;;;-1:-1:-1;;;101841:47:0;;;;;;;;;101919:3;101907:5;101913:1;101907:8;;;;:15;;;;101899:41;;;;-1:-1:-1;;;101899:41:0;;;;;;;;;101971:3;101959:5;101965:1;101959:8;;;;:15;;;;101951:46;;;;-1:-1:-1;;;101951:46:0;;;;;;;;;102013:9;102008:61;;102044:2;102032:5;102038:1;102032:8;;;;:14;;;;102024:45;;;;-1:-1:-1;;;102024:45:0;;;;;;;;;102100:3;102088:5;102094:1;102088:8;;;;:15;;;;102080:45;;;;-1:-1:-1;;;102080:45:0;;;;;;;;;102155:7;;;;102144;;:18;;;;;;;;102136:50;;;;-1:-1:-1;;;102136:50:0;;;;;;;;;102216:7;;;;102205;;;;:18;;;;;;;;102197:51;;;;-1:-1:-1;;;102197:51:0;;;;;;;;;102267:11;;102282:3;102267:18;;;;;;102259:45;;;;-1:-1:-1;;;102259:45:0;;;;;;;;;101608:704;;;;;;:::o;92708:65::-;;;;;;;;;;;;;;;-1:-1:-1;;92708:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;50748:156::-;-1:-1:-1;;;;;50861:25:0;;;50837:4;50861:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;50748:156::o;92158:39::-;92195:2;92158:39;:::o;91789:46::-;91833:2;91789:46;:::o;91739:43::-;91780:2;91739:43;:::o;94781:138::-;94826:7;94846:20;91949:23;;;;;;94846:20;94884:13;;;;;;;;;-1:-1:-1;;;;;94884:13:0;-1:-1:-1;;;;;94884:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;94884:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94884:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;94884:27:0;;;;;;;;92593:74;;;;:::o;39119:143::-;39189:4;39213:41;39218:3;-1:-1:-1;;;;;39238:14:0;;39213:4;:41::i;24714:471::-;24772:7;25017:6;25013:47;;-1:-1:-1;25047:1:0;25040:8;;25013:47;25084:5;;;25088:1;25084;:5;:1;25108:5;;;;;:10;25100:56;;;;-1:-1:-1;;;25100:56:0;;;;;;;;25661:132;25719:7;25746:39;25750:1;25753;25746:39;;;;;;;;;;;;;;;;;:3;:39::i;23824:136::-;23882:7;23909:43;23913:1;23916;23909:43;;;;;;;;;;;;;;;;;:3;:43::i;68696:114::-;68788:14;;68696:114::o;53320:119::-;53377:4;53401:30;:12;53423:7;53401:30;:21;:30;:::i;12117:106::-;12205:10;12117:106;:::o;59147:158::-;59213:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;59213:29:0;-1:-1:-1;;;;;59213:29:0;;;;;;;;:24;;59267:16;59213:24;59267:7;:16::i;:::-;-1:-1:-1;;;;;59258:39:0;;;;;;;;;;;59147:158;;:::o;93593:109::-;92052:4;93648:19;:9;:17;:19::i;:::-;:33;93640:54;;;;-1:-1:-1;;;93640:54:0;;;;;;;;;93593:109::o;93771:80::-;93826:6;;;;93825:7;93817:26;;;;-1:-1:-1;;;93817:26:0;;;;;;;;93937:100;94010:10;;93994:12;:26;;93986:43;;;;-1:-1:-1;;;93986:43:0;;;;;;;;103509:979;91694:18;103638:9;:18;;103630:50;;;;-1:-1:-1;;;103630:50:0;;;;;;;;;91694:18;103729:9;:17;103725:64;;;103748:10;:41;103768:20;:9;91694:18;103768:20;:13;:20;:::i;:::-;103748:41;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;103748:41:0;103725:64;103861:23;103887:18;103895:9;103887:7;:18::i;:::-;:60;;103938:9;103887:60;;;103916:18;103924:9;103916:7;:18::i;:::-;103861:86;;104016:15;104035:20;104045:9;104035;:20::i;:::-;:25;104034:64;;91780:2;104034:64;;;91833:2;104034:64;104016:82;-1:-1:-1;104176:15:0;-1:-1:-1;;;;;104195:21:0;;104206:10;104195:21;;;;:45;;-1:-1:-1;;;;;;104220:20:0;;104231:9;104220:20;;104195:45;:69;;;;;104255:9;-1:-1:-1;;;;;104244:20:0;:7;-1:-1:-1;;;;;104244:20:0;;;104195:69;104194:119;;104312:1;104194:119;;;104282:27;104305:3;104282:18;91694;104292:7;104282:18;:9;:18;:::i;:27::-;104176:137;-1:-1:-1;104364:11:0;;104360:42;;104377:25;;-1:-1:-1;;;;;104377:16:0;;;:25;;;;;104394:7;;104377:25;;;;104394:7;104377:16;:25;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;104377:25:0;104360:42;104449:31;104461:18;91694;104471:7;104461:18;:9;:18;:::i;:::-;104449:11;:31::i;:::-;103509:979;;;;;:::o;68818:181::-;68972:19;;68990:1;68972:19;;;68818:181::o;27032:130::-;27090:7;27117:37;27121:1;27124;27117:37;;;;;;;;;;;;;;;;;:3;:37::i;23360:181::-;23418:7;23450:5;;;23474:6;;;;23466:46;;;;-1:-1:-1;;;23466:46:0;;;;;;;;87366:399;87455:14;87510:1;87455:14;87564:194;87580:1;:8;87576:1;:12;87564:194;;;87610:9;87636:1;87638;87636:4;;;;;;;;;;;;;;;-1:-1:-1;87666:2:0;87661:7;;;;;:18;;;87677:2;87672:1;:7;;87661:18;87657:90;;;87728:2;87724:1;:6;87709;87718:2;87709:11;:22;87700:31;;87657:90;-1:-1:-1;87590:3:0;;87564:194;;;87366:399;;;;;:::o;95002:404::-;95083:19;95120:18;95190:13;;;;;;;;;-1:-1:-1;;;;;95190:13:0;-1:-1:-1;;;;;95190:25:0;;:27;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;95190:27:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;95190:27:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;95190:27:0;;;;;;;;;95232:2;95249:4;95159:105;;;;;;;;;;;;;;;26:21:-1;;;-1:-1;;22:32;6:49;;95159:105:0;;;95149:116;;49:4:-1;95149:116:0;;;;-1:-1:-1;;;;;95351:21:0;;;-1:-1:-1;;;;95002:404:0:o;54282:110::-;54358:26;54368:2;54372:7;54358:26;;;;;;;;;;;;:9;:26::i;93346:176::-;93477:26;93485:5;93492:10;93477:7;:26::i;:::-;93469:45;;;;-1:-1:-1;;;93469:45:0;;;;;;;;57425:215;57525:16;57533:7;57525;:16::i;:::-;57517:73;;;;-1:-1:-1;;;57517:73:0;;;;;;;;;57601:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;10148:123::-;10217:7;10244:19;10252:3;10244:7;:19::i;99477:2055::-;99553:21;;:::i;:::-;92052:4;99596:16;;99592:1933;;;99646:21;99670:27;99682:3;:14;;;-1:-1:-1;;;;;99670:27:0;:11;:27::i;:::-;99646:51;;99712:26;;:::i;:::-;-1:-1:-1;99712:44:0;;;;;;;;99742:1;99712:44;;;99744:1;99712:44;;;;;;99746:1;99712:44;;;;;;;;;;;;;;;;;;;;;99752:1;99712:44;;;;99754:1;99712:44;;;;99771:30;;:::i;:::-;-1:-1:-1;99771:870:0;;;;;;;;99823:3;99771:870;;;99861:3;99771:870;;;;;;;;;;;99939:3;99771:870;;;;;;99978:3;99771:870;;;;100018:3;99771:870;;;;;;100059:2;99771:870;;;;100088:3;99771:870;;;;;;100121:2;99771:870;;;;;;100155:2;99771:870;;;;100186:2;99771:870;;;;100227:2;99771:870;;;;100258:2;99771:870;;;;100289:2;99771:870;;;;100318:3;99771:870;;;;;;100357:3;99771:870;;;;100399:2;99771:870;;;;;;;;;;;100459:2;99771:870;;;;100488:2;99771:870;;;;;;;;;;;100549:3;99771:870;;;;;;;;;;;;100738:34;:4;99771:870;100767:4;100738:34;:13;:34;:::i;:::-;100721:52;;;;100818:16;:2;92277:26;100818:6;:16::i;:::-;100801:34;;:8;;;;:34;;;;100877:45;;100807:1;;100885:29;;:4;;100899:10;;100885:13;:29::i;:::-;100877:38;;;:45;:42;:45;:::i;:::-;100860:63;;;;:8;;;:63;100982:13;;;;100966:30;;:4;;100979:1;;100966:30;:12;:30::i;:::-;100949:48;;:8;;;:48;-1:-1:-1;99592:1933:0;;-1:-1:-1;;99592:1933:0;;101248:14;;101231:41;-1:-1:-1;;;;;;;;101248:23:0;;;;101231:41;;;101318:14;;-1:-1:-1;;;101318:23:0;;;;101317:32;;101300:8;;;:50;101393:14;;-1:-1:-1;;;101393:23:0;;;;101392:32;;101375:8;;;:50;101469:14;;-1:-1:-1;;;101469:23:0;;;;;;101468:32;;101451:8;;;:50;-1:-1:-1;101231:41:0;99477:2055::o;53606:333::-;53691:4;53716:16;53724:7;53716;:16::i;:::-;53708:73;;;;-1:-1:-1;;;53708:73:0;;;;;;;;;53792:13;53808:16;53816:7;53808;:16::i;:::-;53792:32;;53854:5;-1:-1:-1;;;;;53843:16:0;:7;-1:-1:-1;;;;;53843:16:0;;:51;;;;53887:7;-1:-1:-1;;;;;53863:31:0;:20;53875:7;53863:11;:20::i;:::-;-1:-1:-1;;;;;53863:31:0;;53843:51;:87;;;;53898:32;53915:5;53922:7;53898:16;:32::i;:::-;53835:96;53606:333;-1:-1:-1;;;;53606:333:0:o;56695:574::-;56813:4;-1:-1:-1;;;;;56793:24:0;:16;56801:7;56793;:16::i;:::-;-1:-1:-1;;;;;56793:24:0;;56785:78;;;;-1:-1:-1;;;56785:78:0;;;;;;;;;-1:-1:-1;;;;;56882:16:0;;56874:65;;;;-1:-1:-1;;;56874:65:0;;;;;;;;;56952:39;56973:4;56979:2;56983:7;56952:20;:39::i;:::-;57056:29;57073:1;57077:7;57056:8;:29::i;:::-;-1:-1:-1;;;;;57098:19:0;;;;;;:13;:19;;;;;:35;;57125:7;57098:35;:26;:35;:::i;:::-;-1:-1:-1;;;;;;57144:17:0;;;;;;:13;:17;;;;;:30;;57166:7;57144:30;:21;:30;:::i;:::-;-1:-1:-1;57187:29:0;:12;57204:7;57213:2;57187:29;:16;:29;:::i;:::-;;57253:7;57249:2;-1:-1:-1;;;;;57234:27:0;57243:4;-1:-1:-1;;;;;57234:27:0;;;;;;;;;;;56695:574;;;:::o;67178:188::-;67252:12;;;;:6;:12;;;;;:33;;67277:7;67252:33;:24;:33;:::i;:::-;67248:111;;;67334:12;:10;:12::i;:::-;-1:-1:-1;;;;;67307:40:0;67325:7;-1:-1:-1;;;;;67307:40:0;67319:4;67307:40;;;;;;;;;;67178:188;;:::o;41997:137::-;42068:7;42103:22;42107:3;42119:5;42103:3;:22::i;67374:192::-;67449:12;;;;:6;:12;;;;;:36;;67477:7;67449:36;:27;:36;:::i;:::-;67445:114;;;67534:12;:10;:12::i;:::-;-1:-1:-1;;;;;67507:40:0;67525:7;-1:-1:-1;;;;;67507:40:0;67519:4;67507:40;;;;;;;;;;67374:192;;:::o;10610:227::-;10690:7;;;;10750:22;10754:3;10766:5;10750:3;:22::i;:::-;10719:53;;-1:-1:-1;10719:53:0;-1:-1:-1;;;10610:227:0;;;;;;:::o;57870:100::-;57943:19;;;;:8;;:19;;;;;:::i;11272:204::-;11379:7;11422:44;11427:3;11447;11453:12;11422:4;:44::i;39673:158::-;39753:4;39777:46;39787:3;-1:-1:-1;;;;;39807:14:0;;39777:9;:46::i;52735:272::-;52849:28;52859:4;52865:2;52869:7;52849:9;:28::i;:::-;52896:48;52919:4;52925:2;52929:7;52938:5;52896:22;:48::i;:::-;52888:111;;;;-1:-1:-1;;;52888:111:0;;;;;;;;42385:744;42441:13;42662:10;42658:53;;-1:-1:-1;42689:10:0;;;;;;;;;;;;-1:-1:-1;;;42689:10:0;;;;;;42658:53;42736:5;42721:12;42777:78;42784:9;;42777:78;;42810:8;;42841:2;42833:10;;;;42777:78;;;42865:19;42897:6;42887:17;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;42887:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;42887:17:0;87:42:-1;143:17;;-1:-1;42887:17:0;-1:-1:-1;42959:5:0;;-1:-1:-1;42865:39:0;-1:-1:-1;;;42931:10:0;;42975:115;42982:9;;42975:115;;43049:2;43042:4;:9;43037:2;:14;43026:27;;43008:6;43015:7;;;;;;;43008:15;;;;;;;;;;;:45;-1:-1:-1;;;;;43008:45:0;;;;;;;;-1:-1:-1;43076:2:0;43068:10;;;;42975:115;;;-1:-1:-1;43114:6:0;42385:744;-1:-1:-1;;;;42385:744:0:o;35773:414::-;35836:4;35858:21;35868:3;35873:5;35858:9;:21::i;:::-;35853:327;;-1:-1:-1;27:10;;39:1;23:18;;;45:23;;35896:11:0;:23;;;;;;;;;;;;;36079:18;;36057:19;;;:12;;;:19;;;;;;:40;;;;36112:11;;35853:327;-1:-1:-1;36163:5:0;36156:12;;26289:278;26375:7;26410:12;26403:5;26395:28;;;;-1:-1:-1;;;26395:28:0;;;;;;;;;;;26434:9;26450:1;26446;:5;;;;;;;26289:278;-1:-1:-1;;;;;26289:278:0:o;24263:192::-;24349:7;24385:12;24377:6;;;;24369:29;;;;-1:-1:-1;;;24369:29:0;;;;;;;;;;-1:-1:-1;;;24421:5:0;;;24263:192::o;9909:151::-;9993:4;10017:35;10027:3;10047;10017:9;:35::i;27647:166::-;27733:7;27769:12;27761:6;27753:29;;;;-1:-1:-1;;;27753:29:0;;;;;;;;;;;27804:1;27800;:5;;;;;;;27647:166;-1:-1:-1;;;;27647:166:0:o;54619:250::-;54715:18;54721:2;54725:7;54715:5;:18::i;:::-;54752:54;54783:1;54787:2;54791:7;54800:5;54752:22;:54::i;:::-;54744:117;;;;-1:-1:-1;;;54744:117:0;;;;;;;;88721:481;88870:16;;;88884:1;88870:16;;;;;;;;;88788;;88834:1;;88788:16;;88870;;;88788;;109:14:-1;88870:16:0;88:42:-1;144:17;;-1:-1;88870:16:0;88846:40;;88897:12;88947:1;88951:4;88922:34;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;88922:34:0;;;88912:45;;49:4:-1;88912:45:0;;;;;-1:-1:-1;88973:9:0;88968:205;88992:6;88988:1;:10;88968:205;;;89137:1;89127:12;89141:4;89110:36;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;89110:36:0;;;89082:79;;;;;;89068:4;89073:1;89077;89073:5;89068:11;;;;;;;;;;;;;;;;;:93;89000:3;;88968:205;;;-1:-1:-1;89190:4:0;;88721:481;-1:-1:-1;;;;88721:481:0:o;90664:347::-;90805:5;90823:8;90834:23;90842:4;90848:1;90851:5;90834:23;;:7;:23::i;:::-;90823:34;-1:-1:-1;90868:8:0;;90891:113;90909:2;90907:1;:4;;;90891:113;;;90937:20;90943:10;90954:1;90943:13;;;;;;;;;;;;;90937:1;;:20;;;:5;:20;:::i;:::-;90933:24;;90981:1;90976;:6;90972:20;;90991:1;-1:-1:-1;90984:8:0;;-1:-1:-1;;90984:8:0;90972:20;90913:3;;90891:113;;;;90664:347;;;;;;;:::o;90205:345::-;90345:5;90363:8;90374:23;90382:4;90388:1;90391:5;90374:23;;:7;:23::i;:::-;90363:34;-1:-1:-1;90408:8:0;;90431:112;90449:1;90447;:3;;;90431:112;;;90476:20;90482:10;90493:1;90482:13;;;;;;;;90476:20;90472:24;;90520:1;90515;:6;90511:20;;90530:1;-1:-1:-1;90523:8:0;;-1:-1:-1;;90523:8:0;90511:20;90452:3;;90431:112;;89835:256;89952:6;89984:1;89979;:6;;89971:51;;;;-1:-1:-1;;;89971:51:0;;;;;;;;;90082:1;90072;90068;:5;90076:1;90068:9;90047:10;90052:4;90047;:10::i;:::-;:31;;;;;;90040:43;;89835:256;-1:-1:-1;;;;89835:256:0:o;41084:137::-;41154:4;41178:35;41186:3;41206:5;41178:7;:35::i;40777:131::-;40844:4;40868:32;40873:3;40893:5;40868:4;:32::i;9341:176::-;9430:4;9454:55;9459:3;9479;-1:-1:-1;;;;;9493:14:0;;9454:4;:55::i;38661:204::-;38756:18;;38728:7;;38756:26;-1:-1:-1;38748:73:0;;;;-1:-1:-1;;;38748:73:0;;;;;;;;;38839:3;:11;;38851:5;38839:18;;;;;;;;;;;;;;;;38832:25;;38661:204;;;;:::o;39438:149::-;39511:4;39535:44;39543:3;-1:-1:-1;;;;;39563:14:0;;39535:7;:44::i;7996:279::-;8100:19;;8063:7;;;;8100:27;-1:-1:-1;8092:74:0;;;;-1:-1:-1;;;8092:74:0;;;;;;;;;8179:22;8204:3;:12;;8217:5;8204:19;;;;;;;;;;;;;;;;;;8179:44;;8242:5;:10;;;8254:5;:12;;;8234:33;;;;;7996:279;;;;;:::o;8698:319::-;8792:7;8831:17;;;:12;;;:17;;;;;;8882:12;8867:13;8859:36;;;;-1:-1:-1;;;8859:36:0;;;;;;;;;;;8949:3;:12;;8973:1;8962:8;:12;8949:26;;;;;;;;;;;;;;;;;;:33;;;8942:40;;;8698:319;;;;;:::o;37993:129::-;38066:4;38090:19;;;:12;;;;;:19;;;;;;:24;;;37993:129::o;58535:604::-;58656:4;58683:15;:2;-1:-1:-1;;;;;58683:13:0;;:15::i;:::-;58678:60;;-1:-1:-1;58722:4:0;58715:11;;58678:60;58748:23;58774:252;-1:-1:-1;;;58887:12:0;:10;:12::i;:::-;58914:4;58933:7;58955:5;58790:181;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;58790:181:0;;;;-1:-1:-1;;;;;58790:181:0;;38:4:-1;29:7;25:18;67:10;61:17;-1:-1;;;;;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;58790:181:0;58774:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58774:15:0;;;:252;;:15;:252;:::i;:::-;58748:278;;59037:13;59064:10;59053:32;;;;;;;;;;;;;;-1:-1:-1;;;;;;59104:26:0;-1:-1:-1;;;59104:26:0;;-1:-1:-1;;;58535:604:0;;;;;;:::o;55205:404::-;-1:-1:-1;;;;;55285:16:0;;55277:61;;;;-1:-1:-1;;;55277:61:0;;;;;;;;;55358:16;55366:7;55358;:16::i;:::-;55357:17;55349:58;;;;-1:-1:-1;;;55349:58:0;;;;;;;;;55420:45;55449:1;55453:2;55457:7;55420:20;:45::i;:::-;-1:-1:-1;;;;;55478:17:0;;;;;;:13;:17;;;;;:30;;55500:7;55478:30;:21;:30;:::i;:::-;-1:-1:-1;55521:29:0;:12;55538:7;55547:2;55521:29;:16;:29;:::i;:::-;-1:-1:-1;55568:33:0;;55593:7;;-1:-1:-1;;;;;55568:33:0;;;55585:1;;55568:33;;55585:1;;55568:33;55205:404;;:::o;2665:215::-;2721:6;2751:5;;;2776:6;;;;;;:16;;;2791:1;2786;:6;;2776:16;2775:38;;;;2802:1;2798;:5;:14;;;;;2811:1;2807;:5;2798:14;2767:84;;;;-1:-1:-1;;;2767:84:0;;;;;;;;89307:410;89367:7;89409:1;89395:4;:11;:15;89387:53;;;;-1:-1:-1;;;89387:53:0;;;;;;;;;89451:21;89510:1;89496:4;:11;:15;89484:4;89489:1;89484:7;;;;;;;;;;;;;;89476:16;;:36;;;;;;89516:1;89475:42;89451:66;;89528:12;89570:4;89575:13;89570:19;;;;;;;;;;;;;;89553:37;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;89553:37:0;;;89543:48;;;;;;89528:63;;89628:4;89633:1;89628:7;;;;;;;;;;;;;;89620:16;;89639:1;89620:20;89612:29;;89602:4;89607:1;89602:7;;;;;;;;;;;;;:39;;;;;89674:4;89652;89657:13;89652:19;;;;;;;;;;;;;;;;;:26;89704:4;89307:410;-1:-1:-1;;;89307:410:0:o;36363:1544::-;36429:4;36568:19;;;:12;;;:19;;;;;;36604:15;;36600:1300;;37039:18;;-1:-1:-1;;36990:14:0;;;;37039:22;;;;36966:21;;37039:3;;:22;;37326;;;;;;;;;;;;;;37306:42;;37472:9;37443:3;:11;;37455:13;37443:26;;;;;;;;;;;;;;;;;;;:38;;;;37549:23;;;37591:1;37549:12;;;:23;;;;;;37575:17;;;37549:43;;37701:17;;37549:3;;37701:17;;;;;;;;;;;;;;;;;;;;;;37796:3;:12;;:19;37809:5;37796:19;;;;;;;;;;;37789:26;;;37839:4;37832:11;;;;;;;;36600:1300;37883:5;37876:12;;;;;4811:692;4887:4;5022:17;;;:12;;;:17;;;;;;5056:13;5052:444;;-1:-1:-1;;5141:38:0;;;;;;;;;;;;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;5123:12:0;:57;;;;;;;;;;;;;;;;;;;;;;;;5338:19;;5318:17;;;:12;;;:17;;;;;;;:39;5372:11;;5052:444;5452:5;5416:3;:12;;5440:1;5429:8;:12;5416:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;5479:5;5472:12;;;;;28594:619;28654:4;29122:20;;28965:66;29162:23;;;;;;:42;;-1:-1:-1;;29189:15:0;;;29154:51;-1:-1:-1;;28594:619:0:o;31709:196::-;31812:12;31844:53;31867:6;31875:4;31881:1;31884:12;33216;33249:18;33260:6;33249:10;:18::i;:::-;33241:60;;;;-1:-1:-1;;;33241:60:0;;;;;;;;;33375:12;33389:23;33416:6;-1:-1:-1;;;;;33416:11:0;33436:8;33447:4;33416:36;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;33374:78:0;;;;33467:7;33463:595;;;33498:10;-1:-1:-1;33491:17:0;;-1:-1:-1;33491:17:0;33463:595;33612:17;;:21;33608:439;;33875:10;33869:17;33936:15;33923:10;33919:2;33915:19;33908:44;33823:148;34018:12;34011:20;;-1:-1:-1;;;34011:20:0;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;29:2;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;;;;;;:::o;:::-;;;;;;;;;;;29:2;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;;;;;;:::o;:::-;;;;;;;;;;;29:2;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29:2;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;;;;;;:::o;:::-;;;;;;;;;;;29:2;21:6;17:15;125:4;109:14;101:6;88:42;-1:-1;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;5:130;72:20;;-1:-1;;;;;83325:54;;84912:35;;84902:2;;84961:1;;84951:12;160:175;246:18;290:15;276:30;;273:39;-1:-1;270:2;;;325:1;;315:12;999:174;1084:18;1128:15;1114:30;;1111:39;-1:-1;1108:2;;;1163:1;;1153:12;1198:610;;1311:3;1304:4;1296:6;1292:17;1288:27;1278:2;;-1:-1;;1319:12;1278:2;1372:76;77811:17;1372:76;;;1363:85;;1454:16;1513:17;1571:3;77811:17;1546:3;1542:27;1539:36;1536:2;;;1588:1;;1578:12;1536:2;1613:1;;1598:204;1353:4;1620:1;1617:13;1598:204;;;5281:6;5268:20;83636:4;85794:5;83625:16;85771:5;85768:33;85758:2;;1613:1;;85805:12;85758:2;1691:48;;77823:4;1753:14;;;;1781;;;;;1645:1;1638:9;1598:204;;;1602:14;;;;1271:537;;;;;2032:174;2117:18;2161:15;2147:30;;2144:39;-1:-1;2141:2;;;2196:1;;2186:12;2231:610;;2344:3;2337:4;2329:6;2325:17;2321:27;2311:2;;-1:-1;;2352:12;2311:2;2405:76;77811:17;2405:76;;;2396:85;;2487:16;2546:17;2604:3;77811:17;2579:3;2575:27;2572:36;2569:2;;;2621:1;;2611:12;2569:2;2646:1;2631:204;2386:4;2653:1;2650:13;2631:204;;;2736:35;2767:3;2755:10;2736:35;;;2724:48;;77823:4;2786:14;;;;2814;;;;;2678:1;2671:9;2631:204;;;2635:14;;;2304:537;;;;;2849:124;2913:20;;82705:13;;82698:21;85033:32;;85023:2;;85079:1;;85069:12;3996:337;;;4111:3;4104:4;4096:6;4092:17;4088:27;4078:2;;-1:-1;;4119:12;4078:2;-1:-1;4149:20;;4189:18;4178:30;;4175:2;;;-1:-1;;4211:12;4175:2;4255:4;4247:6;4243:17;4231:29;;4306:3;4255:4;4286:17;4247:6;4272:32;;4269:41;4266:2;;;4323:1;;4313:12;4931:128;4997:20;;83244:6;83233:18;;85523:34;;85513:2;;85571:1;;85561:12;5203:126;5268:20;;83636:4;83625:16;;85768:33;;85758:2;;85815:1;;85805:12;5336:241;;5440:2;5428:9;5419:7;5415:23;5411:32;5408:2;;;-1:-1;;5446:12;5408:2;5508:53;5553:7;5529:22;5508:53;;5584:366;;;5705:2;5693:9;5684:7;5680:23;5676:32;5673:2;;;-1:-1;;5711:12;5673:2;5773:53;5818:7;5794:22;5773:53;;;5763:63;;5881:53;5926:7;5863:2;5906:9;5902:22;5881:53;;;5871:63;;5667:283;;;;;;5957:491;;;;6095:2;6083:9;6074:7;6070:23;6066:32;6063:2;;;-1:-1;;6101:12;6063:2;85:6;72:20;97:33;124:5;97:33;;;6153:63;-1:-1;6253:2;6292:22;;72:20;97:33;72:20;97:33;;;6057:391;;6261:63;;-1:-1;;;6361:2;6400:22;;;;5133:20;;6057:391;6455:721;;;;;6619:3;6607:9;6598:7;6594:23;6590:33;6587:2;;;-1:-1;;6626:12;6587:2;6688:53;6733:7;6709:22;6688:53;;;6678:63;;6796:53;6841:7;6778:2;6821:9;6817:22;6796:53;;;6786:63;;6886:2;6929:9;6925:22;5133:20;6894:63;;7022:2;7011:9;7007:18;6994:32;7046:18;7038:6;7035:30;7032:2;;;-1:-1;;7068:12;7032:2;7143:6;7132:9;7128:22;3634:3;3627:4;3619:6;3615:17;3611:27;3601:2;;-1:-1;;3642:12;3601:2;3689:6;3676:20;3662:34;;3711:64;3726:48;3767:6;3726:48;;;3711:64;;;3795:6;3788:5;3781:21;3899:3;6778:2;3890:6;3823;3881:16;;3878:25;3875:2;;;-1:-1;;3906:12;3875:2;84237:6;6778:2;3823:6;3819:17;6778:2;3857:5;3853:16;84214:30;84275:16;;;6778:2;84275:16;84268:27;;;;6581:595;;;;-1:-1;6581:595;;-1:-1;;6581:595;7183:360;;;7301:2;7289:9;7280:7;7276:23;7272:32;7269:2;;;-1:-1;;7307:12;7269:2;7369:53;7414:7;7390:22;7369:53;;;7359:63;;7477:50;7519:7;7459:2;7499:9;7495:22;7477:50;;7550:366;;;7671:2;7659:9;7650:7;7646:23;7642:32;7639:2;;;-1:-1;;7677:12;7639:2;7739:53;7784:7;7760:22;7739:53;;;7729:63;7829:2;7868:22;;;;5133:20;;-1:-1;;;7633:283;7923:235;;8024:2;8012:9;8003:7;7999:23;7995:32;7992:2;;;-1:-1;;8030:12;7992:2;2926:6;2913:20;85058:5;82705:13;82698:21;85036:5;85033:32;85023:2;;-1:-1;;85069:12;8165:241;;8269:2;8257:9;8248:7;8244:23;8240:32;8237:2;;;-1:-1;;8275:12;8237:2;-1:-1;3047:20;;8231:175;-1:-1;8231:175;8413:263;;8528:2;8516:9;8507:7;8503:23;8499:32;8496:2;;;-1:-1;;8534:12;8496:2;-1:-1;3195:13;;8490:186;-1:-1;8490:186;8683:366;;;8804:2;8792:9;8783:7;8779:23;8775:32;8772:2;;;-1:-1;;8810:12;8772:2;3060:6;3047:20;8862:63;;8962:2;9005:9;9001:22;72:20;97:33;124:5;97:33;;;8970:63;;;;8766:283;;;;;;9056:366;;;9177:2;9165:9;9156:7;9152:23;9148:32;9145:2;;;-1:-1;;9183:12;9145:2;-1:-1;;3047:20;;;9335:2;9374:22;;;5133:20;;-1:-1;9139:283;9429:239;;9532:2;9520:9;9511:7;9507:23;9503:32;9500:2;;;-1:-1;;9538:12;9500:2;3337:6;3324:20;3349:32;3375:5;3349:32;;9675:261;;9789:2;9777:9;9768:7;9764:23;9760:32;9757:2;;;-1:-1;;9795:12;9757:2;3476:6;3470:13;3488:32;3514:5;3488:32;;9943:367;;;10067:2;10055:9;10046:7;10042:23;10038:32;10035:2;;;-1:-1;;10073:12;10035:2;10131:17;10118:31;10169:18;10161:6;10158:30;10155:2;;;-1:-1;;10191:12;10155:2;10229:65;10286:7;10277:6;10266:9;10262:22;10229:65;;;10219:75;;;;-1:-1;10029:281;-1:-1;;;;10029:281;10317:1777;;;;;;;;;;;;10735:3;10723:9;10714:7;10710:23;10706:33;10703:2;;;-1:-1;;10742:12;10703:2;10838:18;;10800:17;10787:31;10827:30;10824:2;;;-1:-1;;10860:12;10824:2;10898:65;10955:7;10800:17;10787:31;10935:9;10931:22;10898:65;;;10888:75;;-1:-1;10888:75;-1:-1;11018:77;11087:7;11000:2;11063:22;;11018:77;;;11008:87;;11151:76;11219:7;11132:3;11199:9;11195:22;11151:76;;;11141:86;;11283:76;11351:7;11264:3;11331:9;11327:22;11283:76;;;11273:86;;11415:76;11483:7;11396:3;11463:9;11459:22;11415:76;;;11405:86;;11547:51;11590:7;11528:3;11570:9;11566:22;11547:51;;;11537:61;;11654:76;11722:7;11635:3;11702:9;11698:22;11654:76;;;11644:86;;11786:76;11854:7;11767:3;11834:9;11830:22;11786:76;;;11776:86;;10838:18;11927:3;11916:9;11912:19;11899:33;11941:30;11938:2;;;-1:-1;;11974:12;11938:2;;12013:65;12070:7;11927:3;11916:9;11912:19;11899:33;12050:9;12046:22;12013:65;;;12002:76;;;;;;;;10697:1397;;;;;;;;;;;;;;;12101:1430;;;;;;;;;;12435:3;12423:9;12414:7;12410:23;12406:33;12403:2;;;-1:-1;;12442:12;12403:2;12500:17;12487:31;12538:18;12530:6;12527:30;12524:2;;;-1:-1;;12560:12;12524:2;12598:65;12655:7;12646:6;12635:9;12631:22;12598:65;;;12588:75;;-1:-1;12588:75;-1:-1;12718:76;;-1:-1;12786:7;12700:2;12762:22;;12718:76;;;12708:86;;12849:77;12918:7;12831:2;12898:9;12894:22;12849:77;;;12839:87;;12982:76;13050:7;12963:3;13030:9;13026:22;12982:76;;;12972:86;;13114:76;13182:7;13095:3;13162:9;13158:22;13114:76;;;13104:86;;13246:51;13289:7;13227:3;13269:9;13265:22;13246:51;;;13236:61;;13334:3;13378:9;13374:22;72:20;97:33;124:5;97:33;;;13343:63;;;;13443:3;13487:9;13483:22;5133:20;13452:63;;12397:1134;;;;;;;;;;;;13538:362;;13663:2;13651:9;13642:7;13638:23;13634:32;13631:2;;;-1:-1;;13669:12;13631:2;13720:17;13714:24;13758:18;13750:6;13747:30;13744:2;;;-1:-1;;13780:12;13744:2;13867:6;13856:9;13852:22;4455:3;4448:4;4440:6;4436:17;4432:27;4422:2;;-1:-1;;4463:12;4422:2;4503:6;4497:13;4483:27;;4525:65;4540:49;4582:6;4540:49;;4525:65;4610:6;4603:5;4596:21;4714:3;13663:2;4705:6;4638;4696:16;;4693:25;4690:2;;;-1:-1;;4721:12;4690:2;4741:39;4773:6;13663:2;4672:5;4668:16;13663:2;4638:6;4634:17;4741:39;;;13800:84;13625:275;-1:-1;;;;;13625:275;13907:1178;;;;;;;;14204:3;14192:9;14183:7;14179:23;14175:33;14172:2;;;-1:-1;;14211:12;14172:2;4874:6;4861:20;-1:-1;;;;;85428:5;83114:46;85403:5;85400:35;85390:2;;-1:-1;;85439:12;85390:2;14263:63;-1:-1;14381:76;14449:7;14363:2;14425:22;;14381:76;;;14371:86;;14512:77;14581:7;14494:2;14561:9;14557:22;14512:77;;;14502:87;;14645:76;14713:7;14626:3;14693:9;14689:22;14645:76;;;14635:86;;14777:76;14845:7;14758:3;14825:9;14821:22;14777:76;;;14767:86;;14909:51;14952:7;14890:3;14932:9;14928:22;14909:51;;;14899:61;;14997:3;15041:9;15037:22;5133:20;15006:63;;14166:919;;;;;;;;;;;15092:239;;15195:2;15183:9;15174:7;15170:23;15166:32;15163:2;;;-1:-1;;15201:12;15163:2;5010:6;4997:20;83244:6;85550:5;83233:18;85526:5;85523:34;85513:2;;-1:-1;;85561:12;15586:413;;;15730:3;15718:9;15709:7;15705:23;15701:33;15698:2;;;-1:-1;;15737:12;15698:2;5146:6;5133:20;15789:63;;15907:76;15975:7;15889:2;15955:9;15951:22;15907:76;;16006:492;;;;16147:2;16135:9;16126:7;16122:23;16118:32;16115:2;;;-1:-1;;16153:12;16115:2;5146:6;5133:20;16205:63;;16333:2;16322:9;16318:18;16305:32;16357:18;16349:6;16346:30;16343:2;;;-1:-1;;16379:12;16343:2;16417:65;16474:7;16465:6;16454:9;16450:22;16417:65;;;16109:389;;16407:75;;-1:-1;16407:75;;-1:-1;;;;16109:389;16505:857;;;;;;;16691:3;16679:9;16670:7;16666:23;16662:33;16659:2;;;-1:-1;;16698:12;16659:2;5146:6;5133:20;16750:63;;16868:51;16911:7;16850:2;16891:9;16887:22;16868:51;;;16858:61;;16974:51;17017:7;16956:2;16997:9;16993:22;16974:51;;;16964:61;;17080:51;17123:7;17062:2;17103:9;17099:22;17080:51;;;17070:61;;17196:3;17185:9;17181:19;17168:33;17221:18;17213:6;17210:30;17207:2;;;-1:-1;;17243:12;17207:2;17281:65;17338:7;17329:6;17318:9;17314:22;17281:65;;;16653:709;;;;-1:-1;16653:709;;-1:-1;16653:709;;17271:75;;16653:709;-1:-1;;;16653:709;17369:237;;17471:2;17459:9;17450:7;17446:23;17442:32;17439:2;;;-1:-1;;17477:12;17439:2;17539:51;17582:7;17558:22;17539:51;;17613:984;;;;;;;17859:3;17847:9;17838:7;17834:23;17830:33;17827:2;;;-1:-1;;17866:12;17827:2;17928:51;17971:7;17947:22;17928:51;;;17918:61;;18016:2;18034:51;18077:7;18016:2;18057:9;18053:22;18034:51;;;18024:61;;475:3;456:17;18187:9;456:17;452:27;442:2;;-1:-1;;483:12;442:2;517:4;536:77;551:61;517:4;551:61;;536:77;619:16;18122:2;18187:9;18183:22;707:27;18187:9;707:27;736:3;707:27;704:36;701:2;;;-1:-1;;743:12;701:2;-1:-1;763:205;517:4;785:1;782:13;763:205;;;868:36;900:3;888:10;868:36;;;856:49;;919:14;;;;947;;;;810:1;803:9;763:205;;;767:14;18130:85;;;18271:74;18337:7;18313:22;18271:74;;;18261:84;;;;;;;;18401:74;18467:7;18382:3;18447:9;18443:22;18401:74;;;18391:84;;18531:50;18573:7;18512:3;18553:9;18549:22;18531:50;;;18521:60;;17821:776;;;;;;;;;19400:652;19758:21;19800:1;19785:255;79778:4;19807:1;19804:13;19785:255;;;19871:13;;83244:6;83233:18;45924:36;;18763:4;18754:14;;;;80598;;;;19832:1;19825:9;19785:255;;22202:644;22555:21;22597:1;22582:252;80121:4;22604:1;22601:13;22582:252;;;22668:13;;83636:4;83625:16;46542:35;;18937:4;18928:14;;;;80598;;;;22629:1;22622:9;22582:252;;23244:343;;23386:5;80342:12;81776:6;81771:3;81764:19;23479:52;23524:6;81813:4;81808:3;81804:14;81813:4;23505:5;23501:16;23479:52;;;84832:7;84816:14;-1:-1;;84812:28;23543:39;;;;81813:4;23543:39;;23334:253;-1:-1;;23334:253;24242:300;;81776:6;81771:3;81764:19;84237:6;84232:3;81813:4;81808:3;81804:14;84214:30;-1:-1;81813:4;84284:6;81808:3;84275:16;;84268:27;81813:4;84832:7;;84836:2;24528:6;84816:14;84812:28;81808:3;24497:39;;24490:46;;24344:198;;;;;;42967:2661;43213:63;43261:14;43190:16;43184:23;43213:63;;;43354:4;43347:5;43343:16;43337:23;43366:61;43354:4;43416:3;43412:14;43398:12;43366:61;;;;43512:4;43505:5;43501:16;43495:23;43524:59;43512:4;43572:3;43568:14;43554:12;43524:59;;;;43667:4;43660:5;43656:16;43650:23;43679:59;43667:4;43727:3;43723:14;43709:12;43679:59;;;;43819:4;43812:5;43808:16;43802:23;43831:59;43819:4;43879:3;43875:14;43861:12;43831:59;;;;43973:4;43966:5;43962:16;43956:23;43985:59;43973:4;44033:3;44029:14;44015:12;43985:59;;;;44127:4;44120:5;44116:16;44110:23;44139:59;44127:4;44187:3;44183:14;44169:12;44139:59;;;;44281:4;44274:5;44270:16;44264:23;44293:59;44281:4;44341:3;44337:14;44323:12;44293:59;;;;44436:6;;44429:5;44425:18;44419:25;44450:61;44436:6;44498:3;44494:16;44480:12;44450:61;;;;;44595:6;;44588:5;44584:18;44578:25;44609:61;44595:6;44657:3;44653:16;44639:12;44609:61;;;;;44751:6;;44744:5;44740:18;44734:25;44765:61;44751:6;44813:3;44809:16;44795:12;44765:61;;;;;44905:6;;44898:5;44894:18;44888:25;44919:61;44905:6;44967:3;44963:16;44949:12;44919:61;;;;;45064:6;;45057:5;45053:18;45047:25;45078:61;45064:6;45126:3;45122:16;45108:12;45078:61;;;;;45217:6;;45210:5;45206:18;45200:25;45231:61;45217:6;45279:3;45275:16;45261:12;45231:61;;;;;45375:6;;45368:5;45364:18;45358:25;45389:61;45375:6;45437:3;45433:16;45419:12;45389:61;;;;;45532:6;;45525:5;45521:18;45515:25;45546:61;45532:6;45594:3;45590:16;45576:12;45546:61;;45635:103;-1:-1;;;;;83114:46;45696:37;;45690:48;45865:100;83244:6;83233:18;45924:36;;45918:47;46485:97;83636:4;83625:16;46542:35;;46536:46;46703:253;23036:37;;;46928:2;46919:12;;46819:137;46963:392;23036:37;;;47216:2;47207:12;;23036:37;47318:12;;;47107:248;47362:531;23036:37;;;47643:2;47634:12;;23036:37;;;;47745:12;;;23036:37;47856:12;;;47534:359;47900:271;;23754:5;80342:12;23865:52;23910:6;23905:3;23898:4;23891:5;23887:16;23865:52;;;23929:16;;;;;48034:137;-1:-1;;48034:137;48178:430;;-1:-1;25433:5;25427:12;25467:1;;25456:9;25452:17;25480:1;25475:268;;;;25754:1;25749:425;;;;25445:729;;25475:268;-1:-1;;25680:25;;25668:38;;25549:1;25534:17;;25553:4;25530:28;25720:16;;;-1:-1;25475:268;;25749:425;25818:1;25807:9;25803:17;79625:3;-1:-1;79615:14;79657:4;;-1:-1;79644:18;-1:-1;26007:130;26021:6;26018:1;26015:13;26007:130;;;26080:14;;26067:11;;;26060:35;26114:15;;;;26036:12;;26007:130;;;-1:-1;;;26151:16;;;-1:-1;25445:729;;;;23754:5;80342:12;23865:52;23910:6;23905:3;23898:4;23891:5;23887:16;23865:52;;;23929:16;;48359:249;-1:-1;;;;48359:249;48615:381;-1:-1;;;37491:33;;37475:2;37543:12;;48804:192;49402:222;-1:-1;;;;;83325:54;;;;19192:45;;49529:2;49514:18;;49500:124;49631:672;-1:-1;;;;;83325:54;;;19192:45;;83325:54;;50057:2;50042:18;;19192:45;50140:2;50125:18;;23036:37;;;49876:3;50177:2;50162:18;;50155:48;;;49631:672;;50217:76;;49861:19;;50279:6;50217:76;;;50209:84;49847:456;-1:-1;;;;;;49847:456;50310:349;-1:-1;;;;;83325:54;;;;19035:58;;50645:2;50630:18;;23036:37;50473:2;50458:18;;50444:215;50666:310;50837:2;50822:18;;50826:9;21129:21;50666:310;21156:281;79778:4;21178:1;21175:13;21156:281;;;82417:2;;21275:6;82408:12;83636:4;82384:37;82408:12;21275:6;82384:37;;;83625:16;46542:35;;18928:14;;;21362:68;-1:-1;21203:1;21196:9;21156:281;;50983:210;82705:13;;82698:21;22919:34;;51104:2;51089:18;;51075:118;51429:210;;83020:20;;;;24022:34;;51550:2;51535:18;;51521:118;51646:310;;51793:2;51814:17;51807:47;51868:78;51793:2;51782:9;51778:18;51932:6;51868:78;;51963:416;52163:2;52177:47;;;26413:2;52148:18;;;81764:19;26449:34;81804:14;;;26429:55;-1:-1;;;26504:12;;;26497:26;26542:12;;;52134:245;52386:416;52586:2;52600:47;;;26793:1;52571:18;;;81764:19;-1:-1;;;81804:14;;;26808:31;26858:12;;;52557:245;52809:416;53009:2;53023:47;;;27109:2;52994:18;;;81764:19;27145:34;81804:14;;;27125:55;-1:-1;;;27200:12;;;27193:39;27251:12;;;52980:245;53232:416;53432:2;53446:47;;;27502:1;53417:18;;;81764:19;-1:-1;;;81804:14;;;27517:29;27565:12;;;53403:245;53655:416;53855:2;53869:47;;;27816:1;53840:18;;;81764:19;-1:-1;;;81804:14;;;27831:27;27877:12;;;53826:245;54078:416;54278:2;54292:47;;;28128:1;54263:18;;;81764:19;-1:-1;;;81804:14;;;28143:30;28192:12;;;54249:245;54501:416;54701:2;54715:47;;;28443:2;54686:18;;;81764:19;-1:-1;;;81804:14;;;28459:36;28514:12;;;54672:245;54924:416;55124:2;55138:47;;;28765:2;55109:18;;;81764:19;28801:34;81804:14;;;28781:55;-1:-1;;;28856:12;;;28849:42;28910:12;;;55095:245;55347:416;55547:2;55561:47;;;29161:2;55532:18;;;81764:19;29197:30;81804:14;;;29177:51;29247:12;;;55518:245;55770:416;55970:2;55984:47;;;29498:2;55955:18;;;81764:19;29534:29;81804:14;;;29514:50;29583:12;;;55941:245;56193:416;56393:2;56407:47;;;29834:2;56378:18;;;81764:19;29870:27;81804:14;;;29850:48;29917:12;;;56364:245;56616:416;56816:2;56830:47;;;30168:2;56801:18;;;81764:19;-1:-1;;;81804:14;;;30184:39;30242:12;;;56787:245;57039:416;57239:2;57253:47;;;30493:2;57224:18;;;81764:19;30529:34;81804:14;;;30509:55;-1:-1;;;30584:12;;;30577:28;30624:12;;;57210:245;57462:416;57662:2;57676:47;;;30875:2;57647:18;;;81764:19;30911:27;81804:14;;;30891:48;30958:12;;;57633:245;57885:416;58085:2;58099:47;;;31209:2;58070:18;;;81764:19;31245:34;81804:14;;;31225:55;-1:-1;;;31300:12;;;31293:25;31337:12;;;58056:245;58308:416;58508:2;58522:47;;;31588:2;58493:18;;;81764:19;-1:-1;;;81804:14;;;31604:34;31657:12;;;58479:245;58731:416;58931:2;58945:47;;;31908:1;58916:18;;;81764:19;-1:-1;;;81804:14;;;31923:29;31971:12;;;58902:245;59154:416;59354:2;59368:47;;;32222:2;59339:18;;;81764:19;32258:34;81804:14;;;32238:55;-1:-1;;;32313:12;;;32306:36;32361:12;;;59325:245;59577:416;59777:2;59791:47;;;32612:2;59762:18;;;81764:19;32648:34;81804:14;;;32628:55;-1:-1;;;32703:12;;;32696:40;32755:12;;;59748:245;60000:416;60200:2;60214:47;;;33006:2;60185:18;;;81764:19;33042:34;81804:14;;;33022:55;33111:26;33097:12;;;33090:48;33157:12;;;60171:245;60423:416;60623:2;60637:47;;;33408:2;60608:18;;;81764:19;33444:34;81804:14;;;33424:55;-1:-1;;;33499:12;;;33492:34;33545:12;;;60594:245;60846:416;61046:2;61060:47;;;33796:2;61031:18;;;81764:19;-1:-1;;;81804:14;;;33812:41;33872:12;;;61017:245;61269:416;61469:2;61483:47;;;34123:2;61454:18;;;81764:19;-1:-1;;;81804:14;;;34139:42;34200:12;;;61440:245;61692:416;61892:2;61906:47;;;34451:2;61877:18;;;81764:19;34487:34;81804:14;;;34467:55;-1:-1;;;34542:12;;;34535:26;34580:12;;;61863:245;62115:416;62315:2;62329:47;;;62300:18;;;81764:19;34867:34;81804:14;;;34847:55;34921:12;;;62286:245;62538:416;62738:2;62752:47;;;35172:2;62723:18;;;81764:19;35208:34;81804:14;;;35188:55;-1:-1;;;35263:12;;;35256:25;35300:12;;;62709:245;62961:416;63161:2;63175:47;;;35551:2;63146:18;;;81764:19;35587:34;81804:14;;;35567:55;-1:-1;;;35642:12;;;35635:36;35690:12;;;63132:245;63384:416;63584:2;63598:47;;;35941:2;63569:18;;;81764:19;35977:34;81804:14;;;35957:55;-1:-1;;;36032:12;;;36025:36;36080:12;;;63555:245;63807:416;64007:2;64021:47;;;36331:2;63992:18;;;81764:19;-1:-1;;;81804:14;;;36347:42;36408:12;;;63978:245;64230:416;64430:2;64444:47;;;36659:2;64415:18;;;81764:19;36695:34;81804:14;;;36675:55;-1:-1;;;36750:12;;;36743:33;36795:12;;;64401:245;64653:416;64853:2;64867:47;;;37046:2;64838:18;;;81764:19;37082:34;81804:14;;;37062:55;-1:-1;;;37137:12;;;37130:39;37188:12;;;64824:245;65076:416;65276:2;65290:47;;;37794:2;65261:18;;;81764:19;-1:-1;;;81804:14;;;37810:39;37868:12;;;65247:245;65499:416;65699:2;65713:47;;;38119:2;65684:18;;;81764:19;-1:-1;;;81804:14;;;38135:41;38195:12;;;65670:245;65922:416;66122:2;66136:47;;;38446:2;66107:18;;;81764:19;38482:34;81804:14;;;38462:55;-1:-1;;;38537:12;;;38530:25;38574:12;;;66093:245;66345:416;66545:2;66559:47;;;39096:2;66530:18;;;81764:19;39132:34;81804:14;;;39112:55;-1:-1;;;39187:12;;;39180:41;39240:12;;;66516:245;66768:416;66968:2;66982:47;;;39491:2;66953:18;;;81764:19;39527:31;81804:14;;;39507:52;39578:12;;;66939:245;67191:416;67391:2;67405:47;;;39829:2;67376:18;;;81764:19;-1:-1;;;81804:14;;;39845:37;39901:12;;;67362:245;67614:416;67814:2;67828:47;;;40152:1;67799:18;;;81764:19;-1:-1;;;81804:14;;;40167:27;40213:12;;;67785:245;68037:416;68237:2;68251:47;;;40464:1;68222:18;;;81764:19;-1:-1;;;81804:14;;;40479:27;40525:12;;;68208:245;68460:416;68660:2;68674:47;;;40776:2;68645:18;;;81764:19;-1:-1;;;81804:14;;;40792:43;40854:12;;;68631:245;68883:416;69083:2;69097:47;;;41105:2;69068:18;;;81764:19;-1:-1;;;81804:14;;;41121:43;41183:12;;;69054:245;69306:416;69506:2;69520:47;;;69491:18;;;81764:19;41470:34;81804:14;;;41450:55;41524:12;;;69477:245;69729:416;69929:2;69943:47;;;41775:2;69914:18;;;81764:19;-1:-1;;;81804:14;;;41791:45;41855:12;;;69900:245;70152:416;70352:2;70366:47;;;42106:2;70337:18;;;81764:19;42142:34;81804:14;;;42122:55;-1:-1;;;42197:12;;;42190:39;42248:12;;;70323:245;70575:416;70775:2;70789:47;;;42499:2;70760:18;;;81764:19;-1:-1;;;81804:14;;;42515:40;42574:12;;;70746:245;70998:416;71198:2;71212:47;;;42825:2;71183:18;;;81764:19;-1:-1;;;81804:14;;;42841:42;42902:12;;;71169:245;71421:999;;71800:3;71815:121;71918:17;71909:6;71815:121;;;72023:3;72008:19;;24147:58;;;-1:-1;;;;;83325:54;;72115:3;72100:19;;19035:58;72243:3;72228:19;;21845:21;-1:-1;21872:281;80121:4;21894:1;21891:13;21872:281;;;82417:2;;21991:6;82408:12;83636:4;82384:37;82408:12;21991:6;82384:37;;;83625:16;46542:35;;18928:14;;;22078:68;-1:-1;21919:1;21912:9;21872:281;;;21876:14;;;71800:3;72281;72270:9;72266:19;72259:49;72322:88;71800:3;71789:9;71785:19;72396:6;72388;72322:88;;;72314:96;71771:649;-1:-1;;;;;;;;;71771:649;72427:963;;72788:3;72803:121;72906:17;72897:6;72803:121;;;73003:3;72988:19;;23036:37;;;-1:-1;;;;;83325:54;;73087:3;73072:19;;19192:45;73103:115;73213:3;73198:19;;73189:6;73103:115;;;72788:3;73251;73240:9;73236:19;73229:49;73292:88;72788:3;72777:9;72773:19;73366:6;73358;73292:88;;73397:1049;;73801:3;73816:121;73919:17;73910:6;73816:121;;;74016:3;74001:19;;23036:37;;;-1:-1;;;;;83325:54;;74100:3;74085:19;;19192:45;74116:115;74226:3;74211:19;;74202:6;74116:115;;;74264:3;74249:19;;74242:49;;;73786:19;;81764;81804:14;;;73772:674;-1:-1;;;;73772:674;74453:1550;-1:-1;;;;;83114:46;;45696:37;;75130:2;75115:18;;;23036:37;;;83636:4;83625:16;;;75209:2;75194:18;;46542:35;83625:16;;75288:2;75273:18;;46542:35;74965:3;74950:19;;;75303:115;75413:3;75398:19;;75389:6;75303:115;;;75539:3;75524:19;;20442:21;20484:1;20469:252;79891:4;20491:1;20488:13;20469:252;;;18866:42;18904:3;20561:6;20555:13;18866:42;;;18928:14;;;;80598;;;;20516:1;20509:9;20469:252;;;20473:14;;;;75555:69;75619:3;75608:9;75604:19;75595:6;75555:69;;;75635:117;75747:3;75736:9;75732:19;75723:6;75635:117;;;75763:69;75827:3;75816:9;75812:19;75803:6;75763:69;;;75843;75907:3;75896:9;75892:19;75883:6;75843:69;;;75923:70;75988:3;75977:9;75973:19;75963:7;75923:70;;;74936:1067;;;;;;;;;;;;;;;76010:218;83244:6;83233:18;;;;45924:36;;76135:2;76120:18;;76106:122;76464:218;83542:10;83531:22;;;;46437:36;;76589:2;76574:18;;76560:122;76689:214;83636:4;83625:16;;;;46542:35;;76812:2;76797:18;;76783:120;76910:420;83636:4;83625:16;;;46542:35;;83625:16;;;77237:2;77222:18;;46542:35;83625:16;;;77316:2;77301:18;;46542:35;77081:2;77066:18;;77052:278;77337:256;77399:2;77393:9;77425:17;;;77500:18;77485:34;;77521:22;;;77482:62;77479:2;;;77557:1;;77547:12;77479:2;77399;77566:22;77377:216;;-1:-1;77377:216;77600:243;;77756:18;77748:6;77745:30;77742:2;;;-1:-1;;77778:12;77742:2;-1:-1;77823:4;77811:17;;77679:164;78348:321;;78491:18;78483:6;78480:30;78477:2;;;-1:-1;;78513:12;78477:2;-1:-1;84832:7;78567:17;-1:-1;;78563:33;78654:4;78644:15;;78414:255;84310:268;84375:1;84382:101;84396:6;84393:1;84390:13;84382:101;;;84463:11;;;84457:18;84444:11;;;84437:39;84418:2;84411:10;84382:101;;;84498:6;84495:1;84492:13;84489:2;;;-1:-1;;84375:1;84545:16;;84538:27;84359:219;84853:117;-1:-1;;;;;83325:54;;84912:35;;84902:2;;84961:1;;84951:12;85219:115;-1:-1;;;;;;82871:78;;85277:34;;85267:2;;85325:1;;85315:12

Swarm Source

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