ETH Price: $3,237.12 (+1.33%)

Token

Alpaca City ()
 

Overview

Max Total Supply

25,627

Holders

1,832

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x1f1dbf210d8bd9ba610071d284620c157cdfdf40
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

A miracle city where DeFi meets Alpaca NFTs. Official City Guide - https://guide.alpaca.city

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
AlpacaCore

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT

// pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * // importANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


// Dependency file: contracts/interfaces/IGeneScience.sol


// pragma solidity =0.6.12;

interface IGeneScience {
    function isAlpacaGeneScience() external pure returns (bool);

    /**
     * @dev given genes of alpaca 1 & 2, return a genetic combination
     * @param genes1 genes of matron
     * @param genes2 genes of sire
     * @param generation child generation
     * @param targetBlock target block child is intended to be born
     * @return gene child gene
     * @return energy energy associated with the gene
     * @return generationFactor buffs child energy, higher the generation larger the generationFactor
     *   energy = gene energy * generationFactor
     */
    function mixGenes(
        uint256 genes1,
        uint256 genes2,
        uint256 generation,
        uint256 targetBlock
    )
        external
        view
        returns (
            uint256 gene,
            uint256 energy,
            uint256 generationFactor
        );
}


// Dependency file: @openzeppelin/contracts/introspection/IERC165.sol


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


// Dependency file: @openzeppelin/contracts/utils/Address.sol


// 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) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

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

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

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

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

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

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

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


// Dependency file: contracts/interfaces/ICryptoAlpacaEnergyListener.sol


// pragma solidity 0.6.12;

// import "@openzeppelin/contracts/introspection/IERC165.sol";

interface ICryptoAlpacaEnergyListener is IERC165 {
    /**
        @dev Handles the Alpaca energy change callback.
        @param id The id of the Alpaca which the energy changed
        @param oldEnergy The ID of the token being transferred
        @param newEnergy The amount of tokens being transferred
    */
    function onCryptoAlpacaEnergyChanged(
        uint256 id,
        uint256 oldEnergy,
        uint256 newEnergy
    ) external;
}


// Dependency file: @openzeppelin/contracts/math/SafeMath.sol


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


// Dependency file: @openzeppelin/contracts/utils/EnumerableMap.sol


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


// Dependency file: @openzeppelin/contracts/utils/ReentrancyGuard.sol


// pragma solidity ^0.6.0;

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

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

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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


// Dependency file: @openzeppelin/contracts/GSN/Context.sol


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


// Dependency file: @openzeppelin/contracts/utils/Pausable.sol


// pragma solidity ^0.6.0;

// import "@openzeppelin/contracts/GSN/Context.sol";

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

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

    bool private _paused;

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

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

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

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

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

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


// Dependency file: @openzeppelin/contracts/token/ERC1155/IERC1155.sol


// pragma solidity ^0.6.2;

// import "@openzeppelin/contracts/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
}


// Dependency file: @openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol


// pragma solidity ^0.6.2;

// import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}


// Dependency file: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol


// pragma solidity ^0.6.0;

// import "@openzeppelin/contracts/introspection/IERC165.sol";

/**
 * _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {

    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    )
        external
        returns(bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    )
        external
        returns(bytes4);
}


// Dependency file: @openzeppelin/contracts/introspection/ERC165.sol


// pragma solidity ^0.6.0;

// import "@openzeppelin/contracts/introspection/IERC165.sol";

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


// Dependency file: @openzeppelin/contracts/token/ERC1155/ERC1155.sol


// pragma solidity ^0.6.0;

// import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
// import "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol";
// import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
// import "@openzeppelin/contracts/GSN/Context.sol";
// import "@openzeppelin/contracts/introspection/ERC165.sol";
// import "@openzeppelin/contracts/math/SafeMath.sol";
// import "@openzeppelin/contracts/utils/Address.sol";

/**
 *
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using SafeMath for uint256;
    using Address for address;

    // Mapping from token ID to account balances
    mapping (uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /*
     *     bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
     *     bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
     *     bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
     *
     *     => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
     *        0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
     */
    bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;

    /*
     *     bytes4(keccak256('uri(uint256)')) == 0x0e89341c
     */
    bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;

    /**
     * @dev See {_setURI}.
     */
    constructor (string memory uri) public {
        _setURI(uri);

        // register the supported interfaces to conform to ERC1155 via ERC165
        _registerInterface(_INTERFACE_ID_ERC1155);

        // register the supported interfaces to conform to ERC1155MetadataURI via ERC165
        _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
    }

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) external view override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    )
        public
        view
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            require(accounts[i] != address(0), "ERC1155: batch balance query for the zero address");
            batchBalances[i] = _balances[ids[i]][accounts[i]];
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(_msgSender() != operator, "ERC1155: setting approval status for self");

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

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    )
        public
        virtual
        override
    {
        require(to != address(0), "ERC1155: transfer to the zero address");
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
        _balances[id][to] = _balances[id][to].add(amount);

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        public
        virtual
        override
    {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: transfer caller is not owner nor approved"
        );

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            _balances[id][from] = _balances[id][from].sub(
                amount,
                "ERC1155: insufficient balance for transfer"
            );
            _balances[id][to] = _balances[id][to].add(amount);
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
        require(account != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][account] = _balances[id][account].add(amount);
        emit TransferSingle(operator, address(0), account, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `account`
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens of token type `id`.
     */
    function _burn(address account, uint256 id, uint256 amount) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");

        _balances[id][account] = _balances[id][account].sub(
            amount,
            "ERC1155: burn amount exceeds balance"
        );

        emit TransferSingle(operator, account, address(0), id, amount);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
        require(account != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");

        for (uint i = 0; i < ids.length; i++) {
            _balances[ids[i]][account] = _balances[ids[i]][account].sub(
                amounts[i],
                "ERC1155: burn amount exceeds balance"
            );
        }

        emit TransferBatch(operator, account, address(0), ids, amounts);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        internal virtual
    { }

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    )
        private
    {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver(to).onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    )
        private
    {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
                if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}


// Dependency file: @openzeppelin/contracts/access/Ownable.sol


// pragma solidity ^0.6.0;

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

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

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}


// Dependency file: contracts/CryptoAlpaca/AlpacaBase.sol


// pragma solidity =0.6.12;

// import "@openzeppelin/contracts/math/SafeMath.sol";
// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// import "@openzeppelin/contracts/utils/EnumerableMap.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
// import "contracts/interfaces/IGeneScience.sol";

contract AlpacaBase is Ownable {
    using SafeMath for uint256;

    /* ========== ENUM ========== */

    /**
     * @dev Alpaca can be in one of the two state:
     *
     * EGG - When two alpaca breed with each other, alpaca EGG is created.
     *       `gene` and `energy` are both 0 and will be assigned when egg is cracked
     *
     * GROWN - When egg is cracked and alpaca is born! `gene` and `energy` are determined
     *         in this state.
     */
    enum AlpacaGrowthState {EGG, GROWN}

    /* ========== PUBLIC STATE VARIABLES ========== */

    /**
     * @dev payment required to use cracked if it's done automatically
     * assigning to 0 indicate cracking action is not automatic
     */
    uint256 public autoCrackingFee = 0;

    /**
     * @dev Base breeding ALPA fee
     */
    uint256 public baseHatchingFee = 10e18; // 10 ALPA

    /**
     * @dev ALPA ERC20 contract address
     */
    IERC20 public alpa;

    /**
     * @dev 10% of the breeding ALPA fee goes to `devAddress`
     */
    address public devAddress;

    /**
     * @dev 90% of the breeding ALPA fee goes to `stakingAddress`
     */
    address public stakingAddress;

    /**
     * @dev number of percentage breeding ALPA fund goes to devAddress
     * dev percentage = devBreedingPercentage / 100
     * staking percentage = (100 - devBreedingPercentage) / 100
     */
    uint256 public devBreedingPercentage = 10;

    /**
     * @dev An approximation of currently how many seconds are in between blocks.
     */
    uint256 public secondsPerBlock = 15;

    /**
     * @dev amount of time a new born alpaca needs to wait before participating in breeding activity.
     */
    uint256 public newBornCoolDown = uint256(1 days);

    /**
     * @dev amount of time an egg needs to wait to be cracked
     */
    uint256 public hatchingDuration = uint256(5 minutes);

    /**
     * @dev when two alpaca just bred, the breeding multiplier will doubled to control
     * alpaca's population. This is the amount of time each parent must wait for the
     * breeding multiplier to reset back to 1
     */
    uint256 public hatchingMultiplierCoolDown = uint256(6 hours);

    /**
     * @dev hard cap on the maximum hatching cost multiplier it can reach to
     */
    uint16 public maxHatchCostMultiplier = 16;

    /**
     * @dev Gen0 generation factor
     */
    uint64 public constant GEN0_GENERATION_FACTOR = 10;

    /**
     * @dev maximum gen-0 alpaca energy. This is to prevent contract owner from
     * creating arbitrary energy for gen-0 alpaca
     */
    uint32 public constant MAX_GEN0_ENERGY = 3600;

    /**
     * @dev hatching fee increase with higher alpa generation
     */
    uint256 public generationHatchingFeeMultiplier = 2;

    /**
     * @dev gene science contract address for genetic combination algorithm.
     */
    IGeneScience public geneScience;

    /* ========== INTERNAL STATE VARIABLES ========== */

    /**
     * @dev An array containing the Alpaca struct for all Alpacas in existence. The ID
     * of each alpaca is the index into this array.
     */
    Alpaca[] internal alpacas;

    /**
     * @dev mapping from AlpacaIDs to an address where alpaca owner approved address to use
     * this alpca for breeding. addrss can breed with this cat multiple times without limit.
     * This will be resetted everytime someone transfered the alpaca.
     */
    EnumerableMap.UintToAddressMap internal alpacaAllowedToAddress;

    /* ========== ALPACA STRUCT ========== */

    /**
     * @dev Everything about your alpaca is stored in here. Each alpaca's appearance
     * is determined by the gene. The energy associated with each alpaca is also
     * related to the gene
     */
    struct Alpaca {
        // Theaalpaca genetic code.
        uint256 gene;
        // the alpaca energy level
        uint32 energy;
        // The timestamp from the block when this alpaca came into existence.
        uint64 birthTime;
        // The minimum timestamp alpaca needs to wait to avoid hatching multiplier
        uint64 hatchCostMultiplierEndBlock;
        // hatching cost multiplier
        uint16 hatchingCostMultiplier;
        // The ID of the parents of this alpaca, set to 0 for gen0 alpaca.
        uint32 matronId;
        uint32 sireId;
        // The "generation number" of this alpaca. The generation number of an alpacas
        // is the smaller of the two generation numbers of their parents, plus one.
        uint16 generation;
        // The minimum timestamp new born alpaca needs to wait to hatch egg.
        uint64 cooldownEndBlock;
        // The generation factor buffs alpaca energy level
        uint64 generationFactor;
        // defines current alpaca state
        AlpacaGrowthState state;
    }

    /* ========== VIEW ========== */

    function getTotalAlpaca() external view returns (uint256) {
        return alpacas.length;
    }

    function _getBaseHatchingCost(uint256 _generation)
        internal
        view
        returns (uint256)
    {
        return
            baseHatchingFee.add(
                _generation.mul(generationHatchingFeeMultiplier).mul(1e18)
            );
    }

    /* ========== OWNER MUTATIVE FUNCTION ========== */

    /**
     * @param _hatchingDuration hatching duration
     */
    function setHatchingDuration(uint256 _hatchingDuration) external onlyOwner {
        hatchingDuration = _hatchingDuration;
    }

    /**
     * @param _stakingAddress staking address
     */
    function setStakingAddress(address _stakingAddress) external onlyOwner {
        stakingAddress = _stakingAddress;
    }

    /**
     * @param _devAddress dev address
     */
    function setDevAddress(address _devAddress) external onlyDev {
        devAddress = _devAddress;
    }

    /**
     * @param _maxHatchCostMultiplier max hatch cost multiplier
     */
    function setMaxHatchCostMultiplier(uint16 _maxHatchCostMultiplier)
        external
        onlyOwner
    {
        maxHatchCostMultiplier = _maxHatchCostMultiplier;
    }

    /**
     * @param _devBreedingPercentage base generation factor
     */
    function setDevBreedingPercentage(uint256 _devBreedingPercentage)
        external
        onlyOwner
    {
        require(
            devBreedingPercentage <= 100,
            "CryptoAlpaca: invalid breeding percentage - must be between 0 and 100"
        );
        devBreedingPercentage = _devBreedingPercentage;
    }

    /**
     * @param _generationHatchingFeeMultiplier multiplier
     */
    function setGenerationHatchingFeeMultiplier(
        uint256 _generationHatchingFeeMultiplier
    ) external onlyOwner {
        generationHatchingFeeMultiplier = _generationHatchingFeeMultiplier;
    }

    /**
     * @param _baseHatchingFee base birthing
     */
    function setBaseHatchingFee(uint256 _baseHatchingFee) external onlyOwner {
        baseHatchingFee = _baseHatchingFee;
    }

    /**
     * @param _newBornCoolDown new born cool down
     */
    function setNewBornCoolDown(uint256 _newBornCoolDown) external onlyOwner {
        newBornCoolDown = _newBornCoolDown;
    }

    /**
     * @param _hatchingMultiplierCoolDown base birthing
     */
    function setHatchingMultiplierCoolDown(uint256 _hatchingMultiplierCoolDown)
        external
        onlyOwner
    {
        hatchingMultiplierCoolDown = _hatchingMultiplierCoolDown;
    }

    /**
     * @dev update how many seconds per blocks are currently observed.
     * @param _secs number of seconds
     */
    function setSecondsPerBlock(uint256 _secs) external onlyOwner {
        secondsPerBlock = _secs;
    }

    /**
     * @dev only owner can update autoCrackingFee
     */
    function setAutoCrackingFee(uint256 _autoCrackingFee) external onlyOwner {
        autoCrackingFee = _autoCrackingFee;
    }

    /**
     * @dev owner can upgrading gene science
     */
    function setGeneScience(IGeneScience _geneScience) external onlyOwner {
        require(
            _geneScience.isAlpacaGeneScience(),
            "CryptoAlpaca: invalid gene science contract"
        );

        // Set the new contract address
        geneScience = _geneScience;
    }

    /**
     * @dev owner can update ALPA erc20 token location
     */
    function setAlpaContract(IERC20 _alpa) external onlyOwner {
        alpa = _alpa;
    }

    /* ========== MODIFIER ========== */

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


// Dependency file: contracts/CryptoAlpaca/AlpacaToken.sol


// pragma solidity =0.6.12;

// import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
// import "contracts/CryptoAlpaca/AlpacaBase.sol";

contract AlpacaToken is AlpacaBase, ERC1155("") {
    /* ========== EVENTS ========== */

    /**
     * @dev Emitted when single `alpacaId` alpaca with `gene` and `energy` is born
     */
    event BornSingle(uint256 indexed alpacaId, uint256 gene, uint256 energy);

    /**
     * @dev Equivalent to multiple {BornSingle} events
     */
    event BornBatch(uint256[] alpacaIds, uint256[] genes, uint256[] energy);

    /* ========== VIEWS ========== */

    /**
     * @dev Check if `_alpacaId` is owned by `_account`
     */
    function isOwnerOf(address _account, uint256 _alpacaId)
        public
        view
        returns (bool)
    {
        return balanceOf(_account, _alpacaId) == 1;
    }

    /* ========== OWNER MUTATIVE FUNCTION ========== */

    /**
     * @dev Allow contract owner to update URI to look up all alpaca metadata
     */
    function setURI(string memory _newuri) external onlyOwner {
        _setURI(_newuri);
    }

    /**
     * @dev Allow contract owner to create generation 0 alpaca with `_gene`,
     *   `_energy` and transfer to `owner`
     *
     * Requirements:
     *
     * - `_energy` must be less than or equal to MAX_GEN0_ENERGY
     */
    function createGen0Alpaca(
        uint256 _gene,
        uint256 _energy,
        address _owner
    ) external onlyOwner {
        address alpacaOwner = _owner;
        if (alpacaOwner == address(0)) {
            alpacaOwner = owner();
        }

        _createGen0Alpaca(_gene, _energy, alpacaOwner);
    }

    /**
     * @dev Equivalent to multiple {createGen0Alpaca} function
     *
     * Requirements:
     *
     * - all `_energies` must be less than or equal to MAX_GEN0_ENERGY
     */
    function createGen0AlpacaBatch(
        uint256[] memory _genes,
        uint256[] memory _energies,
        address _owner
    ) external onlyOwner {
        address alpacaOwner = _owner;
        if (alpacaOwner == address(0)) {
            alpacaOwner = owner();
        }

        _createGen0AlpacaBatch(_genes, _energies, _owner);
    }

    /* ========== INTERNAL ALPA GENERATION ========== */

    /**
     * @dev Create an alpaca egg. Egg's `gene` and `energy` will assigned to 0
     * initially and won't be determined until egg is cracked.
     */
    function _createEgg(
        uint256 _matronId,
        uint256 _sireId,
        uint256 _generation,
        uint256 _cooldownEndBlock,
        address _owner
    ) internal returns (uint256) {
        require(_matronId == uint256(uint32(_matronId)));
        require(_sireId == uint256(uint32(_sireId)));
        require(_generation == uint256(uint16(_generation)));

        Alpaca memory _alpaca = Alpaca({
            gene: 0,
            energy: 0,
            birthTime: uint64(now),
            hatchCostMultiplierEndBlock: 0,
            hatchingCostMultiplier: 1,
            matronId: uint32(_matronId),
            sireId: uint32(_sireId),
            cooldownEndBlock: uint64(_cooldownEndBlock),
            generation: uint16(_generation),
            generationFactor: 0,
            state: AlpacaGrowthState.EGG
        });

        alpacas.push(_alpaca);
        uint256 eggId = alpacas.length - 1;

        _mint(_owner, eggId, 1, "");

        return eggId;
    }

    /**
     * @dev Internal gen-0 alpaca creation function
     *
     * Requirements:
     *
     * - `_energy` must be less than or equal to MAX_GEN0_ENERGY
     */
    function _createGen0Alpaca(
        uint256 _gene,
        uint256 _energy,
        address _owner
    ) internal returns (uint256) {
        require(_energy <= MAX_GEN0_ENERGY, "CryptoAlpaca: invalid energy");

        Alpaca memory _alpaca = Alpaca({
            gene: _gene,
            energy: uint32(_energy),
            birthTime: uint64(now),
            hatchCostMultiplierEndBlock: 0,
            hatchingCostMultiplier: 1,
            matronId: 0,
            sireId: 0,
            cooldownEndBlock: 0,
            generation: 0,
            generationFactor: GEN0_GENERATION_FACTOR,
            state: AlpacaGrowthState.GROWN
        });

        alpacas.push(_alpaca);
        uint256 newAlpacaID = alpacas.length - 1;

        _mint(_owner, newAlpacaID, 1, "");

        // emit the born event
        emit BornSingle(newAlpacaID, _gene, _energy);

        return newAlpacaID;
    }

    /**
     * @dev Internal gen-0 alpaca batch creation function
     *
     * Requirements:
     *
     * - all `_energies` must be less than or equal to MAX_GEN0_ENERGY
     */
    function _createGen0AlpacaBatch(
        uint256[] memory _genes,
        uint256[] memory _energies,
        address _owner
    ) internal returns (uint256[] memory) {
        require(
            _genes.length > 0,
            "CryptoAlpaca: must pass at least one genes"
        );
        require(
            _genes.length == _energies.length,
            "CryptoAlpaca: genes and energy length mismatch"
        );

        uint256 alpacaIdStart = alpacas.length;
        uint256[] memory ids = new uint256[](_genes.length);
        uint256[] memory amount = new uint256[](_genes.length);

        for (uint256 i = 0; i < _genes.length; i++) {
            require(
                _energies[i] <= MAX_GEN0_ENERGY,
                "CryptoAlpaca: invalid energy"
            );

            Alpaca memory _alpaca = Alpaca({
                gene: _genes[i],
                energy: uint32(_energies[i]),
                birthTime: uint64(now),
                hatchCostMultiplierEndBlock: 0,
                hatchingCostMultiplier: 1,
                matronId: 0,
                sireId: 0,
                cooldownEndBlock: 0,
                generation: 0,
                generationFactor: GEN0_GENERATION_FACTOR,
                state: AlpacaGrowthState.GROWN
            });

            alpacas.push(_alpaca);
            ids[i] = alpacaIdStart + i;
            amount[i] = 1;
        }

        _mintBatch(_owner, ids, amount, "");

        emit BornBatch(ids, _genes, _energies);

        return ids;
    }
}


// Dependency file: contracts/interfaces/ICryptoAlpaca.sol


// pragma solidity =0.6.12;

// import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

interface ICryptoAlpaca is IERC1155 {
    function getAlpaca(uint256 _id)
        external
        view
        returns (
            uint256 id,
            bool isReady,
            uint256 cooldownEndBlock,
            uint256 birthTime,
            uint256 matronId,
            uint256 sireId,
            uint256 hatchingCost,
            uint256 hatchingCostMultiplier,
            uint256 hatchCostMultiplierEndBlock,
            uint256 generation,
            uint256 gene,
            uint256 energy,
            uint256 state
        );

    function hasPermissionToBreedAsSire(address _addr, uint256 _id)
        external
        view
        returns (bool);

    function grandPermissionToBreed(address _addr, uint256 _sireId) external;

    function clearPermissionToBreed(uint256 _alpacaId) external;

    function hatch(uint256 _matronId, uint256 _sireId)
        external
        payable
        returns (uint256);

    function crack(uint256 _id) external;
}


// Dependency file: contracts/CryptoAlpaca/AlpacaBreed.sol


// pragma solidity =0.6.12;

// import "@openzeppelin/contracts/math/SafeMath.sol";
// import "@openzeppelin/contracts/utils/EnumerableMap.sol";
// import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
// import "@openzeppelin/contracts/utils/Pausable.sol";

// import "contracts/CryptoAlpaca/AlpacaToken.sol";
// import "contracts/interfaces/ICryptoAlpaca.sol";

contract AlpacaBreed is AlpacaToken, ICryptoAlpaca, ReentrancyGuard, Pausable {
    using SafeMath for uint256;
    using EnumerableMap for EnumerableMap.UintToAddressMap;

    /* ========== EVENTS ========== */

    // The Hatched event is fired when two alpaca successfully hached an egg.
    event Hatched(
        uint256 indexed eggId,
        uint256 matronId,
        uint256 sireId,
        uint256 cooldownEndBlock
    );

    // The GrantedToBreed event is fired whne an alpaca's owner granted
    // addr account to use alpacaId as sire to breed.
    event GrantedToBreed(uint256 indexed alpacaId, address addr);

    /* ========== VIEWS ========== */

    /**
     * Returns all the relevant information about a specific alpaca.
     * @param _id The ID of the alpaca of interest.
     */
    function getAlpaca(uint256 _id)
        external
        override
        view
        returns (
            uint256 id,
            bool isReady,
            uint256 cooldownEndBlock,
            uint256 birthTime,
            uint256 matronId,
            uint256 sireId,
            uint256 hatchingCost,
            uint256 hatchingCostMultiplier,
            uint256 hatchCostMultiplierEndBlock,
            uint256 generation,
            uint256 gene,
            uint256 energy,
            uint256 state
        )
    {
        Alpaca storage alpaca = alpacas[_id];

        id = _id;
        isReady = (alpaca.cooldownEndBlock <= block.number);
        cooldownEndBlock = alpaca.cooldownEndBlock;
        birthTime = alpaca.birthTime;
        matronId = alpaca.matronId;
        sireId = alpaca.sireId;
        hatchingCost = _getBaseHatchingCost(alpaca.generation);
        hatchingCostMultiplier = alpaca.hatchingCostMultiplier;
        if (alpaca.hatchCostMultiplierEndBlock <= block.number) {
            hatchingCostMultiplier = 1;
        }

        hatchCostMultiplierEndBlock = alpaca.hatchCostMultiplierEndBlock;
        generation = alpaca.generation;
        gene = alpaca.gene;
        energy = alpaca.energy;
        state = uint256(alpaca.state);
    }

    /**
     * @dev Calculating hatching ALPA cost
     */
    function hatchingALPACost(uint256 _matronId, uint256 _sireId)
        external
        view
        returns (uint256)
    {
        return _hatchingALPACost(_matronId, _sireId, false);
    }

    /**
     * @dev Checks to see if a given egg passed cooldownEndBlock and ready to crack
     * @param _id alpaca egg ID
     */

    function isReadyToCrack(uint256 _id) external view returns (bool) {
        Alpaca storage alpaca = alpacas[_id];
        return
            (alpaca.state == AlpacaGrowthState.EGG) &&
            (alpaca.cooldownEndBlock <= uint64(block.number));
    }

    /* ========== EXTERNAL MUTATIVE FUNCTIONS  ========== */

    /**
     * Grants permission to another account to sire with one of your alpacas.
     * @param _addr The address that will be able to use sire for breeding.
     * @param _sireId a alpaca _addr will be able to use for breeding as sire.
     */
    function grandPermissionToBreed(address _addr, uint256 _sireId)
        external
        override
    {
        require(
            isOwnerOf(msg.sender, _sireId),
            "CryptoAlpaca: You do not own sire alpaca"
        );

        alpacaAllowedToAddress.set(_sireId, _addr);
        emit GrantedToBreed(_sireId, _addr);
    }

    /**
     * check if `_addr` has permission to user alpaca `_id` to breed with as sire.
     */
    function hasPermissionToBreedAsSire(address _addr, uint256 _id)
        external
        override
        view
        returns (bool)
    {
        if (isOwnerOf(_addr, _id)) {
            return true;
        }

        return alpacaAllowedToAddress.get(_id) == _addr;
    }

    /**
     * Clear the permission on alpaca for another user to use to breed.
     * @param _alpacaId a alpaca to clear permission .
     */
    function clearPermissionToBreed(uint256 _alpacaId) external override {
        require(
            isOwnerOf(msg.sender, _alpacaId),
            "CryptoAlpaca: You do not own this alpaca"
        );

        alpacaAllowedToAddress.remove(_alpacaId);
    }

    /**
     * @dev Hatch an baby alpaca egg with two alpaca you own (_matronId and _sireId).
     * Requires a pre-payment of the fee given out to the first caller of crack()
     * @param _matronId The ID of the Alpaca acting as matron
     * @param _sireId The ID of the Alpaca acting as sire
     * @return The hatched alpaca egg ID
     */
    function hatch(uint256 _matronId, uint256 _sireId)
        external
        override
        payable
        whenNotPaused
        nonReentrant
        returns (uint256)
    {
        address msgSender = msg.sender;

        // Checks for payment.
        require(
            msg.value >= autoCrackingFee,
            "CryptoAlpaca: Required autoCrackingFee not sent"
        );

        // Checks for ALPA payment
        require(
            alpa.allowance(msgSender, address(this)) >=
                _hatchingALPACost(_matronId, _sireId, true),
            "CryptoAlpaca: Required hetching ALPA fee not sent"
        );

        // Checks if matron and sire are valid mating pair
        require(
            _ownerPermittedToBreed(msgSender, _matronId, _sireId),
            "CryptoAlpaca: Invalid permission"
        );

        // Grab a reference to the potential matron
        Alpaca storage matron = alpacas[_matronId];

        // Make sure matron isn't pregnant, or in the middle of a siring cooldown
        require(
            _isReadyToHatch(matron),
            "CryptoAlpaca: Matron is not yet ready to hatch"
        );

        // Grab a reference to the potential sire
        Alpaca storage sire = alpacas[_sireId];

        // Make sure sire isn't pregnant, or in the middle of a siring cooldown
        require(
            _isReadyToHatch(sire),
            "CryptoAlpaca: Sire is not yet ready to hatch"
        );

        // Test that matron and sire are a valid mating pair.
        require(
            _isValidMatingPair(matron, _matronId, sire, _sireId),
            "CryptoAlpaca: Matron and Sire are not valid mating pair"
        );

        // All checks passed, Alpaca gets pregnant!
        return _hatchEgg(_matronId, _sireId);
    }

    /**
     * @dev egg is ready to crack and give life to baby alpaca!
     * @param _id A Alpaca egg that's ready to crack.
     */
    function crack(uint256 _id) external override nonReentrant {
        // Grab a reference to the egg in storage.
        Alpaca storage egg = alpacas[_id];

        // Check that the egg is a valid alpaca.
        require(egg.birthTime != 0, "CryptoAlpaca: not valid egg");
        require(
            egg.state == AlpacaGrowthState.EGG,
            "CryptoAlpaca: not a valid egg"
        );

        // Check that the matron is pregnant, and that its time has come!
        require(_isReadyToCrack(egg), "CryptoAlpaca: egg cant be cracked yet");

        // Grab a reference to the sire in storage.
        Alpaca storage matron = alpacas[egg.matronId];
        Alpaca storage sire = alpacas[egg.sireId];

        // Call the sooper-sekret gene mixing operation.
        (
            uint256 childGene,
            uint256 childEnergy,
            uint256 generationFactor
        ) = geneScience.mixGenes(
            matron.gene,
            sire.gene,
            egg.generation,
            uint256(egg.cooldownEndBlock).sub(1)
        );

        egg.gene = childGene;
        egg.energy = uint32(childEnergy);
        egg.state = AlpacaGrowthState.GROWN;
        egg.cooldownEndBlock = uint64(
            (newBornCoolDown.div(secondsPerBlock)).add(block.number)
        );
        egg.generationFactor = uint64(generationFactor);

        // Send the balance fee to the person who made birth happen.
        if (autoCrackingFee > 0) {
            msg.sender.transfer(autoCrackingFee);
        }

        // emit the born event
        emit BornSingle(_id, childGene, childEnergy);
    }

    /* ========== PRIVATE FUNCTION ========== */

    /**
     * @dev Recalculate the hatchingCostMultiplier for alpaca after breed.
     * If hatchCostMultiplierEndBlock is less than current block number
     * reset hatchingCostMultiplier back to 2, otherwize multiply hatchingCostMultiplier by 2. Also update
     * hatchCostMultiplierEndBlock.
     */
    function _refreshHatchingMultiplier(Alpaca storage _alpaca) private {
        if (_alpaca.hatchCostMultiplierEndBlock < block.number) {
            _alpaca.hatchingCostMultiplier = 2;
        } else {
            uint16 newMultiplier = _alpaca.hatchingCostMultiplier * 2;
            if (newMultiplier > maxHatchCostMultiplier) {
                newMultiplier = maxHatchCostMultiplier;
            }

            _alpaca.hatchingCostMultiplier = newMultiplier;
        }
        _alpaca.hatchCostMultiplierEndBlock = uint64(
            (hatchingMultiplierCoolDown.div(secondsPerBlock)).add(block.number)
        );
    }

    function _ownerPermittedToBreed(
        address _sender,
        uint256 _matronId,
        uint256 _sireId
    ) private view returns (bool) {
        // owner must own matron, othersize not permitted
        if (!isOwnerOf(_sender, _matronId)) {
            return false;
        }

        // if owner owns sire, it's permitted
        if (isOwnerOf(_sender, _sireId)) {
            return true;
        }

        // if sire's owner has given permission to _sender to breed,
        // then it's permitted to breed
        if (alpacaAllowedToAddress.contains(_sireId)) {
            return alpacaAllowedToAddress.get(_sireId) == _sender;
        }

        return false;
    }

    /**
     * @dev Checks that a given alpaca is able to breed. Requires that the
     * current cooldown is finished (for sires) and also checks that there is
     * no pending pregnancy.
     */
    function _isReadyToHatch(Alpaca storage _alpaca)
        private
        view
        returns (bool)
    {
        return
            (_alpaca.state == AlpacaGrowthState.GROWN) &&
            (_alpaca.cooldownEndBlock < uint64(block.number));
    }

    /**
     * @dev Checks to see if a given alpaca is pregnant and (if so) if the gestation
     * period has passed.
     */

    function _isReadyToCrack(Alpaca storage _egg) private view returns (bool) {
        return
            (_egg.state == AlpacaGrowthState.EGG) &&
            (_egg.cooldownEndBlock < uint64(block.number));
    }

    /**
     * @dev Calculating breeding ALPA cost for internal usage.
     */
    function _hatchingALPACost(
        uint256 _matronId,
        uint256 _sireId,
        bool _strict
    ) private view returns (uint256) {
        uint256 blockNum = block.number;
        if (!_strict) {
            blockNum = blockNum + 1;
        }

        Alpaca storage sire = alpacas[_sireId];
        uint256 sireHatchingBase = _getBaseHatchingCost(sire.generation);
        uint256 sireMultiplier = sire.hatchingCostMultiplier;
        if (sire.hatchCostMultiplierEndBlock < blockNum) {
            sireMultiplier = 1;
        }

        Alpaca storage matron = alpacas[_matronId];
        uint256 matronHatchingBase = _getBaseHatchingCost(matron.generation);
        uint256 matronMultiplier = matron.hatchingCostMultiplier;
        if (matron.hatchCostMultiplierEndBlock < blockNum) {
            matronMultiplier = 1;
        }

        return
            (sireHatchingBase.mul(sireMultiplier)).add(
                matronHatchingBase.mul(matronMultiplier)
            );
    }

    /**
     * @dev Internal utility function to initiate hatching egg, assumes that all breeding
     *  requirements have been checked.
     */
    function _hatchEgg(uint256 _matronId, uint256 _sireId)
        private
        returns (uint256)
    {
        // Transfer birthing ALPA fee to this contract
        uint256 alpaCost = _hatchingALPACost(_matronId, _sireId, true);

        uint256 devAmount = alpaCost.mul(devBreedingPercentage).div(100);
        uint256 stakingAmount = alpaCost.mul(100 - devBreedingPercentage).div(
            100
        );

        assert(alpa.transferFrom(msg.sender, devAddress, devAmount));
        assert(alpa.transferFrom(msg.sender, stakingAddress, stakingAmount));

        // Grab a reference to the Alpacas from storage.
        Alpaca storage sire = alpacas[_sireId];
        Alpaca storage matron = alpacas[_matronId];

        // refresh hatching multiplier for both parents.
        _refreshHatchingMultiplier(sire);
        _refreshHatchingMultiplier(matron);

        // Determine the lower generation number of the two parents
        uint256 parentGen = matron.generation;
        if (sire.generation < matron.generation) {
            parentGen = sire.generation;
        }

        // child generation will be 1 larger than min of the two parents generation;
        uint256 childGen = parentGen.add(1);

        // Determine when the egg will be cracked
        uint256 cooldownEndBlock = (hatchingDuration.div(secondsPerBlock)).add(
            block.number
        );

        uint256 eggID = _createEgg(
            _matronId,
            _sireId,
            childGen,
            cooldownEndBlock,
            msg.sender
        );

        // Emit the hatched event.
        emit Hatched(eggID, _matronId, _sireId, cooldownEndBlock);

        return eggID;
    }

    /**
     * @dev Internal check to see if a given sire and matron are a valid mating pair.
     * @param _matron A reference to the Alpaca struct of the potential matron.
     * @param _matronId The matron's ID.
     * @param _sire A reference to the Alpaca struct of the potential sire.
     * @param _sireId The sire's ID
     */
    function _isValidMatingPair(
        Alpaca storage _matron,
        uint256 _matronId,
        Alpaca storage _sire,
        uint256 _sireId
    ) private view returns (bool) {
        // A Aapaca can't breed with itself
        if (_matronId == _sireId) {
            return false;
        }

        // Alpaca can't breed with their parents.
        if (_matron.matronId == _sireId || _matron.sireId == _sireId) {
            return false;
        }
        if (_sire.matronId == _matronId || _sire.sireId == _matronId) {
            return false;
        }

        return true;
    }

    /**
     * @dev openzeppelin ERC1155 Hook that is called before any token transfer
     * Clear any alpacaAllowedToAddress associated to the alpaca
     * that's been transfered
     */
    function _beforeTokenTransfer(
        address,
        address,
        address,
        uint256[] memory ids,
        uint256[] memory,
        bytes memory
    ) internal virtual override {
        for (uint256 i = 0; i < ids.length; i++) {
            if (alpacaAllowedToAddress.contains(ids[i])) {
                alpacaAllowedToAddress.remove(ids[i]);
            }
        }
    }
}


// Dependency file: contracts/CryptoAlpaca/AlpacaOperator.sol


// pragma solidity =0.6.12;

// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// import "@openzeppelin/contracts/introspection/IERC165.sol";
// import "@openzeppelin/contracts/utils/Address.sol";
// import "contracts/interfaces/IGeneScience.sol";
// import "contracts/interfaces/ICryptoAlpacaEnergyListener.sol";
// import "contracts/CryptoAlpaca/AlpacaBreed.sol";

contract AlpacaOperator is AlpacaBreed {
    using Address for address;

    address public operator;

    /*
     * bytes4(keccak256('onCryptoAlpacaEnergyChanged(uint256,uint256,uint256)')) == 0x5a864e1c
     */
    bytes4
        private constant _INTERFACE_ID_CRYPTO_ALPACA_ENERGY_LISTENER = 0x5a864e1c;

    /* ========== EVENTS ========== */

    /**
     * @dev Event for when alpaca's energy changed from `fromEnergy`
     */
    event EnergyChanged(
        uint256 indexed id,
        uint256 oldEnergy,
        uint256 newEnergy
    );

    /* ========== OPERATOR ONLY FUNCTION ========== */

    function updateAlpacaEnergy(
        address _owner,
        uint256 _id,
        uint32 _newEnergy
    ) external onlyOperator nonReentrant {
        require(_newEnergy > 0, "CryptoAlpaca: invalid energy");

        require(
            isOwnerOf(_owner, _id),
            "CryptoAlpaca: alpaca does not belongs to owner"
        );

        Alpaca storage thisAlpaca = alpacas[_id];
        uint32 oldEnergy = thisAlpaca.energy;
        thisAlpaca.energy = _newEnergy;

        emit EnergyChanged(_id, oldEnergy, _newEnergy);
        _doSafeEnergyChangedAcceptanceCheck(_owner, _id, oldEnergy, _newEnergy);
    }

    /**
     * @dev Transfers operator role to different address
     * Can only be called by the current operator.
     */
    function transferOperator(address _newOperator) external onlyOperator {
        require(
            _newOperator != address(0),
            "CryptoAlpaca: new operator is the zero address"
        );
        operator = _newOperator;
    }

    /* ========== MODIFIERS ========== */

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

    /* =========== PRIVATE ========= */

    function _doSafeEnergyChangedAcceptanceCheck(
        address _to,
        uint256 _id,
        uint256 _oldEnergy,
        uint256 _newEnergy
    ) private {
        if (_to.isContract()) {
            if (
                IERC165(_to).supportsInterface(
                    _INTERFACE_ID_CRYPTO_ALPACA_ENERGY_LISTENER
                )
            ) {
                ICryptoAlpacaEnergyListener(_to).onCryptoAlpacaEnergyChanged(
                    _id,
                    _oldEnergy,
                    _newEnergy
                );
            }
        }
    }
}


// Root file: contracts/CryptoAlpaca/AlpacaCore.sol


pragma solidity =0.6.12;

// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// import "contracts/interfaces/IGeneScience.sol";
// import "contracts/CryptoAlpaca/AlpacaOperator.sol";

contract AlpacaCore is AlpacaOperator {
    /**
     * @dev Initializes crypto alpaca contract.
     * @param _alpa ALPA ERC20 contract address
     * @param _devAddress dev address.
     * @param _stakingAddress staking address.
     */
    constructor(
        IERC20 _alpa,
        IGeneScience _geneScience,
        address _operator,
        address _devAddress,
        address _stakingAddress
    ) public {
        alpa = _alpa;
        geneScience = _geneScience;
        operator = _operator;
        devAddress = _devAddress;
        stakingAddress = _stakingAddress;

        // start with the mythical genesis alpaca
        _createGen0Alpaca(uint256(-1), 0, msg.sender);
    }

    /* ========== OWNER MUTATIVE FUNCTION ========== */

    /**
     * @dev Allows owner to withdrawal the balance available to the contract.
     */
    function withdrawBalance(uint256 _amount, address payable _to)
        external
        onlyOwner
    {
        _to.transfer(_amount);
    }

    /**
     * @dev pause crypto alpaca contract stops any further hatching.
     */
    function pause() external onlyOwner {
        _pause();
    }

    /**
     * @dev unpause crypto alpaca contract.
     */
    function unpause() external onlyOwner {
        _unpause();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IERC20","name":"_alpa","type":"address"},{"internalType":"contract IGeneScience","name":"_geneScience","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_devAddress","type":"address"},{"internalType":"address","name":"_stakingAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","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":"uint256[]","name":"alpacaIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"genes","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"energy","type":"uint256[]"}],"name":"BornBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"alpacaId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gene","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"energy","type":"uint256"}],"name":"BornSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldEnergy","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newEnergy","type":"uint256"}],"name":"EnergyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"alpacaId","type":"uint256"},{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"GrantedToBreed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"eggId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"matronId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sireId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"cooldownEndBlock","type":"uint256"}],"name":"Hatched","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"GEN0_GENERATION_FACTOR","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GEN0_ENERGY","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"alpa","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoCrackingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseHatchingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_alpacaId","type":"uint256"}],"name":"clearPermissionToBreed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"crack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gene","type":"uint256"},{"internalType":"uint256","name":"_energy","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"name":"createGen0Alpaca","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_genes","type":"uint256[]"},{"internalType":"uint256[]","name":"_energies","type":"uint256[]"},{"internalType":"address","name":"_owner","type":"address"}],"name":"createGen0AlpacaBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devBreedingPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"geneScience","outputs":[{"internalType":"contract IGeneScience","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"generationHatchingFeeMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getAlpaca","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isReady","type":"bool"},{"internalType":"uint256","name":"cooldownEndBlock","type":"uint256"},{"internalType":"uint256","name":"birthTime","type":"uint256"},{"internalType":"uint256","name":"matronId","type":"uint256"},{"internalType":"uint256","name":"sireId","type":"uint256"},{"internalType":"uint256","name":"hatchingCost","type":"uint256"},{"internalType":"uint256","name":"hatchingCostMultiplier","type":"uint256"},{"internalType":"uint256","name":"hatchCostMultiplierEndBlock","type":"uint256"},{"internalType":"uint256","name":"generation","type":"uint256"},{"internalType":"uint256","name":"gene","type":"uint256"},{"internalType":"uint256","name":"energy","type":"uint256"},{"internalType":"uint256","name":"state","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAlpaca","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_sireId","type":"uint256"}],"name":"grandPermissionToBreed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"hasPermissionToBreedAsSire","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_matronId","type":"uint256"},{"internalType":"uint256","name":"_sireId","type":"uint256"}],"name":"hatch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_matronId","type":"uint256"},{"internalType":"uint256","name":"_sireId","type":"uint256"}],"name":"hatchingALPACost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hatchingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hatchingMultiplierCoolDown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_alpacaId","type":"uint256"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isReadyToCrack","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxHatchCostMultiplier","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newBornCoolDown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondsPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_alpa","type":"address"}],"name":"setAlpaContract","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":"uint256","name":"_autoCrackingFee","type":"uint256"}],"name":"setAutoCrackingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_baseHatchingFee","type":"uint256"}],"name":"setBaseHatchingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_devAddress","type":"address"}],"name":"setDevAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_devBreedingPercentage","type":"uint256"}],"name":"setDevBreedingPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGeneScience","name":"_geneScience","type":"address"}],"name":"setGeneScience","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_generationHatchingFeeMultiplier","type":"uint256"}],"name":"setGenerationHatchingFeeMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_hatchingDuration","type":"uint256"}],"name":"setHatchingDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_hatchingMultiplierCoolDown","type":"uint256"}],"name":"setHatchingMultiplierCoolDown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_maxHatchCostMultiplier","type":"uint16"}],"name":"setMaxHatchCostMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newBornCoolDown","type":"uint256"}],"name":"setNewBornCoolDown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_secs","type":"uint256"}],"name":"setSecondsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingAddress","type":"address"}],"name":"setStakingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newuri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"transferOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint32","name":"_newEnergy","type":"uint32"}],"name":"updateAlpacaEnergy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_to","type":"address"}],"name":"withdrawBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600155678ac7230489e800006002908155600a6006819055600f6007556201518060085561012c6009556154609055600b805461ffff19166010179055600c553480156200005357600080fd5b506040516200684638038062006846833981810160405260a08110156200007957600080fd5b50805160208083015160408085015160608601516080909601518251948501909252600080855294959294909390620000b1620001c3565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506200010d6301ffc9a760e01b620001c8565b62000118816200024d565b6200012a636cdb3d1360e11b620001c8565b6200013c6303a24d0760e21b620001c8565b50600160155560168054600380546001600160a01b03199081166001600160a01b038a811691909117909255600d805482168984161790556001600160a81b0319909216610100878316021790925560048054821685841617905560058054909116918316919091179055620001b760001960003362000266565b50505050505062000cfe565b335b90565b6001600160e01b0319808216141562000228576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152601160205260409020805460ff19166001179055565b80516200026290601490602084019062000b52565b5050565b6000610e10831115620002c0576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b620002ca62000bd7565b604080516101608101825286815263ffffffff861660208201526001600160401b0342169181019190915260006060820181905260016080830181905260a0830182905260c0830182905260e08301829052610100830191909152600a610120830152610140820152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff98891617600160201b600160601b0319166401000000006001600160401b039687160217600160601b600160a01b0319166c01000000000000000000000000948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff90930180546101208701516001600160401b031990911694831694909417600160401b600160801b031916680100000000000000009490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b9084908111156200050357fe5b021790555050600e54604080516020810190915260008152600019909101915062000535908590839060019062000578565b6040805187815260208101879052815183927f41ef5b80fa5aaaea22ba4396c76c6e35b7de2e2d4c1bbcdf0bef9db3809105b4928290030190a295945050505050565b6001600160a01b038416620005bf5760405162461bcd60e51b8152600401808060200182810382526021815260200180620068256021913960400191505060405180910390fd5b6000620005cb620001c3565b9050620005f281600087620005e088620006a7565b620005eb88620006a7565b87620006ec565b60008481526012602090815260408083206001600160a01b03891684528252909120546200062b918590620033d062000771821b17901c565b60008581526012602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a4620006a081600087878787620007d5565b5050505050565b604080516001808252818301909252606091829190602080830190803683370190505090508281600081518110620006db57fe5b602090810291909101015292915050565b60005b83518110156200076857620007288482815181106200070a57fe5b6020026020010151600f62000a3460201b6200342a1790919060201c565b156200075f576200075d8482815181106200073f57fe5b6020026020010151600f62000a4260201b620034361790919060201c565b505b600101620006ef565b50505050505050565b600082820183811015620007cc576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b620007f4846001600160a01b031662000a5060201b620034421760201c565b1562000a2c57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015620008865781810151838201526020016200086c565b50505050905090810190601f168015620008b45780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b158015620008d857600080fd5b505af1925050508015620008ff57506040513d6020811015620008fa57600080fd5b505160015b620009db576200090e62000c4e565b806200091b5750620009a3565b8060405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620009675781810151838201526020016200094d565b50505050905090810190601f168015620009955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60405162461bcd60e51b8152600401808060200182810382526034815260200180620067c96034913960400191505060405180910390fd5b6001600160e01b0319811663f23a6e6160e01b14620007685760405162461bcd60e51b8152600401808060200182810382526028815260200180620067fd6028913960400191505060405180910390fd5b505050505050565b6000620007cc838362000a56565b6000620007cc838362000a6e565b3b151590565b60009081526001919091016020526040902054151590565b6000818152600183016020526040812054801562000b47578354600019808301919081019060009087908390811062000aa357fe5b906000526020600020906002020190508087600001848154811062000ac457fe5b60009182526020808320845460029093020191825560019384015491840191909155835482528983019052604090209084019055865487908062000b0457fe5b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450620007cf9350505050565b6000915050620007cf565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062000b9557805160ff191683800117855562000bc5565b8280016001018555821562000bc5579182015b8281111562000bc557825182559160200191906001019062000ba8565b5062000bd392915062000c31565b5090565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290529061014082015290565b5b8082111562000bd3576000815560010162000c32565b60e01c90565b600060443d101562000c6057620001c5565b600481823e6308c379a062000c76825162000c48565b1462000c8257620001c5565b6040513d600319016004823e80513d6001600160401b03808311602484018310171562000cb35750505050620001c5565b8284019250825191508082111562000ccf5750505050620001c5565b503d8301602082840101111562000ce957505050620001c5565b601f01601f1916810160200160405291505090565b615abb8062000d0e6000396000f3fe60806040526004361061038b5760003560e01c806379e81f39116101dc578063a8b3171e11610102578063e3b212e8116100a0578063f2b47d521161006f578063f2b47d5214611253578063f2fde38b14611268578063f4e0d9ac1461129b578063faeb3f82146112ce5761038b565b8063e3b212e814611101578063e985e9c514611116578063f1d24bf214611151578063f242432a1461117d5761038b565b8063cb14382f116100dc578063cb14382f14611050578063cdeec2841461107a578063d0d41fe1146110b9578063d7b4be24146110ec5761038b565b8063a8b3171e14610fbd578063b0ea6a1b14610fed578063c5b8f772146110175761038b565b80639c1f6bf81161017a578063a05ace1511610149578063a05ace1514610f2e578063a22cb46514610f58578063a51cf95e14610f93578063a6fd95fa14610fa85761038b565b80639c1f6bf814610e8e5780639d1bd76d14610ec15780639e82767d14610eeb5780639fa5678314610f195761038b565b80638456cb59116101b65780638456cb5914610e0c57806389d7b18914610e215780638ce40a8b14610e4b5780638da5cb5b14610e795761038b565b806379e81f3914610c835780637a7d493714610cbc5780637c5269c214610cd15761038b565b8063383ad4a9116102c1578063570ca7351161025f57806369cffe961161022e57806369cffe9614610b615780636e33f31614610b9a5780636f8eec3b14610c29578063715018a614610c6e5761038b565b8063570ca73514610af857806359d6dd9d14610b0d5780635c975abb14610b225780636882f5d114610b375761038b565b80634a3d84e81161029b5780634a3d84e8146109085780634ce5d088146109395780634e1273f41461094e5780635663896e14610ace5761038b565b8063383ad4a9146108ad5780633ad10ef6146108c25780633f4ba83a146108f35761038b565b806313c5314e1161032e5780632eb2c2d6116103085780632eb2c2d61461067d5780633154fd961461084b578063328e48be1461087557806333c3d0591461088a5761038b565b806313c5314e1461060b5780631f644c851461062057806329605e771461064a5761038b565b80630ac395bf1161036a5780630ac395bf146104d65780630d22c9971461050f5780630e89341c1461054257806311c1b74f146105e15761038b565b8062fdd58e1461039057806301ffc9a7146103db57806302fe530514610423575b600080fd5b34801561039c57600080fd5b506103c9600480360360408110156103b357600080fd5b506001600160a01b0381351690602001356112f8565b60408051918252519081900360200190f35b3480156103e757600080fd5b5061040f600480360360208110156103fe57600080fd5b50356001600160e01b03191661136a565b604080519115158252519081900360200190f35b34801561042f57600080fd5b506104d46004803603602081101561044657600080fd5b810190602081018135600160201b81111561046057600080fd5b82018360208201111561047257600080fd5b803590602001918460018302840111600160201b8311171561049357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611389945050505050565b005b3480156104e257600080fd5b5061040f600480360360408110156104f957600080fd5b506001600160a01b0381351690602001356113ed565b34801561051b57600080fd5b506104d46004803603602081101561053257600080fd5b50356001600160a01b031661142c565b34801561054e57600080fd5b5061056c6004803603602081101561056557600080fd5b50356114a6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105a657818101518382015260200161058e565b50505050905090810190601f1680156105d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105ed57600080fd5b506104d46004803603602081101561060457600080fd5b503561153e565b34801561061757600080fd5b506103c961159b565b34801561062c57600080fd5b506104d46004803603602081101561064357600080fd5b50356115a1565b34801561065657600080fd5b506104d46004803603602081101561066d57600080fd5b50356001600160a01b03166115fe565b34801561068957600080fd5b506104d4600480360360a08110156106a057600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156106d357600080fd5b8201836020820111156106e557600080fd5b803590602001918460208302840111600160201b8311171561070657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561075557600080fd5b82018360208201111561076757600080fd5b803590602001918460208302840111600160201b8311171561078857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156107d757600080fd5b8201836020820111156107e957600080fd5b803590602001918460018302840111600160201b8311171561080a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116c4945050505050565b34801561085757600080fd5b506104d46004803603602081101561086e57600080fd5b50356119c7565b34801561088157600080fd5b506103c9611a24565b6103c9600480360360408110156108a057600080fd5b5080359060200135611a2a565b3480156108b957600080fd5b506103c9611d62565b3480156108ce57600080fd5b506108d7611d69565b604080516001600160a01b039092168252519081900360200190f35b3480156108ff57600080fd5b506104d4611d78565b34801561091457600080fd5b5061091d611dda565b604080516001600160401b039092168252519081900360200190f35b34801561094557600080fd5b506103c9611ddf565b34801561095a57600080fd5b50610a7e6004803603604081101561097157600080fd5b810190602081018135600160201b81111561098b57600080fd5b82018360208201111561099d57600080fd5b803590602001918460208302840111600160201b831117156109be57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a0d57600080fd5b820183602082011115610a1f57600080fd5b803590602001918460208302840111600160201b83111715610a4057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611de5945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610aba578181015183820152602001610aa2565b505050509050019250505060405180910390f35b348015610ada57600080fd5b506104d460048036036020811015610af157600080fd5b5035611f62565b348015610b0457600080fd5b506108d7611fbf565b348015610b1957600080fd5b506108d7611fd3565b348015610b2e57600080fd5b5061040f611fe2565b348015610b4357600080fd5b506104d460048036036020811015610b5a57600080fd5b5035611feb565b348015610b6d57600080fd5b506104d460048036036040811015610b8457600080fd5b506001600160a01b038135169060200135612048565b348015610ba657600080fd5b50610bc460048036036020811015610bbd57600080fd5b50356120dd565b604080519d8e529b151560208e01528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e088015261010087015261012086015261014085015261016084015261018083015251908190036101a00190f35b348015610c3557600080fd5b506104d460048036036060811015610c4c57600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff16612269565b348015610c7a57600080fd5b506104d461245d565b348015610c8f57600080fd5b506104d460048036036040811015610ca657600080fd5b50803590602001356001600160a01b03166124ff565b348015610cc857600080fd5b506103c9612592565b348015610cdd57600080fd5b506104d460048036036060811015610cf457600080fd5b810190602081018135600160201b811115610d0e57600080fd5b820183602082011115610d2057600080fd5b803590602001918460208302840111600160201b83111715610d4157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610d9057600080fd5b820183602082011115610da257600080fd5b803590602001918460208302840111600160201b83111715610dc357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505090356001600160a01b031691506125989050565b348015610e1857600080fd5b506104d461261c565b348015610e2d57600080fd5b506104d460048036036020811015610e4457600080fd5b503561267c565b348015610e5757600080fd5b50610e606126d0565b6040805163ffffffff9092168252519081900360200190f35b348015610e8557600080fd5b506108d76126d6565b348015610e9a57600080fd5b506104d460048036036020811015610eb157600080fd5b50356001600160a01b03166126e5565b348015610ecd57600080fd5b506104d460048036036020811015610ee457600080fd5b50356127ff565b348015610ef757600080fd5b506104d460048036036020811015610f0e57600080fd5b503561ffff1661285c565b348015610f2557600080fd5b506103c96128cc565b348015610f3a57600080fd5b506104d460048036036020811015610f5157600080fd5b50356128d2565b348015610f6457600080fd5b506104d460048036036040811015610f7b57600080fd5b506001600160a01b038135169060200135151561292f565b348015610f9f57600080fd5b506103c9612a1e565b348015610fb457600080fd5b506103c9612a24565b348015610fc957600080fd5b506103c960048036036040811015610fe057600080fd5b5080359060200135612a2a565b348015610ff957600080fd5b506104d46004803603602081101561101057600080fd5b5035612a3f565b34801561102357600080fd5b5061040f6004803603604081101561103a57600080fd5b506001600160a01b038135169060200135612e33565b34801561105c57600080fd5b506104d46004803603602081101561107357600080fd5b5035612e49565b34801561108657600080fd5b506104d46004803603606081101561109d57600080fd5b50803590602081013590604001356001600160a01b0316612ee8565b3480156110c557600080fd5b506104d4600480360360208110156110dc57600080fd5b50356001600160a01b0316612f65565b3480156110f857600080fd5b506108d7612fdb565b34801561110d57600080fd5b506103c9612fea565b34801561112257600080fd5b5061040f6004803603604081101561113957600080fd5b506001600160a01b0381358116916020013516612ff0565b34801561115d57600080fd5b5061116661301e565b6040805161ffff9092168252519081900360200190f35b34801561118957600080fd5b506104d4600480360360a08110156111a057600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b8111156111df57600080fd5b8201836020820111156111f157600080fd5b803590602001918460018302840111600160201b8311171561121257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613028945050505050565b34801561125f57600080fd5b506108d76131f3565b34801561127457600080fd5b506104d46004803603602081101561128b57600080fd5b50356001600160a01b0316613202565b3480156112a757600080fd5b506104d4600480360360208110156112be57600080fd5b50356001600160a01b03166132fa565b3480156112da57600080fd5b5061040f600480360360208110156112f157600080fd5b5035613374565b60006001600160a01b03831661133f5760405162461bcd60e51b815260040180806020018281038252602b815260200180615683602b913960400191505060405180910390fd5b5060008181526012602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526011602052604090205460ff1690565b611391613448565b6000546001600160a01b039081169116146113e1576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6113ea8161344c565b50565b60006113f98383612e33565b1561140657506001611364565b6001600160a01b03831661141b600f8461345f565b6001600160a01b0316149392505050565b611434613448565b6000546001600160a01b03908116911614611484576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60148054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156115325780601f1061150757610100808354040283529160200191611532565b820191906000526020600020905b81548152906001019060200180831161151557829003601f168201915b50505050509050919050565b611546613448565b6000546001600160a01b03908116911614611596576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600c55565b60095481565b6115a9613448565b6000546001600160a01b039081169116146115f9576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600955565b611606613448565b60165461010090046001600160a01b039081169116146116575760405162461bcd60e51b81526004018080602001828103825260288152602001806155ff6028913960400191505060405180910390fd5b6001600160a01b03811661169c5760405162461bcd60e51b815260040180806020018281038252602e815260200180615655602e913960400191505060405180910390fd5b601680546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b81518351146117045760405162461bcd60e51b8152600401808060200182810382526028815260200180615a3d6028913960400191505060405180910390fd5b6001600160a01b0384166117495760405162461bcd60e51b81526004018080602001828103825260258152602001806157846025913960400191505060405180910390fd5b611751613448565b6001600160a01b0316856001600160a01b0316148061177c575061177c85611777613448565b612ff0565b6117b75760405162461bcd60e51b81526004018080602001828103825260328152602001806157a96032913960400191505060405180910390fd5b60006117c1613448565b90506117d181878787878761346b565b60005b84518110156118d75760008582815181106117eb57fe5b60200260200101519050600085838151811061180357fe5b60200260200101519050611870816040518060600160405280602a81526020016158a4602a91396012600086815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020546134dd9092919063ffffffff16565b60008381526012602090815260408083206001600160a01b038e811685529252808320939093558a16815220546118a790826133d0565b60009283526012602090815260408085206001600160a01b038c16865290915290922091909155506001016117d4565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561195d578181015183820152602001611945565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561199c578181015183820152602001611984565b5050505090500194505050505060405180910390a46119bf818787878787613574565b505050505050565b6119cf613448565b6000546001600160a01b03908116911614611a1f576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600855565b600a5481565b60165460009060ff1615611a78576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60026015541415611ad0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026015556001543390341015611b185760405162461bcd60e51b815260040180806020018281038252602f81526020018061595d602f913960400191505060405180910390fd5b611b24848460016137ea565b60035460408051636eb1769f60e11b81526001600160a01b0385811660048301523060248301529151919092169163dd62ed3e916044808301926020929190829003018186803b158015611b7757600080fd5b505afa158015611b8b573d6000803e3d6000fd5b505050506040513d6020811015611ba157600080fd5b50511015611be05760405162461bcd60e51b815260040180806020018281038252603181526020018061582e6031913960400191505060405180910390fd5b611beb8185856138f0565b611c3c576040805162461bcd60e51b815260206004820181905260248201527f43727970746f416c706163613a20496e76616c6964207065726d697373696f6e604482015290519081900360640190fd5b6000600e8581548110611c4b57fe5b90600052602060002090600302019050611c648161395f565b611c9f5760405162461bcd60e51b815260040180806020018281038252602e815260200180615627602e913960400191505060405180910390fd5b6000600e8581548110611cae57fe5b90600052602060002090600302019050611cc78161395f565b611d025760405162461bcd60e51b815260040180806020018281038252602c81526020018061572e602c913960400191505060405180910390fd5b611d0e8287838861399c565b611d495760405162461bcd60e51b81526004018080602001828103825260378152602001806159de6037913960400191505060405180910390fd5b611d538686613a32565b60016015559695505050505050565b600e545b90565b6004546001600160a01b031681565b611d80613448565b6000546001600160a01b03908116911614611dd0576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b611dd8613cc4565b565b600a81565b60065481565b60608151835114611e275760405162461bcd60e51b81526004018080602001828103825260298152602001806159b56029913960400191505060405180910390fd5b606083516001600160401b0381118015611e4057600080fd5b50604051908082528060200260200182016040528015611e6a578160200160208202803683370190505b50905060005b8451811015611f5a5760006001600160a01b0316858281518110611e9057fe5b60200260200101516001600160a01b03161415611ede5760405162461bcd60e51b81526004018080602001828103825260318152602001806156ae6031913960400191505060405180910390fd5b60126000858381518110611eee57fe5b602002602001015181526020019081526020016000206000868381518110611f1257fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611f4757fe5b6020908102919091010152600101611e70565b509392505050565b611f6a613448565b6000546001600160a01b03908116911614611fba576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600755565b60165461010090046001600160a01b031681565b6003546001600160a01b031681565b60165460ff1690565b611ff3613448565b6000546001600160a01b03908116911614612043576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600155565b6120523382612e33565b61208d5760405162461bcd60e51b8152600401808060200182810382526028815260200180615a156028913960400191505060405180910390fd5b612099600f8284613d62565b50604080516001600160a01b0384168152905182917f3a4b868f54c9e39494d33bc09f2562f925681d3acef65a3e7b2284f8b9845220919081900360200190a25050565b600080600080600080600080600080600080600080600e8f815481106120ff57fe5b906000526020600020906003020190508e9d50438160020160009054906101000a90046001600160401b03166001600160401b031611159c508060020160009054906101000a90046001600160401b03166001600160401b03169b508060010160049054906101000a90046001600160401b03166001600160401b03169a508060010160169054906101000a900463ffffffff1663ffffffff16995080600101601a9054906101000a900463ffffffff1663ffffffff1698506121d781600101601e9054906101000a900461ffff1661ffff16613d78565b6001820154909850600160a01b810461ffff16975043600160601b9091046001600160401b03161161220857600196505b60018181015482546002840154600160601b83046001600160401b03169950600160f01b830461ffff16985090965063ffffffff9091169450600160801b900460ff169081111561225557fe5b91505091939597999b9d90929496989a9c50565b612271613448565b60165461010090046001600160a01b039081169116146122c25760405162461bcd60e51b81526004018080602001828103825260288152602001806155ff6028913960400191505060405180910390fd5b6002601554141561231a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260155563ffffffff8116612377576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b6123818383612e33565b6123bc5760405162461bcd60e51b815260040180806020018281038252602e815260200180615581602e913960400191505060405180910390fd5b6000600e83815481106123cb57fe5b60009182526020918290206003919091020160018101805463ffffffff19811663ffffffff878116918217909355604080519390921680845294830152805192945086927ff39159b02e5738f08489b315416eaf67d250b11089fdfe6271af951e461a83709281900390910190a261245185858363ffffffff168663ffffffff16613dad565b50506001601555505050565b612465613448565b6000546001600160a01b039081169116146124b5576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b612507613448565b6000546001600160a01b03908116911614612557576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561258d573d6000803e3d6000fd5b505050565b60075481565b6125a0613448565b6000546001600160a01b039081169116146125f0576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b03811661260a576126076126d6565b90505b612615848484613eb7565b5050505050565b612624613448565b6000546001600160a01b03908116911614612674576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b611dd861440e565b6126863382612e33565b6126c15760405162461bcd60e51b81526004018080602001828103825260288152602001806155af6028913960400191505060405180910390fd5b6126cc600f82613436565b5050565b610e1081565b6000546001600160a01b031690565b6126ed613448565b6000546001600160a01b0390811691161461273d576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b031663c2f5ddc56040518163ffffffff1660e01b815260040160206040518083038186803b15801561277657600080fd5b505afa15801561278a573d6000803e3d6000fd5b505050506040513d60208110156127a057600080fd5b50516127dd5760405162461bcd60e51b815260040180806020018281038252602b815260200180615932602b913960400191505060405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b612807613448565b6000546001600160a01b03908116911614612857576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600a55565b612864613448565b6000546001600160a01b039081169116146128b4576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600b805461ffff191661ffff92909216919091179055565b60025481565b6128da613448565b6000546001600160a01b0390811691161461292a576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600255565b816001600160a01b0316612941613448565b6001600160a01b031614156129875760405162461bcd60e51b815260040180806020018281038252602981526020018061598c6029913960400191505060405180910390fd5b8060136000612994613448565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556129d8613448565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600c5481565b60085481565b6000612a38838360006137ea565b9392505050565b60026015541415612a97576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026015819055506000600e8281548110612aae57fe5b600091825260209091206003909102016001810154909150600160201b90046001600160401b0316612b27576040805162461bcd60e51b815260206004820152601b60248201527f43727970746f416c706163613a206e6f742076616c6964206567670000000000604482015290519081900360640190fd5b60006002820154600160801b900460ff166001811115612b4357fe5b14612b95576040805162461bcd60e51b815260206004820152601d60248201527f43727970746f416c706163613a206e6f7420612076616c696420656767000000604482015290519081900360640190fd5b612b9e8161448f565b612bd95760405162461bcd60e51b81526004018080602001828103825260258152602001806157db6025913960400191505060405180910390fd5b6001810154600e8054600092600160b01b900463ffffffff16908110612bfb57fe5b906000526020600020906003020190506000600e83600101601a9054906101000a900463ffffffff1663ffffffff1681548110612c3457fe5b600091825260208220600d5485546003909302909101805460018881015460028a0154939750869586956001600160a01b0316946344b3b11b949193919261ffff600160f01b9091041691612c92916001600160401b031690614497565b6040518563ffffffff1660e01b8152600401808581526020018481526020018361ffff16815260200182815260200194505050505060606040518083038186803b158015612cdf57600080fd5b505afa158015612cf3573d6000803e3d6000fd5b505050506040513d6060811015612d0957600080fd5b50805160208201516040909201518189556001808a01805463ffffffff191663ffffffff861617905560028a018054939750939550909350919060ff60801b1916600160801b830217905550612d7643612d706007546008546144d990919063ffffffff16565b906133d0565b60028701805467ffffffffffffffff19166001600160401b039283161767ffffffffffffffff60401b1916600160401b9284169290920291909117905560015415612deb57600154604051339180156108fc02916000818181858888f19350505050158015612de9573d6000803e3d6000fd5b505b6040805184815260208101849052815189927f41ef5b80fa5aaaea22ba4396c76c6e35b7de2e2d4c1bbcdf0bef9db3809105b4928290030190a2505060016015555050505050565b6000612e3f83836112f8565b6001149392505050565b612e51613448565b6000546001600160a01b03908116911614612ea1576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b60646006541115612ee35760405162461bcd60e51b815260040180806020018281038252604581526020018061585f6045913960600191505060405180910390fd5b600655565b612ef0613448565b6000546001600160a01b03908116911614612f40576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b038116612f5a57612f576126d6565b90505b61261584848361451b565b612f6d613448565b6004546001600160a01b03908116911614612fb95760405162461bcd60e51b815260040180806020018281038252602381526020018061590f6023913960400191505060405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031681565b60015481565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205460ff1690565b600b5461ffff1681565b6001600160a01b03841661306d5760405162461bcd60e51b81526004018080602001828103825260258152602001806157846025913960400191505060405180910390fd5b613075613448565b6001600160a01b0316856001600160a01b0316148061309b575061309b85611777613448565b6130d65760405162461bcd60e51b81526004018080602001828103825260298152602001806157056029913960400191505060405180910390fd5b60006130e0613448565b90506131008187876130f18861481d565b6130fa8861481d565b8761346b565b613147836040518060600160405280602a81526020016158a4602a913960008781526012602090815260408083206001600160a01b038d16845290915290205491906134dd565b60008581526012602090815260408083206001600160a01b038b8116855292528083209390935587168152205461317e90846133d0565b60008581526012602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46119bf818787878787614861565b600d546001600160a01b031681565b61320a613448565b6000546001600160a01b0390811691161461325a576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6001600160a01b03811661329f5760405162461bcd60e51b81526004018080602001828103825260268152602001806156df6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b613302613448565b6000546001600160a01b03908116911614613352576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b600080600e838154811061338457fe5b60009182526020822060039091020191506002820154600160801b900460ff1660018111156133af57fe5b148015612a385750600201546001600160401b034381169116111592915050565b600082820183811015612a38576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000612a3883836149d2565b6000612a3883836149ea565b3b151590565b3390565b80516126cc9060149060208401906153b5565b6000612a388383614ac8565b60005b83518110156134d45761349e84828151811061348657fe5b6020026020010151600f61342a90919063ffffffff16565b156134cc576134ca8482815181106134b257fe5b6020026020010151600f61343690919063ffffffff16565b505b60010161346e565b50505050505050565b6000818484111561356c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613531578181015183820152602001613519565b50505050905090810190601f16801561355e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b613586846001600160a01b0316613442565b156119bf57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156136145781810151838201526020016135fc565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561365357818101518382015260200161363b565b50505050905001848103825285818151815260200191508051906020019080838360005b8381101561368f578181015183820152602001613677565b50505050905090810190601f1680156136bc5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1580156136e157600080fd5b505af192505050801561370657506040513d602081101561370157600080fd5b505160015b61379b576137126154a8565b8061371d5750613764565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315613531578181015183820152602001613519565b60405162461bcd60e51b815260040180806020018281038252603481526020018061554d6034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b146134d45760405162461bcd60e51b81526004018080602001828103825260288152602001806155d76028913960400191505060405180910390fd5b600043826137f6576001015b6000600e858154811061380557fe5b60009182526020822060039190910201600181015490925061383190600160f01b900461ffff16613d78565b6001830154909150600160a01b810461ffff1690600160601b90046001600160401b0316841115613860575060015b6000600e898154811061386f57fe5b60009182526020822060039190910201600181015490925061389b90600160f01b900461ffff16613d78565b6001830154909150600160a01b810461ffff1690600160601b90046001600160401b03168711156138ca575060015b6138e16138d78383614b0a565b612d708787614b0a565b9b9a5050505050505050505050565b60006138fc8484612e33565b61390857506000612a38565b6139128483612e33565b1561391f57506001612a38565b61392a600f8361342a565b15613955576001600160a01b038416613944600f8461345f565b6001600160a01b0316149050612a38565b5060009392505050565b600060015b6002830154600160801b900460ff16600181111561397e57fe5b148015611364575050600201546001600160401b0343811691161090565b6000818414156139ae57506000613a2a565b6001850154600160b01b900463ffffffff168214806139dd57506001850154600160d01b900463ffffffff1682145b156139ea57506000613a2a565b6001830154600160b01b900463ffffffff16841480613a1957506001830154600160d01b900463ffffffff1684145b15613a2657506000613a2a565b5060015b949350505050565b600080613a41848460016137ea565b90506000613a656064613a5f60065485614b0a90919063ffffffff16565b906144d9565b90506000613a866064613a5f60065460640386614b0a90919063ffffffff16565b60035460048054604080516323b872dd60e01b815233938101939093526001600160a01b0391821660248401526044830187905251939450909116916323b872dd916064808201926020929091908290030181600087803b158015613aea57600080fd5b505af1158015613afe573d6000803e3d6000fd5b505050506040513d6020811015613b1457600080fd5b5051613b1c57fe5b600354600554604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101859052905191909216916323b872dd9160648083019260209291908290030181600087803b158015613b7b57600080fd5b505af1158015613b8f573d6000803e3d6000fd5b505050506040513d6020811015613ba557600080fd5b5051613bad57fe5b6000600e8681548110613bbc57fe5b906000526020600020906003020190506000600e8881548110613bdb57fe5b90600052602060002090600302019050613bf482614b63565b613bfd81614b63565b6001808201549083015461ffff600160f01b9283900481169290910416811115613c3357506001820154600160f01b900461ffff165b6000613c408260016133d0565b90506000613c5f43612d706007546009546144d990919063ffffffff16565b90506000613c708c8c858533614c32565b604080518e8152602081018e9052808201859052905191925082917fe5319461929da8fd31411cd6242ec17e2adddf5de0053f228fba15aff76f53bd9181900360600190a29b9a5050505050505050505050565b60165460ff16613d12576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6016805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa613d45613448565b604080516001600160a01b039092168252519081900360200190a1565b6000613a2a84846001600160a01b038516614edd565b6000611364613da4670de0b6b3a7640000613d9e600c5486614b0a90919063ffffffff16565b90614b0a565b600254906133d0565b613dbf846001600160a01b0316613442565b15613eb157604080516301ffc9a760e01b81526316a1938760e21b600482015290516001600160a01b038616916301ffc9a7916024808301926020929190829003018186803b158015613e1157600080fd5b505afa158015613e25573d6000803e3d6000fd5b505050506040513d6020811015613e3b57600080fd5b505115613eb157836001600160a01b0316635a864e1c8484846040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050600060405180830381600087803b158015613e9857600080fd5b505af1158015613eac573d6000803e3d6000fd5b505050505b50505050565b60606000845111613ef95760405162461bcd60e51b815260040180806020018281038252602a81526020018061575a602a913960400191505060405180910390fd5b8251845114613f395760405162461bcd60e51b815260040180806020018281038252602e815260200180615800602e913960400191505060405180910390fd5b600e5484516060906001600160401b0381118015613f5657600080fd5b50604051908082528060200260200182016040528015613f80578160200160208202803683370190505b509050606086516001600160401b0381118015613f9c57600080fd5b50604051908082528060200260200182016040528015613fc6578160200160208202803683370190505b50905060005b87518110156142e757610e1063ffffffff16878281518110613fea57fe5b60200260200101511115614045576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b61404d615433565b6040518061016001604052808a848151811061406557fe5b6020026020010151815260200189848151811061407e57fe5b60209081029190910181015163ffffffff1682526001600160401b034216908201526000604082018190526001606083018190526080830182905260a0830182905260c0830182905260e0830191909152600a61010083015261012090910152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b9084908111156142a357fe5b021790555050508185018483815181106142b957fe5b60200260200101818152505060018383815181106142d357fe5b602090810291909101015250600101613fcc565b5061430385838360405180602001604052806000815250614f74565b7f4be573152b250c90824828a616cae2e4314f6cc886d0c6289b05977b254eb8be82888860405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561436f578181015183820152602001614357565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156143ae578181015183820152602001614396565b50505050905001848103825285818151815260200191508051906020019060200280838360005b838110156143ed5781810151838201526020016143d5565b50505050905001965050505050505060405180910390a15095945050505050565b60165460ff1615614459576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6016805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613d45613448565b600080613964565b6000612a3883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506134dd565b6000612a3883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506151c2565b6000610e10831115614574576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b61457c615433565b604080516101608101825286815263ffffffff861660208201526001600160401b0342169181019190915260006060820181905260016080830181905260a0830182905260c0830182905260e08301829052610100830191909152600a610120830152610140820152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b9084908111156147aa57fe5b0217905550505060006001600e805490500390506147da8482600160405180602001604052806000815250615227565b6040805187815260208101879052815183927f41ef5b80fa5aaaea22ba4396c76c6e35b7de2e2d4c1bbcdf0bef9db3809105b4928290030190a295945050505050565b60408051600180825281830190925260609182919060208083019080368337019050509050828160008151811061485057fe5b602090810291909101015292915050565b614873846001600160a01b0316613442565b156119bf57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156149025781810151838201526020016148ea565b50505050905090810190601f16801561492f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561495257600080fd5b505af192505050801561497757506040513d602081101561497257600080fd5b505160015b614983576137126154a8565b6001600160e01b0319811663f23a6e6160e01b146134d45760405162461bcd60e51b81526004018080602001828103825260288152602001806155d76028913960400191505060405180910390fd5b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015614abe5783546000198083019190810190600090879083908110614a1d57fe5b9060005260206000209060020201905080876000018481548110614a3d57fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080614a7c57fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506113649350505050565b6000915050611364565b6000612a3883836040518060400160405280601e81526020017f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000815250615328565b600082614b1957506000611364565b82820282848281614b2657fe5b0414612a385760405162461bcd60e51b81526004018080602001828103825260218152602001806158ce6021913960400191505060405180910390fd5b600181015443600160601b9091046001600160401b03161015614b9b5760018101805461ffff60a01b1916600160a11b179055614bec565b6001810154600b54600261ffff600160a01b909304831602919081169082161115614bc95750600b5461ffff165b60018201805461ffff909216600160a01b0261ffff60a01b199092169190911790555b614c0743612d70600754600a546144d990919063ffffffff16565b81600101600c6101000a8154816001600160401b0302191690836001600160401b0316021790555050565b60008563ffffffff168614614c4657600080fd5b8463ffffffff168514614c5857600080fd5b8361ffff168414614c6857600080fd5b614c70615433565b60408051610160810182526000808252602082018190526001600160401b0342811693830193909352606082018190526001608083015263ffffffff8a811660a0840152891660c083015261ffff881660e0830152918616610100820152610120810182905290610140820152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b908490811115614ea257fe5b0217905550505060006001600e80549050039050614ed28482600160405180602001604052806000815250615227565b979650505050505050565b600082815260018401602052604081205480614f42575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612a38565b82856000016001830381548110614f5557fe5b9060005260206000209060020201600101819055506000915050612a38565b6001600160a01b038416614fb95760405162461bcd60e51b8152600401808060200182810382526021815260200180615a656021913960400191505060405180910390fd5b8151835114614ff95760405162461bcd60e51b8152600401808060200182810382526028815260200180615a3d6028913960400191505060405180910390fd5b6000615003613448565b90506150148160008787878761346b565b60005b84518110156150d85761508f6012600087848151811061503357fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000205485838151811061507957fe5b60200260200101516133d090919063ffffffff16565b6012600087848151811061509f57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101615017565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561515f578181015183820152602001615147565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561519e578181015183820152602001615186565b5050505090500194505050505060405180910390a461261581600087878787613574565b600081836152115760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613531578181015183820152602001613519565b50600083858161521d57fe5b0495945050505050565b6001600160a01b03841661526c5760405162461bcd60e51b8152600401808060200182810382526021815260200180615a656021913960400191505060405180910390fd5b6000615276613448565b9050615288816000876130f18861481d565b60008481526012602090815260408083206001600160a01b03891684529091529020546152b590846133d0565b60008581526012602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461261581600087878787614861565b600082815260018401602052604081205482816153865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613531578181015183820152602001613519565b5084600001600182038154811061539957fe5b9060005260206000209060020201600101549150509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106153f657805160ff1916838001178555615423565b82800160010185558215615423579182015b82811115615423578251825591602001919060010190615408565b5061542f92915061548d565b5090565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290529061014082015290565b5b8082111561542f576000815560010161548e565b60e01c90565b600060443d10156154b857611d66565b600481823e6308c379a06154cc82516154a2565b146154d657611d66565b6040513d600319016004823e80513d6001600160401b0381602484011181841117156155055750505050611d66565b8284019250825191508082111561551f5750505050611d66565b503d8301602082840101111561553757505050611d66565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e74657243727970746f416c706163613a20616c7061636120646f6573206e6f742062656c6f6e677320746f206f776e657243727970746f416c706163613a20596f7520646f206e6f74206f776e207468697320616c70616361455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e7343727970746f416c706163613a2063616c6c6572206973206e6f7420746865206f70657261746f7243727970746f416c706163613a204d6174726f6e206973206e6f742079657420726561647920746f20686174636843727970746f416c706163613a206e6577206f70657261746f7220697320746865207a65726f2061646472657373455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a2062617463682062616c616e636520717565727920666f7220746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656443727970746f416c706163613a2053697265206973206e6f742079657420726561647920746f20686174636843727970746f416c706163613a206d7573742070617373206174206c65617374206f6e652067656e6573455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656443727970746f416c706163613a206567672063616e7420626520637261636b65642079657443727970746f416c706163613a2067656e657320616e6420656e65726779206c656e677468206d69736d6174636843727970746f416c706163613a205265717569726564206865746368696e6720414c504120666565206e6f742073656e7443727970746f416c706163613a20696e76616c6964206272656564696e672070657263656e74616765202d206d757374206265206265747765656e203020616e6420313030455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657243727970746f416c706163613a2063616c6c6572206973206e6f74207468652064657643727970746f416c706163613a20696e76616c69642067656e6520736369656e636520636f6e747261637443727970746f416c706163613a205265717569726564206175746f437261636b696e67466565206e6f742073656e74455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d6174636843727970746f416c706163613a204d6174726f6e20616e64205369726520617265206e6f742076616c6964206d6174696e67207061697243727970746f416c706163613a20596f7520646f206e6f74206f776e207369726520616c70616361455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373a26469706673582212203674cc1e4a86e9ad62b9369be0f1ccd79640a6a0a7494d4747b45b096de997ac64736f6c634300060c0033455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e746572455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e73455243313135353a206d696e7420746f20746865207a65726f20616464726573730000000000000000000000007ca4408137eb639570f8e647d9bd7b7e8717514a00000000000000000000000021a852760822d181acc253cb9029362358f1fc770000000000000000000000006dcbe4d0919ff7f933d70c349f11edf92ca38a9e000000000000000000000000ae4b27c433109098c07c87513c895d580ab5b0e6000000000000000000000000db48ec20fcce2cc730f3b3bceafa456e54ceb98d

Deployed Bytecode

0x60806040526004361061038b5760003560e01c806379e81f39116101dc578063a8b3171e11610102578063e3b212e8116100a0578063f2b47d521161006f578063f2b47d5214611253578063f2fde38b14611268578063f4e0d9ac1461129b578063faeb3f82146112ce5761038b565b8063e3b212e814611101578063e985e9c514611116578063f1d24bf214611151578063f242432a1461117d5761038b565b8063cb14382f116100dc578063cb14382f14611050578063cdeec2841461107a578063d0d41fe1146110b9578063d7b4be24146110ec5761038b565b8063a8b3171e14610fbd578063b0ea6a1b14610fed578063c5b8f772146110175761038b565b80639c1f6bf81161017a578063a05ace1511610149578063a05ace1514610f2e578063a22cb46514610f58578063a51cf95e14610f93578063a6fd95fa14610fa85761038b565b80639c1f6bf814610e8e5780639d1bd76d14610ec15780639e82767d14610eeb5780639fa5678314610f195761038b565b80638456cb59116101b65780638456cb5914610e0c57806389d7b18914610e215780638ce40a8b14610e4b5780638da5cb5b14610e795761038b565b806379e81f3914610c835780637a7d493714610cbc5780637c5269c214610cd15761038b565b8063383ad4a9116102c1578063570ca7351161025f57806369cffe961161022e57806369cffe9614610b615780636e33f31614610b9a5780636f8eec3b14610c29578063715018a614610c6e5761038b565b8063570ca73514610af857806359d6dd9d14610b0d5780635c975abb14610b225780636882f5d114610b375761038b565b80634a3d84e81161029b5780634a3d84e8146109085780634ce5d088146109395780634e1273f41461094e5780635663896e14610ace5761038b565b8063383ad4a9146108ad5780633ad10ef6146108c25780633f4ba83a146108f35761038b565b806313c5314e1161032e5780632eb2c2d6116103085780632eb2c2d61461067d5780633154fd961461084b578063328e48be1461087557806333c3d0591461088a5761038b565b806313c5314e1461060b5780631f644c851461062057806329605e771461064a5761038b565b80630ac395bf1161036a5780630ac395bf146104d65780630d22c9971461050f5780630e89341c1461054257806311c1b74f146105e15761038b565b8062fdd58e1461039057806301ffc9a7146103db57806302fe530514610423575b600080fd5b34801561039c57600080fd5b506103c9600480360360408110156103b357600080fd5b506001600160a01b0381351690602001356112f8565b60408051918252519081900360200190f35b3480156103e757600080fd5b5061040f600480360360208110156103fe57600080fd5b50356001600160e01b03191661136a565b604080519115158252519081900360200190f35b34801561042f57600080fd5b506104d46004803603602081101561044657600080fd5b810190602081018135600160201b81111561046057600080fd5b82018360208201111561047257600080fd5b803590602001918460018302840111600160201b8311171561049357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611389945050505050565b005b3480156104e257600080fd5b5061040f600480360360408110156104f957600080fd5b506001600160a01b0381351690602001356113ed565b34801561051b57600080fd5b506104d46004803603602081101561053257600080fd5b50356001600160a01b031661142c565b34801561054e57600080fd5b5061056c6004803603602081101561056557600080fd5b50356114a6565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105a657818101518382015260200161058e565b50505050905090810190601f1680156105d35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105ed57600080fd5b506104d46004803603602081101561060457600080fd5b503561153e565b34801561061757600080fd5b506103c961159b565b34801561062c57600080fd5b506104d46004803603602081101561064357600080fd5b50356115a1565b34801561065657600080fd5b506104d46004803603602081101561066d57600080fd5b50356001600160a01b03166115fe565b34801561068957600080fd5b506104d4600480360360a08110156106a057600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135600160201b8111156106d357600080fd5b8201836020820111156106e557600080fd5b803590602001918460208302840111600160201b8311171561070657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561075557600080fd5b82018360208201111561076757600080fd5b803590602001918460208302840111600160201b8311171561078857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156107d757600080fd5b8201836020820111156107e957600080fd5b803590602001918460018302840111600160201b8311171561080a57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116c4945050505050565b34801561085757600080fd5b506104d46004803603602081101561086e57600080fd5b50356119c7565b34801561088157600080fd5b506103c9611a24565b6103c9600480360360408110156108a057600080fd5b5080359060200135611a2a565b3480156108b957600080fd5b506103c9611d62565b3480156108ce57600080fd5b506108d7611d69565b604080516001600160a01b039092168252519081900360200190f35b3480156108ff57600080fd5b506104d4611d78565b34801561091457600080fd5b5061091d611dda565b604080516001600160401b039092168252519081900360200190f35b34801561094557600080fd5b506103c9611ddf565b34801561095a57600080fd5b50610a7e6004803603604081101561097157600080fd5b810190602081018135600160201b81111561098b57600080fd5b82018360208201111561099d57600080fd5b803590602001918460208302840111600160201b831117156109be57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a0d57600080fd5b820183602082011115610a1f57600080fd5b803590602001918460208302840111600160201b83111715610a4057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611de5945050505050565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610aba578181015183820152602001610aa2565b505050509050019250505060405180910390f35b348015610ada57600080fd5b506104d460048036036020811015610af157600080fd5b5035611f62565b348015610b0457600080fd5b506108d7611fbf565b348015610b1957600080fd5b506108d7611fd3565b348015610b2e57600080fd5b5061040f611fe2565b348015610b4357600080fd5b506104d460048036036020811015610b5a57600080fd5b5035611feb565b348015610b6d57600080fd5b506104d460048036036040811015610b8457600080fd5b506001600160a01b038135169060200135612048565b348015610ba657600080fd5b50610bc460048036036020811015610bbd57600080fd5b50356120dd565b604080519d8e529b151560208e01528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e088015261010087015261012086015261014085015261016084015261018083015251908190036101a00190f35b348015610c3557600080fd5b506104d460048036036060811015610c4c57600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff16612269565b348015610c7a57600080fd5b506104d461245d565b348015610c8f57600080fd5b506104d460048036036040811015610ca657600080fd5b50803590602001356001600160a01b03166124ff565b348015610cc857600080fd5b506103c9612592565b348015610cdd57600080fd5b506104d460048036036060811015610cf457600080fd5b810190602081018135600160201b811115610d0e57600080fd5b820183602082011115610d2057600080fd5b803590602001918460208302840111600160201b83111715610d4157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610d9057600080fd5b820183602082011115610da257600080fd5b803590602001918460208302840111600160201b83111715610dc357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505090356001600160a01b031691506125989050565b348015610e1857600080fd5b506104d461261c565b348015610e2d57600080fd5b506104d460048036036020811015610e4457600080fd5b503561267c565b348015610e5757600080fd5b50610e606126d0565b6040805163ffffffff9092168252519081900360200190f35b348015610e8557600080fd5b506108d76126d6565b348015610e9a57600080fd5b506104d460048036036020811015610eb157600080fd5b50356001600160a01b03166126e5565b348015610ecd57600080fd5b506104d460048036036020811015610ee457600080fd5b50356127ff565b348015610ef757600080fd5b506104d460048036036020811015610f0e57600080fd5b503561ffff1661285c565b348015610f2557600080fd5b506103c96128cc565b348015610f3a57600080fd5b506104d460048036036020811015610f5157600080fd5b50356128d2565b348015610f6457600080fd5b506104d460048036036040811015610f7b57600080fd5b506001600160a01b038135169060200135151561292f565b348015610f9f57600080fd5b506103c9612a1e565b348015610fb457600080fd5b506103c9612a24565b348015610fc957600080fd5b506103c960048036036040811015610fe057600080fd5b5080359060200135612a2a565b348015610ff957600080fd5b506104d46004803603602081101561101057600080fd5b5035612a3f565b34801561102357600080fd5b5061040f6004803603604081101561103a57600080fd5b506001600160a01b038135169060200135612e33565b34801561105c57600080fd5b506104d46004803603602081101561107357600080fd5b5035612e49565b34801561108657600080fd5b506104d46004803603606081101561109d57600080fd5b50803590602081013590604001356001600160a01b0316612ee8565b3480156110c557600080fd5b506104d4600480360360208110156110dc57600080fd5b50356001600160a01b0316612f65565b3480156110f857600080fd5b506108d7612fdb565b34801561110d57600080fd5b506103c9612fea565b34801561112257600080fd5b5061040f6004803603604081101561113957600080fd5b506001600160a01b0381358116916020013516612ff0565b34801561115d57600080fd5b5061116661301e565b6040805161ffff9092168252519081900360200190f35b34801561118957600080fd5b506104d4600480360360a08110156111a057600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b8111156111df57600080fd5b8201836020820111156111f157600080fd5b803590602001918460018302840111600160201b8311171561121257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613028945050505050565b34801561125f57600080fd5b506108d76131f3565b34801561127457600080fd5b506104d46004803603602081101561128b57600080fd5b50356001600160a01b0316613202565b3480156112a757600080fd5b506104d4600480360360208110156112be57600080fd5b50356001600160a01b03166132fa565b3480156112da57600080fd5b5061040f600480360360208110156112f157600080fd5b5035613374565b60006001600160a01b03831661133f5760405162461bcd60e51b815260040180806020018281038252602b815260200180615683602b913960400191505060405180910390fd5b5060008181526012602090815260408083206001600160a01b03861684529091529020545b92915050565b6001600160e01b03191660009081526011602052604090205460ff1690565b611391613448565b6000546001600160a01b039081169116146113e1576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6113ea8161344c565b50565b60006113f98383612e33565b1561140657506001611364565b6001600160a01b03831661141b600f8461345f565b6001600160a01b0316149392505050565b611434613448565b6000546001600160a01b03908116911614611484576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60148054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156115325780601f1061150757610100808354040283529160200191611532565b820191906000526020600020905b81548152906001019060200180831161151557829003601f168201915b50505050509050919050565b611546613448565b6000546001600160a01b03908116911614611596576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600c55565b60095481565b6115a9613448565b6000546001600160a01b039081169116146115f9576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600955565b611606613448565b60165461010090046001600160a01b039081169116146116575760405162461bcd60e51b81526004018080602001828103825260288152602001806155ff6028913960400191505060405180910390fd5b6001600160a01b03811661169c5760405162461bcd60e51b815260040180806020018281038252602e815260200180615655602e913960400191505060405180910390fd5b601680546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b81518351146117045760405162461bcd60e51b8152600401808060200182810382526028815260200180615a3d6028913960400191505060405180910390fd5b6001600160a01b0384166117495760405162461bcd60e51b81526004018080602001828103825260258152602001806157846025913960400191505060405180910390fd5b611751613448565b6001600160a01b0316856001600160a01b0316148061177c575061177c85611777613448565b612ff0565b6117b75760405162461bcd60e51b81526004018080602001828103825260328152602001806157a96032913960400191505060405180910390fd5b60006117c1613448565b90506117d181878787878761346b565b60005b84518110156118d75760008582815181106117eb57fe5b60200260200101519050600085838151811061180357fe5b60200260200101519050611870816040518060600160405280602a81526020016158a4602a91396012600086815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020546134dd9092919063ffffffff16565b60008381526012602090815260408083206001600160a01b038e811685529252808320939093558a16815220546118a790826133d0565b60009283526012602090815260408085206001600160a01b038c16865290915290922091909155506001016117d4565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561195d578181015183820152602001611945565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561199c578181015183820152602001611984565b5050505090500194505050505060405180910390a46119bf818787878787613574565b505050505050565b6119cf613448565b6000546001600160a01b03908116911614611a1f576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600855565b600a5481565b60165460009060ff1615611a78576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60026015541415611ad0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026015556001543390341015611b185760405162461bcd60e51b815260040180806020018281038252602f81526020018061595d602f913960400191505060405180910390fd5b611b24848460016137ea565b60035460408051636eb1769f60e11b81526001600160a01b0385811660048301523060248301529151919092169163dd62ed3e916044808301926020929190829003018186803b158015611b7757600080fd5b505afa158015611b8b573d6000803e3d6000fd5b505050506040513d6020811015611ba157600080fd5b50511015611be05760405162461bcd60e51b815260040180806020018281038252603181526020018061582e6031913960400191505060405180910390fd5b611beb8185856138f0565b611c3c576040805162461bcd60e51b815260206004820181905260248201527f43727970746f416c706163613a20496e76616c6964207065726d697373696f6e604482015290519081900360640190fd5b6000600e8581548110611c4b57fe5b90600052602060002090600302019050611c648161395f565b611c9f5760405162461bcd60e51b815260040180806020018281038252602e815260200180615627602e913960400191505060405180910390fd5b6000600e8581548110611cae57fe5b90600052602060002090600302019050611cc78161395f565b611d025760405162461bcd60e51b815260040180806020018281038252602c81526020018061572e602c913960400191505060405180910390fd5b611d0e8287838861399c565b611d495760405162461bcd60e51b81526004018080602001828103825260378152602001806159de6037913960400191505060405180910390fd5b611d538686613a32565b60016015559695505050505050565b600e545b90565b6004546001600160a01b031681565b611d80613448565b6000546001600160a01b03908116911614611dd0576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b611dd8613cc4565b565b600a81565b60065481565b60608151835114611e275760405162461bcd60e51b81526004018080602001828103825260298152602001806159b56029913960400191505060405180910390fd5b606083516001600160401b0381118015611e4057600080fd5b50604051908082528060200260200182016040528015611e6a578160200160208202803683370190505b50905060005b8451811015611f5a5760006001600160a01b0316858281518110611e9057fe5b60200260200101516001600160a01b03161415611ede5760405162461bcd60e51b81526004018080602001828103825260318152602001806156ae6031913960400191505060405180910390fd5b60126000858381518110611eee57fe5b602002602001015181526020019081526020016000206000868381518110611f1257fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054828281518110611f4757fe5b6020908102919091010152600101611e70565b509392505050565b611f6a613448565b6000546001600160a01b03908116911614611fba576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600755565b60165461010090046001600160a01b031681565b6003546001600160a01b031681565b60165460ff1690565b611ff3613448565b6000546001600160a01b03908116911614612043576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600155565b6120523382612e33565b61208d5760405162461bcd60e51b8152600401808060200182810382526028815260200180615a156028913960400191505060405180910390fd5b612099600f8284613d62565b50604080516001600160a01b0384168152905182917f3a4b868f54c9e39494d33bc09f2562f925681d3acef65a3e7b2284f8b9845220919081900360200190a25050565b600080600080600080600080600080600080600080600e8f815481106120ff57fe5b906000526020600020906003020190508e9d50438160020160009054906101000a90046001600160401b03166001600160401b031611159c508060020160009054906101000a90046001600160401b03166001600160401b03169b508060010160049054906101000a90046001600160401b03166001600160401b03169a508060010160169054906101000a900463ffffffff1663ffffffff16995080600101601a9054906101000a900463ffffffff1663ffffffff1698506121d781600101601e9054906101000a900461ffff1661ffff16613d78565b6001820154909850600160a01b810461ffff16975043600160601b9091046001600160401b03161161220857600196505b60018181015482546002840154600160601b83046001600160401b03169950600160f01b830461ffff16985090965063ffffffff9091169450600160801b900460ff169081111561225557fe5b91505091939597999b9d90929496989a9c50565b612271613448565b60165461010090046001600160a01b039081169116146122c25760405162461bcd60e51b81526004018080602001828103825260288152602001806155ff6028913960400191505060405180910390fd5b6002601554141561231a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260155563ffffffff8116612377576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b6123818383612e33565b6123bc5760405162461bcd60e51b815260040180806020018281038252602e815260200180615581602e913960400191505060405180910390fd5b6000600e83815481106123cb57fe5b60009182526020918290206003919091020160018101805463ffffffff19811663ffffffff878116918217909355604080519390921680845294830152805192945086927ff39159b02e5738f08489b315416eaf67d250b11089fdfe6271af951e461a83709281900390910190a261245185858363ffffffff168663ffffffff16613dad565b50506001601555505050565b612465613448565b6000546001600160a01b039081169116146124b5576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b612507613448565b6000546001600160a01b03908116911614612557576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561258d573d6000803e3d6000fd5b505050565b60075481565b6125a0613448565b6000546001600160a01b039081169116146125f0576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b03811661260a576126076126d6565b90505b612615848484613eb7565b5050505050565b612624613448565b6000546001600160a01b03908116911614612674576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b611dd861440e565b6126863382612e33565b6126c15760405162461bcd60e51b81526004018080602001828103825260288152602001806155af6028913960400191505060405180910390fd5b6126cc600f82613436565b5050565b610e1081565b6000546001600160a01b031690565b6126ed613448565b6000546001600160a01b0390811691161461273d576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b031663c2f5ddc56040518163ffffffff1660e01b815260040160206040518083038186803b15801561277657600080fd5b505afa15801561278a573d6000803e3d6000fd5b505050506040513d60208110156127a057600080fd5b50516127dd5760405162461bcd60e51b815260040180806020018281038252602b815260200180615932602b913960400191505060405180910390fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b612807613448565b6000546001600160a01b03908116911614612857576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600a55565b612864613448565b6000546001600160a01b039081169116146128b4576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600b805461ffff191661ffff92909216919091179055565b60025481565b6128da613448565b6000546001600160a01b0390811691161461292a576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600255565b816001600160a01b0316612941613448565b6001600160a01b031614156129875760405162461bcd60e51b815260040180806020018281038252602981526020018061598c6029913960400191505060405180910390fd5b8060136000612994613448565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556129d8613448565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600c5481565b60085481565b6000612a38838360006137ea565b9392505050565b60026015541415612a97576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026015819055506000600e8281548110612aae57fe5b600091825260209091206003909102016001810154909150600160201b90046001600160401b0316612b27576040805162461bcd60e51b815260206004820152601b60248201527f43727970746f416c706163613a206e6f742076616c6964206567670000000000604482015290519081900360640190fd5b60006002820154600160801b900460ff166001811115612b4357fe5b14612b95576040805162461bcd60e51b815260206004820152601d60248201527f43727970746f416c706163613a206e6f7420612076616c696420656767000000604482015290519081900360640190fd5b612b9e8161448f565b612bd95760405162461bcd60e51b81526004018080602001828103825260258152602001806157db6025913960400191505060405180910390fd5b6001810154600e8054600092600160b01b900463ffffffff16908110612bfb57fe5b906000526020600020906003020190506000600e83600101601a9054906101000a900463ffffffff1663ffffffff1681548110612c3457fe5b600091825260208220600d5485546003909302909101805460018881015460028a0154939750869586956001600160a01b0316946344b3b11b949193919261ffff600160f01b9091041691612c92916001600160401b031690614497565b6040518563ffffffff1660e01b8152600401808581526020018481526020018361ffff16815260200182815260200194505050505060606040518083038186803b158015612cdf57600080fd5b505afa158015612cf3573d6000803e3d6000fd5b505050506040513d6060811015612d0957600080fd5b50805160208201516040909201518189556001808a01805463ffffffff191663ffffffff861617905560028a018054939750939550909350919060ff60801b1916600160801b830217905550612d7643612d706007546008546144d990919063ffffffff16565b906133d0565b60028701805467ffffffffffffffff19166001600160401b039283161767ffffffffffffffff60401b1916600160401b9284169290920291909117905560015415612deb57600154604051339180156108fc02916000818181858888f19350505050158015612de9573d6000803e3d6000fd5b505b6040805184815260208101849052815189927f41ef5b80fa5aaaea22ba4396c76c6e35b7de2e2d4c1bbcdf0bef9db3809105b4928290030190a2505060016015555050505050565b6000612e3f83836112f8565b6001149392505050565b612e51613448565b6000546001600160a01b03908116911614612ea1576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b60646006541115612ee35760405162461bcd60e51b815260040180806020018281038252604581526020018061585f6045913960600191505060405180910390fd5b600655565b612ef0613448565b6000546001600160a01b03908116911614612f40576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b806001600160a01b038116612f5a57612f576126d6565b90505b61261584848361451b565b612f6d613448565b6004546001600160a01b03908116911614612fb95760405162461bcd60e51b815260040180806020018281038252602381526020018061590f6023913960400191505060405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031681565b60015481565b6001600160a01b03918216600090815260136020908152604080832093909416825291909152205460ff1690565b600b5461ffff1681565b6001600160a01b03841661306d5760405162461bcd60e51b81526004018080602001828103825260258152602001806157846025913960400191505060405180910390fd5b613075613448565b6001600160a01b0316856001600160a01b0316148061309b575061309b85611777613448565b6130d65760405162461bcd60e51b81526004018080602001828103825260298152602001806157056029913960400191505060405180910390fd5b60006130e0613448565b90506131008187876130f18861481d565b6130fa8861481d565b8761346b565b613147836040518060600160405280602a81526020016158a4602a913960008781526012602090815260408083206001600160a01b038d16845290915290205491906134dd565b60008581526012602090815260408083206001600160a01b038b8116855292528083209390935587168152205461317e90846133d0565b60008581526012602090815260408083206001600160a01b03808b168086529184529382902094909455805188815291820187905280518a8416938616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a46119bf818787878787614861565b600d546001600160a01b031681565b61320a613448565b6000546001600160a01b0390811691161461325a576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b6001600160a01b03811661329f5760405162461bcd60e51b81526004018080602001828103825260268152602001806156df6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b613302613448565b6000546001600160a01b03908116911614613352576040805162461bcd60e51b815260206004820181905260248201526000805160206158ef833981519152604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b600080600e838154811061338457fe5b60009182526020822060039091020191506002820154600160801b900460ff1660018111156133af57fe5b148015612a385750600201546001600160401b034381169116111592915050565b600082820183811015612a38576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000612a3883836149d2565b6000612a3883836149ea565b3b151590565b3390565b80516126cc9060149060208401906153b5565b6000612a388383614ac8565b60005b83518110156134d45761349e84828151811061348657fe5b6020026020010151600f61342a90919063ffffffff16565b156134cc576134ca8482815181106134b257fe5b6020026020010151600f61343690919063ffffffff16565b505b60010161346e565b50505050505050565b6000818484111561356c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613531578181015183820152602001613519565b50505050905090810190601f16801561355e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b613586846001600160a01b0316613442565b156119bf57836001600160a01b031663bc197c8187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b03168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156136145781810151838201526020016135fc565b50505050905001848103835286818151815260200191508051906020019060200280838360005b8381101561365357818101518382015260200161363b565b50505050905001848103825285818151815260200191508051906020019080838360005b8381101561368f578181015183820152602001613677565b50505050905090810190601f1680156136bc5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600087803b1580156136e157600080fd5b505af192505050801561370657506040513d602081101561370157600080fd5b505160015b61379b576137126154a8565b8061371d5750613764565b60405162461bcd60e51b8152602060048201818152835160248401528351849391928392604401919085019080838360008315613531578181015183820152602001613519565b60405162461bcd60e51b815260040180806020018281038252603481526020018061554d6034913960400191505060405180910390fd5b6001600160e01b0319811663bc197c8160e01b146134d45760405162461bcd60e51b81526004018080602001828103825260288152602001806155d76028913960400191505060405180910390fd5b600043826137f6576001015b6000600e858154811061380557fe5b60009182526020822060039190910201600181015490925061383190600160f01b900461ffff16613d78565b6001830154909150600160a01b810461ffff1690600160601b90046001600160401b0316841115613860575060015b6000600e898154811061386f57fe5b60009182526020822060039190910201600181015490925061389b90600160f01b900461ffff16613d78565b6001830154909150600160a01b810461ffff1690600160601b90046001600160401b03168711156138ca575060015b6138e16138d78383614b0a565b612d708787614b0a565b9b9a5050505050505050505050565b60006138fc8484612e33565b61390857506000612a38565b6139128483612e33565b1561391f57506001612a38565b61392a600f8361342a565b15613955576001600160a01b038416613944600f8461345f565b6001600160a01b0316149050612a38565b5060009392505050565b600060015b6002830154600160801b900460ff16600181111561397e57fe5b148015611364575050600201546001600160401b0343811691161090565b6000818414156139ae57506000613a2a565b6001850154600160b01b900463ffffffff168214806139dd57506001850154600160d01b900463ffffffff1682145b156139ea57506000613a2a565b6001830154600160b01b900463ffffffff16841480613a1957506001830154600160d01b900463ffffffff1684145b15613a2657506000613a2a565b5060015b949350505050565b600080613a41848460016137ea565b90506000613a656064613a5f60065485614b0a90919063ffffffff16565b906144d9565b90506000613a866064613a5f60065460640386614b0a90919063ffffffff16565b60035460048054604080516323b872dd60e01b815233938101939093526001600160a01b0391821660248401526044830187905251939450909116916323b872dd916064808201926020929091908290030181600087803b158015613aea57600080fd5b505af1158015613afe573d6000803e3d6000fd5b505050506040513d6020811015613b1457600080fd5b5051613b1c57fe5b600354600554604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101859052905191909216916323b872dd9160648083019260209291908290030181600087803b158015613b7b57600080fd5b505af1158015613b8f573d6000803e3d6000fd5b505050506040513d6020811015613ba557600080fd5b5051613bad57fe5b6000600e8681548110613bbc57fe5b906000526020600020906003020190506000600e8881548110613bdb57fe5b90600052602060002090600302019050613bf482614b63565b613bfd81614b63565b6001808201549083015461ffff600160f01b9283900481169290910416811115613c3357506001820154600160f01b900461ffff165b6000613c408260016133d0565b90506000613c5f43612d706007546009546144d990919063ffffffff16565b90506000613c708c8c858533614c32565b604080518e8152602081018e9052808201859052905191925082917fe5319461929da8fd31411cd6242ec17e2adddf5de0053f228fba15aff76f53bd9181900360600190a29b9a5050505050505050505050565b60165460ff16613d12576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6016805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa613d45613448565b604080516001600160a01b039092168252519081900360200190a1565b6000613a2a84846001600160a01b038516614edd565b6000611364613da4670de0b6b3a7640000613d9e600c5486614b0a90919063ffffffff16565b90614b0a565b600254906133d0565b613dbf846001600160a01b0316613442565b15613eb157604080516301ffc9a760e01b81526316a1938760e21b600482015290516001600160a01b038616916301ffc9a7916024808301926020929190829003018186803b158015613e1157600080fd5b505afa158015613e25573d6000803e3d6000fd5b505050506040513d6020811015613e3b57600080fd5b505115613eb157836001600160a01b0316635a864e1c8484846040518463ffffffff1660e01b8152600401808481526020018381526020018281526020019350505050600060405180830381600087803b158015613e9857600080fd5b505af1158015613eac573d6000803e3d6000fd5b505050505b50505050565b60606000845111613ef95760405162461bcd60e51b815260040180806020018281038252602a81526020018061575a602a913960400191505060405180910390fd5b8251845114613f395760405162461bcd60e51b815260040180806020018281038252602e815260200180615800602e913960400191505060405180910390fd5b600e5484516060906001600160401b0381118015613f5657600080fd5b50604051908082528060200260200182016040528015613f80578160200160208202803683370190505b509050606086516001600160401b0381118015613f9c57600080fd5b50604051908082528060200260200182016040528015613fc6578160200160208202803683370190505b50905060005b87518110156142e757610e1063ffffffff16878281518110613fea57fe5b60200260200101511115614045576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b61404d615433565b6040518061016001604052808a848151811061406557fe5b6020026020010151815260200189848151811061407e57fe5b60209081029190910181015163ffffffff1682526001600160401b034216908201526000604082018190526001606083018190526080830182905260a0830182905260c0830182905260e0830191909152600a61010083015261012090910152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b9084908111156142a357fe5b021790555050508185018483815181106142b957fe5b60200260200101818152505060018383815181106142d357fe5b602090810291909101015250600101613fcc565b5061430385838360405180602001604052806000815250614f74565b7f4be573152b250c90824828a616cae2e4314f6cc886d0c6289b05977b254eb8be82888860405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b8381101561436f578181015183820152602001614357565b50505050905001848103835286818151815260200191508051906020019060200280838360005b838110156143ae578181015183820152602001614396565b50505050905001848103825285818151815260200191508051906020019060200280838360005b838110156143ed5781810151838201526020016143d5565b50505050905001965050505050505060405180910390a15095945050505050565b60165460ff1615614459576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6016805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613d45613448565b600080613964565b6000612a3883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506134dd565b6000612a3883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506151c2565b6000610e10831115614574576040805162461bcd60e51b815260206004820152601c60248201527f43727970746f416c706163613a20696e76616c696420656e6572677900000000604482015290519081900360640190fd5b61457c615433565b604080516101608101825286815263ffffffff861660208201526001600160401b0342169181019190915260006060820181905260016080830181905260a0830182905260c0830182905260e08301829052610100830191909152600a610120830152610140820152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b9084908111156147aa57fe5b0217905550505060006001600e805490500390506147da8482600160405180602001604052806000815250615227565b6040805187815260208101879052815183927f41ef5b80fa5aaaea22ba4396c76c6e35b7de2e2d4c1bbcdf0bef9db3809105b4928290030190a295945050505050565b60408051600180825281830190925260609182919060208083019080368337019050509050828160008151811061485057fe5b602090810291909101015292915050565b614873846001600160a01b0316613442565b156119bf57836001600160a01b031663f23a6e6187878686866040518663ffffffff1660e01b815260040180866001600160a01b03168152602001856001600160a01b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156149025781810151838201526020016148ea565b50505050905090810190601f16801561492f5780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600087803b15801561495257600080fd5b505af192505050801561497757506040513d602081101561497257600080fd5b505160015b614983576137126154a8565b6001600160e01b0319811663f23a6e6160e01b146134d45760405162461bcd60e51b81526004018080602001828103825260288152602001806155d76028913960400191505060405180910390fd5b60009081526001919091016020526040902054151590565b60008181526001830160205260408120548015614abe5783546000198083019190810190600090879083908110614a1d57fe5b9060005260206000209060020201905080876000018481548110614a3d57fe5b600091825260208083208454600290930201918255600193840154918401919091558354825289830190526040902090840190558654879080614a7c57fe5b60008281526020808220600260001990940193840201828155600190810183905592909355888152898201909252604082209190915594506113649350505050565b6000915050611364565b6000612a3883836040518060400160405280601e81526020017f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000815250615328565b600082614b1957506000611364565b82820282848281614b2657fe5b0414612a385760405162461bcd60e51b81526004018080602001828103825260218152602001806158ce6021913960400191505060405180910390fd5b600181015443600160601b9091046001600160401b03161015614b9b5760018101805461ffff60a01b1916600160a11b179055614bec565b6001810154600b54600261ffff600160a01b909304831602919081169082161115614bc95750600b5461ffff165b60018201805461ffff909216600160a01b0261ffff60a01b199092169190911790555b614c0743612d70600754600a546144d990919063ffffffff16565b81600101600c6101000a8154816001600160401b0302191690836001600160401b0316021790555050565b60008563ffffffff168614614c4657600080fd5b8463ffffffff168514614c5857600080fd5b8361ffff168414614c6857600080fd5b614c70615433565b60408051610160810182526000808252602082018190526001600160401b0342811693830193909352606082018190526001608083015263ffffffff8a811660a0840152891660c083015261ffff881660e0830152918616610100820152610120810182905290610140820152600e80546001808201835560009290925282517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd600390920291820190815560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe8301805460408701516060880151608089015160a08a015160c08b015160e08c015163ffffffff1990961663ffffffff988916176bffffffffffffffff000000001916600160201b6001600160401b03968716021767ffffffffffffffff60601b1916600160601b948616949094029390931761ffff60a01b1916600160a01b61ffff938416021763ffffffff60b01b1916600160b01b918816919091021763ffffffff60d01b1916600160d01b9690921695909502176001600160f01b0316600160f01b94909216939093021790556101008501517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff909301805461012087015167ffffffffffffffff199091169483169490941767ffffffffffffffff60401b1916600160401b9490921693909302178083556101408501519495508594919391929160ff60801b1990911690600160801b908490811115614ea257fe5b0217905550505060006001600e80549050039050614ed28482600160405180602001604052806000815250615227565b979650505050505050565b600082815260018401602052604081205480614f42575050604080518082018252838152602080820184815286546001818101895560008981528481209551600290930290950191825591519082015586548684528188019092529290912055612a38565b82856000016001830381548110614f5557fe5b9060005260206000209060020201600101819055506000915050612a38565b6001600160a01b038416614fb95760405162461bcd60e51b8152600401808060200182810382526021815260200180615a656021913960400191505060405180910390fd5b8151835114614ff95760405162461bcd60e51b8152600401808060200182810382526028815260200180615a3d6028913960400191505060405180910390fd5b6000615003613448565b90506150148160008787878761346b565b60005b84518110156150d85761508f6012600087848151811061503357fe5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b031681526020019081526020016000205485838151811061507957fe5b60200260200101516133d090919063ffffffff16565b6012600087848151811061509f57fe5b602090810291909101810151825281810192909252604090810160009081206001600160a01b038b168252909252902055600101615017565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561515f578181015183820152602001615147565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561519e578181015183820152602001615186565b5050505090500194505050505060405180910390a461261581600087878787613574565b600081836152115760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613531578181015183820152602001613519565b50600083858161521d57fe5b0495945050505050565b6001600160a01b03841661526c5760405162461bcd60e51b8152600401808060200182810382526021815260200180615a656021913960400191505060405180910390fd5b6000615276613448565b9050615288816000876130f18861481d565b60008481526012602090815260408083206001600160a01b03891684529091529020546152b590846133d0565b60008581526012602090815260408083206001600160a01b03808b16808652918452828520959095558151898152928301889052815190948616927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6292908290030190a461261581600087878787614861565b600082815260018401602052604081205482816153865760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613531578181015183820152602001613519565b5084600001600182038154811061539957fe5b9060005260206000209060020201600101549150509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106153f657805160ff1916838001178555615423565b82800160010185558215615423579182015b82811115615423578251825591602001919060010190615408565b5061542f92915061548d565b5090565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290529061014082015290565b5b8082111561542f576000815560010161548e565b60e01c90565b600060443d10156154b857611d66565b600481823e6308c379a06154cc82516154a2565b146154d657611d66565b6040513d600319016004823e80513d6001600160401b0381602484011181841117156155055750505050611d66565b8284019250825191508082111561551f5750505050611d66565b503d8301602082840101111561553757505050611d66565b601f01601f191681016020016040529150509056fe455243313135353a207472616e7366657220746f206e6f6e2045524331313535526563656976657220696d706c656d656e74657243727970746f416c706163613a20616c7061636120646f6573206e6f742062656c6f6e677320746f206f776e657243727970746f416c706163613a20596f7520646f206e6f74206f776e207468697320616c70616361455243313135353a204552433131353552656365697665722072656a656374656420746f6b656e7343727970746f416c706163613a2063616c6c6572206973206e6f7420746865206f70657261746f7243727970746f416c706163613a204d6174726f6e206973206e6f742079657420726561647920746f20686174636843727970746f416c706163613a206e6577206f70657261746f7220697320746865207a65726f2061646472657373455243313135353a2062616c616e636520717565727920666f7220746865207a65726f2061646472657373455243313135353a2062617463682062616c616e636520717565727920666f7220746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656443727970746f416c706163613a2053697265206973206e6f742079657420726561647920746f20686174636843727970746f416c706163613a206d7573742070617373206174206c65617374206f6e652067656e6573455243313135353a207472616e7366657220746f20746865207a65726f2061646472657373455243313135353a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656443727970746f416c706163613a206567672063616e7420626520637261636b65642079657443727970746f416c706163613a2067656e657320616e6420656e65726779206c656e677468206d69736d6174636843727970746f416c706163613a205265717569726564206865746368696e6720414c504120666565206e6f742073656e7443727970746f416c706163613a20696e76616c6964206272656564696e672070657263656e74616765202d206d757374206265206265747765656e203020616e6420313030455243313135353a20696e73756666696369656e742062616c616e636520666f72207472616e73666572536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657243727970746f416c706163613a2063616c6c6572206973206e6f74207468652064657643727970746f416c706163613a20696e76616c69642067656e6520736369656e636520636f6e747261637443727970746f416c706163613a205265717569726564206175746f437261636b696e67466565206e6f742073656e74455243313135353a2073657474696e6720617070726f76616c2073746174757320666f722073656c66455243313135353a206163636f756e747320616e6420696473206c656e677468206d69736d6174636843727970746f416c706163613a204d6174726f6e20616e64205369726520617265206e6f742076616c6964206d6174696e67207061697243727970746f416c706163613a20596f7520646f206e6f74206f776e207369726520616c70616361455243313135353a2069647320616e6420616d6f756e7473206c656e677468206d69736d61746368455243313135353a206d696e7420746f20746865207a65726f2061646472657373a26469706673582212203674cc1e4a86e9ad62b9369be0f1ccd79640a6a0a7494d4747b45b096de997ac64736f6c634300060c0033

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

0000000000000000000000007ca4408137eb639570f8e647d9bd7b7e8717514a00000000000000000000000021a852760822d181acc253cb9029362358f1fc770000000000000000000000006dcbe4d0919ff7f933d70c349f11edf92ca38a9e000000000000000000000000ae4b27c433109098c07c87513c895d580ab5b0e6000000000000000000000000db48ec20fcce2cc730f3b3bceafa456e54ceb98d

-----Decoded View---------------
Arg [0] : _alpa (address): 0x7cA4408137eb639570F8E647d9bD7B7E8717514A
Arg [1] : _geneScience (address): 0x21A852760822d181ACC253Cb9029362358f1Fc77
Arg [2] : _operator (address): 0x6Dcbe4D0919FF7f933d70C349f11edF92Ca38a9E
Arg [3] : _devAddress (address): 0xaE4b27c433109098c07C87513C895d580AB5B0E6
Arg [4] : _stakingAddress (address): 0xdB48EC20fCce2CC730f3b3bcEAfA456e54ceB98D

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000007ca4408137eb639570f8e647d9bd7b7e8717514a
Arg [1] : 00000000000000000000000021a852760822d181acc253cb9029362358f1fc77
Arg [2] : 0000000000000000000000006dcbe4d0919ff7f933d70c349f11edf92ca38a9e
Arg [3] : 000000000000000000000000ae4b27c433109098c07c87513c895d580ab5b0e6
Arg [4] : 000000000000000000000000db48ec20fcce2cc730f3b3bceafa456e54ceb98d


Deployed Bytecode Sourcemap

93822:1321:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43799:223;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;43799:223:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;39755:142;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39755:142:0;-1:-1:-1;;;;;;39755:142:0;;:::i;:::-;;;;;;;;;;;;;;;;;;68179:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68179:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;68179:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68179:93:0;;-1:-1:-1;68179:93:0;;-1:-1:-1;;;;;68179:93:0:i;:::-;;78737:286;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;78737:286:0;;;;;;;;:::i;66682:89::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66682:89:0;-1:-1:-1;;;;;66682:89:0;;:::i;43549:99::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43549:99:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64905:206;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64905:206:0;;:::i;60053:52::-;;;;;;;;;;;;;:::i;63641:130::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63641:130:0;;:::i;92368:245::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92368:245:0;-1:-1:-1;;;;;92368:245:0;;:::i;46511:1220::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46511:1220:0;;;;;;;;-1:-1:-1;46511:1220:0;;-1:-1:-1;;;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46511:1220:0;;;;;;;;-1:-1:-1;46511:1220:0;;-1:-1:-1;;;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46511:1220:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46511:1220:0;;-1:-1:-1;46511:1220:0;;-1:-1:-1;;;;;46511:1220:0:i;65386:126::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65386:126:0;;:::i;60353:60::-;;;;;;;;;;;;;:::i;79801:1829::-;;;;;;;;;;;;;;;;-1:-1:-1;79801:1829:0;;;;;;;:::i;63134:98::-;;;;;;;;;;;;;:::i;59234:25::-;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;59234:25:0;;;;;;;;;;;;;;95073:67;;;;;;;;;;;;;:::i;60622:50::-;;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;60622:50:0;;;;;;;;;;;;;;59599:41;;;;;;;;;;;;;:::i;44188:634::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;44188:634:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;44188:634:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44188:634:0;;;;;;;;-1:-1:-1;44188:634:0;;-1:-1:-1;;;;;44188:634:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;44188:634:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44188:634:0;;-1:-1:-1;44188:634:0;;-1:-1:-1;;;;;44188:634:0:i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65925:104;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65925:104:0;;:::i;91049:23::-;;;;;;;;;;;;;:::i;59126:18::-;;;;;;;;;;;;;:::i;30257:78::-;;;;;;;;;;;;;:::i;66106:126::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66106:126:0;;:::i;78282:345::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;78282:345:0;;;;;;;;:::i;75972:1315::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75972:1315:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91600:632;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91600:632:0;;-1:-1:-1;;;;;91600:632:0;;;;;;;;;;;;;:::i;57233:148::-;;;;;;;;;;;;;:::i;94698:145::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94698:145:0;;;;;;-1:-1:-1;;;;;94698:145:0;;:::i;59750:35::-;;;;;;;;;;;;;:::i;69046:351::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;69046:351:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;69046:351:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;69046:351:0;;;;;;;;-1:-1:-1;69046:351:0;;-1:-1:-1;;;;;69046:351:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;69046:351:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;69046:351:0;;-1:-1:-1;;;69046:351:0;;-1:-1:-1;;;;;69046:351:0;;-1:-1:-1;69046:351:0;;-1:-1:-1;69046:351:0:i;94939:63::-;;;;;;;;;;;;;:::i;79178:263::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79178:263:0;;:::i;60831:45::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;56591:79;;;;;;;;;;;;;:::i;66304:296::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66304:296:0;-1:-1:-1;;;;;66304:296:0;;:::i;65595:193::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65595:193:0;;:::i;64226:176::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64226:176:0;;;;:::i;59009:38::-;;;;;;;;;;;;;:::i;65183:126::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;65183:126:0;;:::i;44895:311::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;44895:311:0;;;;;;;;;;:::i;60966:50::-;;;;;;;;;;;;;:::i;59915:48::-;;;;;;;;;;;;;:::i;77357:196::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77357:196:0;;;;;;;:::i;81776:1641::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81776:1641:0;;:::i;67839:176::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67839:176:0;;;;;;;;:::i;64489:331::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64489:331:0;;:::i;68524:322::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68524:322:0;;;;;;;;;;;-1:-1:-1;;;;;68524:322:0;;:::i;64031:104::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64031:104:0;-1:-1:-1;;;;;64031:104:0;;:::i;59353:29::-;;;;;;;;;;;;;:::i;58912:34::-;;;;;;;;;;;;;:::i;45278:160::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;45278:160:0;;;;;;;;;;:::i;60518:41::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;45510:924;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;45510:924:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;45510:924:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;45510:924:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45510:924:0;;-1:-1:-1;45510:924:0;;-1:-1:-1;;;;;45510:924:0:i;61121:31::-;;;;;;;;;;;;;:::i;57536:244::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57536:244:0;-1:-1:-1;;;;;57536:244:0;;:::i;63844:122::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63844:122:0;-1:-1:-1;;;;;63844:122:0;;:::i;77699:257::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77699:257:0;;:::i;43799:223::-;43877:7;-1:-1:-1;;;;;43905:21:0;;43897:77;;;;-1:-1:-1;;;43897:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43992:13:0;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;43992:22:0;;;;;;;;;;43799:223;;;;;:::o;39755:142::-;-1:-1:-1;;;;;;39856:33:0;39832:4;39856:33;;;:20;:33;;;;;;;;;39755:142::o;68179:93::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;68248:16:::1;68256:7;68248;:16::i;:::-;68179:93:::0;:::o;78737:286::-;78869:4;78895:21;78905:5;78912:3;78895:9;:21::i;:::-;78891:65;;;-1:-1:-1;78940:4:0;78933:11;;78891:65;-1:-1:-1;;;;;78975:40:0;;:31;:22;79002:3;78975:26;:31::i;:::-;-1:-1:-1;;;;;78975:40:0;;;78737:286;-1:-1:-1;;;78737:286:0:o;66682:89::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;66751:4:::1;:12:::0;;-1:-1:-1;;;;;;66751:12:0::1;-1:-1:-1::0;;;;;66751:12:0;;;::::1;::::0;;;::::1;::::0;;66682:89::o;43549:99::-;43636:4;43629:11;;;;;;;;-1:-1:-1;;43629:11:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43603:13;;43629:11;;43636:4;;43629:11;;43636:4;43629:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43549:99;;;:::o;64905:206::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;65037:31:::1;:66:::0;64905:206::o;60053:52::-;;;;:::o;63641:130::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;63727:16:::1;:36:::0;63641:130::o;92368:245::-;92819:12;:10;:12::i;:::-;92807:8;;;;;-1:-1:-1;;;;;92807:8:0;;;:24;;;92785:114;;;;-1:-1:-1;;;92785:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;92471:26:0;::::1;92449:122;;;;-1:-1:-1::0;;;92449:122:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92582:8;:23:::0;;-1:-1:-1;;;;;92582:23:0;;::::1;;;-1:-1:-1::0;;;;;;92582:23:0;;::::1;::::0;;;::::1;::::0;;92368:245::o;46511:1220::-;46776:7;:14;46762:3;:10;:28;46754:81;;;;-1:-1:-1;;;46754:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46854:16:0;;46846:66;;;;-1:-1:-1;;;46846:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46953:12;:10;:12::i;:::-;-1:-1:-1;;;;;46945:20:0;:4;-1:-1:-1;;;;;46945:20:0;;:60;;;;46969:36;46986:4;46992:12;:10;:12::i;:::-;46969:16;:36::i;:::-;46923:160;;;;-1:-1:-1;;;46923:160:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47096:16;47115:12;:10;:12::i;:::-;47096:31;;47140:60;47161:8;47171:4;47177:2;47181:3;47186:7;47195:4;47140:20;:60::i;:::-;47218:9;47213:358;47237:3;:10;47233:1;:14;47213:358;;;47269:10;47282:3;47286:1;47282:6;;;;;;;;;;;;;;47269:19;;47303:14;47320:7;47328:1;47320:10;;;;;;;;;;;;;;47303:27;;47369:126;47411:6;47369:126;;;;;;;;;;;;;;;;;:9;:13;47379:2;47369:13;;;;;;;;;;;:19;47383:4;-1:-1:-1;;;;;47369:19:0;-1:-1:-1;;;;;47369:19:0;;;;;;;;;;;;;:23;;:126;;;;;:::i;:::-;47347:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;47347:19:0;;;;;;;;;;:148;;;;47530:17;;;;;;:29;;47552:6;47530:21;:29::i;:::-;47510:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;47510:17:0;;;;;;;;;;:49;;;;-1:-1:-1;47249:3:0;;47213:358;;;;47618:2;-1:-1:-1;;;;;47588:47:0;47612:4;-1:-1:-1;;;;;47588:47:0;47602:8;-1:-1:-1;;;;;47588:47:0;;47622:3;47627:7;47588:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47648:75;47684:8;47694:4;47700:2;47704:3;47709:7;47718:4;47648:35;:75::i;:::-;46511:1220;;;;;;:::o;65386:126::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;65470:15:::1;:34:::0;65386:126::o;60353:60::-;;;;:::o;79801:1829::-;30575:7;;79968;;30575;;30574:8;30566:37;;;;;-1:-1:-1;;;30566:37:0;;;;;;;;;;;;-1:-1:-1;;;30566:37:0;;;;;;;;;;;;;;;27168:1:::1;27774:7;;:19;;27766:63;;;::::0;;-1:-1:-1;;;27766:63:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;27168:1;27907:7;:18:::0;80103:15:::2;::::0;80013:10:::2;::::0;80090:9:::2;:28;;80068:125;;;;-1:-1:-1::0;;;80068:125:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80325:43;80343:9;80354:7;80363:4;80325:17;:43::i;:::-;80264:4;::::0;:40:::2;::::0;;-1:-1:-1;;;80264:40:0;;-1:-1:-1;;;;;80264:40:0;;::::2;;::::0;::::2;::::0;80298:4:::2;80264:40:::0;;;;;;:4;;;::::2;::::0;:14:::2;::::0;:40;;;;;::::2;::::0;;;;;;;;:4;:40;::::2;;::::0;::::2;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;-1:-1:-1::0;80264:40:0;:104:::2;;80242:203;;;;-1:-1:-1::0;;;80242:203:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80540:53;80563:9;80574;80585:7;80540:22;:53::i;:::-;80518:135;;;::::0;;-1:-1:-1;;;80518:135:0;;::::2;;::::0;::::2;::::0;;;;;;;::::2;::::0;;;;;;;;;;;;;::::2;;80719:21;80743:7;80751:9;80743:18;;;;;;;;;;;;;;;;;;80719:42;;80879:23;80895:6;80879:15;:23::i;:::-;80857:119;;;;-1:-1:-1::0;;;80857:119:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81040:19;81062:7;81070;81062:16;;;;;;;;;;;;;;;;;;81040:38;;81194:21;81210:4;81194:15;:21::i;:::-;81172:115;;;;-1:-1:-1::0;;;81172:115:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81385:52;81404:6;81412:9;81423:4;81429:7;81385:18;:52::i;:::-;81363:157;;;;-1:-1:-1::0;;;81363:157:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81593:29;81603:9;81614:7;81593:9;:29::i;:::-;27124:1:::1;28086:7;:22:::0;81586:36;79801:1829;-1:-1:-1;;;;;;79801:1829:0:o;63134:98::-;63210:7;:14;63134:98;;:::o;59234:25::-;;;-1:-1:-1;;;;;59234:25:0;;:::o;95073:67::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;95122:10:::1;:8;:10::i;:::-;95073:67::o:0;60622:50::-;60670:2;60622:50;:::o;59599:41::-;;;;:::o;44188:634::-;44352:16;44413:3;:10;44394:8;:15;:29;44386:83;;;;-1:-1:-1;;;44386:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44482:30;44529:8;:15;-1:-1:-1;;;;;44515:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44515:30:0;;44482:63;;44563:9;44558:224;44582:8;:15;44578:1;:19;44558:224;;;44650:1;-1:-1:-1;;;;;44627:25:0;:8;44636:1;44627:11;;;;;;;;;;;;;;-1:-1:-1;;;;;44627:25:0;;;44619:87;;;;-1:-1:-1;;;44619:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44740:9;:17;44750:3;44754:1;44750:6;;;;;;;;;;;;;;44740:17;;;;;;;;;;;:30;44758:8;44767:1;44758:11;;;;;;;;;;;;;;-1:-1:-1;;;;;44740:30:0;-1:-1:-1;;;;;44740:30:0;;;;;;;;;;;;;44721:13;44735:1;44721:16;;;;;;;;;;;;;;;;;:49;44599:3;;44558:224;;;-1:-1:-1;44801:13:0;44188:634;-1:-1:-1;;;44188:634:0:o;65925:104::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;65998:15:::1;:23:::0;65925:104::o;91049:23::-;;;;;;-1:-1:-1;;;;;91049:23:0;;:::o;59126:18::-;;;-1:-1:-1;;;;;59126:18:0;;:::o;30257:78::-;30320:7;;;;30257:78;:::o;66106:126::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;66190:15:::1;:34:::0;66106:126::o;78282:345::-;78420:30;78430:10;78442:7;78420:9;:30::i;:::-;78398:120;;;;-1:-1:-1;;;78398:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78531:42;:22;78558:7;78567:5;78531:26;:42::i;:::-;-1:-1:-1;78589:30:0;;;-1:-1:-1;;;;;78589:30:0;;;;;;78604:7;;78589:30;;;;;;;;;;78282:345;;:::o;75972:1315::-;76086:10;76111:12;76138:24;76177:17;76209:16;76240:14;76269:20;76304:30;76349:35;76399:18;76432:12;76459:14;76488:13;76529:21;76553:7;76561:3;76553:12;;;;;;;;;;;;;;;;;;76529:36;;76583:3;76578:8;;76635:12;76608:6;:23;;;;;;;;;;-1:-1:-1;;;;;76608:23:0;-1:-1:-1;;;;;76608:39:0;;;76597:51;;76678:6;:23;;;;;;;;;;-1:-1:-1;;;;;76678:23:0;-1:-1:-1;;;;;76659:42:0;;;76724:6;:16;;;;;;;;;;-1:-1:-1;;;;;76724:16:0;-1:-1:-1;;;;;76712:28:0;;;76762:6;:15;;;;;;;;;;;;76751:26;;;;76797:6;:13;;;;;;;;;;;;76788:22;;;;76836:39;76857:6;:17;;;;;;;;;;;;76836:39;;:20;:39::i;:::-;76911:29;;;;76821:54;;-1:-1:-1;;;;76911:29:0;;;;;-1:-1:-1;76993:12:0;-1:-1:-1;;;76955:34:0;;;-1:-1:-1;;;;;76955:34:0;:50;76951:109;;77047:1;77022:26;;76951:109;77102:34;;;;;77195:11;;77266:12;;;;-1:-1:-1;;;77102:34:0;;-1:-1:-1;;;;;77102:34:0;;-1:-1:-1;;;;77160:17:0;;;;;-1:-1:-1;77195:11:0;;-1:-1:-1;77226:13:0;;;;;-1:-1:-1;;;;77266:12:0;;;;;77258:21;;;;;;;77250:29;;75972:1315;;;;;;;;;;;;;;;;:::o;91600:632::-;92819:12;:10;:12::i;:::-;92807:8;;;;;-1:-1:-1;;;;;92807:8:0;;;:24;;;92785:114;;;;-1:-1:-1;;;92785:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27168:1:::1;27774:7;;:19;;27766:63;;;::::0;;-1:-1:-1;;;27766:63:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;27168:1;27907:7;:18:::0;91764:14:::2;::::0;::::2;91756:55;;;::::0;;-1:-1:-1;;;91756:55:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;::::2;::::0;;;;;;;;;;;;;::::2;;91846:22;91856:6;91864:3;91846:9;:22::i;:::-;91824:118;;;;-1:-1:-1::0;;;91824:118:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91955:25;91983:7;91991:3;91983:12;;;;;;;;;::::0;;;::::2;::::0;;;;::::2;::::0;;;::::2;;92025:17;::::0;::::2;::::0;;-1:-1:-1;;92053:30:0;::::2;92025:17;92053:30:::0;;::::2;::::0;;::::2;::::0;;;92101:41:::2;::::0;;92025:17;;;::::2;92101:41:::0;;;;;::::2;::::0;;;91983:12;;-1:-1:-1;92115:3:0;;92101:41:::2;::::0;;;;;;;;::::2;92153:71;92189:6;92197:3;92202:9;92153:71;;92213:10;92153:71;;:35;:71::i;:::-;-1:-1:-1::0;;27124:1:0::1;28086:7;:22:::0;-1:-1:-1;;;91600:632:0:o;57233:148::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;57340:1:::1;57324:6:::0;;57303:40:::1;::::0;-1:-1:-1;;;;;57324:6:0;;::::1;::::0;57303:40:::1;::::0;57340:1;;57303:40:::1;57371:1;57354:19:::0;;-1:-1:-1;;;;;;57354:19:0::1;::::0;;57233:148::o;94698:145::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;94814:21:::1;::::0;-1:-1:-1;;;;;94814:12:0;::::1;::::0;:21;::::1;;;::::0;94827:7;;94814:21:::1;::::0;;;94827:7;94814:12;:21;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;94698:145:::0;;:::o;59750:35::-;;;;:::o;69046:351::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;69232:6;-1:-1:-1;;;;;69253:25:0;::::1;69249:79;;69309:7;:5;:7::i;:::-;69295:21;;69249:79;69340:49;69363:6;69371:9;69382:6;69340:22;:49::i;:::-;;56873:1;69046:351:::0;;;:::o;94939:63::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;94986:8:::1;:6;:8::i;79178:263::-:0;79280:32;79290:10;79302:9;79280;:32::i;:::-;79258:122;;;;-1:-1:-1;;;79258:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79393:40;:22;79423:9;79393:29;:40::i;:::-;;79178:263;:::o;60831:45::-;60872:4;60831:45;:::o;56591:79::-;56629:7;56656:6;-1:-1:-1;;;;;56656:6:0;56591:79;:::o;66304:296::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;66407:12:::1;-1:-1:-1::0;;;;;66407:32:0::1;;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;66407:34:0;66385:127:::1;;;;-1:-1:-1::0;;;66385:127:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66566:11;:26:::0;;-1:-1:-1;;;;;;66566:26:0::1;-1:-1:-1::0;;;;;66566:26:0;;;::::1;::::0;;;::::1;::::0;;66304:296::o;65595:193::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;65724:26:::1;:56:::0;65595:193::o;64226:176::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;64346:22:::1;:48:::0;;-1:-1:-1;;64346:48:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;64226:176::o;59009:38::-;;;;:::o;65183:126::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;65267:15:::1;:34:::0;65183:126::o;44895:311::-;45014:8;-1:-1:-1;;;;;44998:24:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;44998:24:0;;;44990:78;;;;-1:-1:-1;;;44990:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45126:8;45081:18;:32;45100:12;:10;:12::i;:::-;-1:-1:-1;;;;;45081:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;45081:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;45081:53:0;;;;;;;;;;;45165:12;:10;:12::i;:::-;-1:-1:-1;;;;;45150:48:0;;45189:8;45150:48;;;;;;;;;;;;;;;;;;;;44895:311;;:::o;60966:50::-;;;;:::o;59915:48::-;;;;:::o;77357:196::-;77469:7;77501:44;77519:9;77530:7;77539:5;77501:17;:44::i;:::-;77494:51;77357:196;-1:-1:-1;;;77357:196:0:o;81776:1641::-;27168:1;27774:7;;:19;;27766:63;;;;;-1:-1:-1;;;27766:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;27168:1;27907:7;:18;;;;81898::::1;81919:7;81927:3;81919:12;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;82002:13;::::0;::::1;::::0;81919:12;;-1:-1:-1;;;;82002:13:0;::::1;-1:-1:-1::0;;;;;82002:13:0::1;81994:58;;;::::0;;-1:-1:-1;;;81994:58:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;82098:21;82085:9;::::0;::::1;::::0;-1:-1:-1;;;82085:9:0;::::1;;;:34;::::0;::::1;;;;;;;82063:113;;;::::0;;-1:-1:-1;;;82063:113:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;82272:20;82288:3;82272:15;:20::i;:::-;82264:70;;;;-1:-1:-1::0;;;82264:70:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82432:12;::::0;::::1;::::0;82424:7:::1;:21:::0;;82400::::1;::::0;-1:-1:-1;;;82432:12:0;::::1;;;::::0;82424:21;::::1;;;;;;;;;;;;;;;82400:45;;82456:19;82478:7;82486:3;:10;;;;;;;;;;;;82478:19;;;;;;;;;;;::::0;;;::::1;::::0;;82687:11:::1;::::0;82722;;82478:19:::1;::::0;;::::1;::::0;;::::1;82748:9:::0;;82687:11;82772:14;;::::1;::::0;82809:20:::1;::::0;::::1;::::0;82478:19;;-1:-1:-1;82478:19:0;;;;-1:-1:-1;;;;;82687:11:0::1;::::0;:20:::1;::::0;82722:11;;82748:9;;82772:14:::1;-1:-1:-1::0;;;82772:14:0;;::::1;;::::0;82801:36:::1;::::0;-1:-1:-1;;;;;82809:20:0::1;::::0;82801:33:::1;:36::i;:::-;82687:161;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;82687:161:0;;::::1;::::0;::::1;::::0;;;;;;82861:20;;;82892:10:::1;::::0;;::::1;:32:::0;;-1:-1:-1;;82892:32:0::1;;::::0;::::1;;::::0;;82935:9:::1;::::0;::::1;:35:::0;;82687:161;;-1:-1:-1;82687:161:0;;-1:-1:-1;82687:161:0;;-1:-1:-1;82892:10:0;82935:9;-1:-1:-1;;;;82935:35:0::1;-1:-1:-1::0;;;82892:10:0;82935:35:::1;;;;;83025:56;83068:12;83026:36;83046:15;;83026;;:19;;:36;;;;:::i;:::-;83025:42:::0;::::1;:56::i;:::-;82981:20;::::0;::::1;:111:::0;;-1:-1:-1;;82981:111:0::1;-1:-1:-1::0;;;;;82981:111:0;;::::1;;-1:-1:-1::0;;;;83103:47:0::1;-1:-1:-1::0;;;83103:47:0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;83237:15:0;:19;83233:88:::1;;83293:15;::::0;83273:36:::1;::::0;:10:::1;::::0;:36;::::1;;;::::0;::::1;::::0;;;83293:15;83273:10;:36;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;83233:88;83370:39;::::0;;;;;::::1;::::0;::::1;::::0;;;;;83381:3;;83370:39:::1;::::0;;;;;;::::1;-1:-1:-1::0;;27124:1:0;28086:7;:22;-1:-1:-1;;;;;81776:1641:0:o;67839:176::-;67943:4;67972:30;67982:8;67992:9;67972;:30::i;:::-;68006:1;67972:35;;67839:176;-1:-1:-1;;;67839:176:0:o;64489:331::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;64655:3:::1;64630:21;;:28;;64608:147;;;;-1:-1:-1::0;;;64608:147:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64766:21;:46:::0;64489:331::o;68524:322::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;68684:6;-1:-1:-1;;;;;68705:25:0;::::1;68701:79;;68761:7;:5;:7::i;:::-;68747:21;;68701:79;68792:46;68810:5;68817:7;68826:11;68792:17;:46::i;64031:104::-:0;66972:12;:10;:12::i;:::-;66958:10;;-1:-1:-1;;;;;66958:10:0;;;:26;;;66936:111;;;;-1:-1:-1;;;66936:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64103:10:::1;:24:::0;;-1:-1:-1;;;;;;64103:24:0::1;-1:-1:-1::0;;;;;64103:24:0;;;::::1;::::0;;;::::1;::::0;;64031:104::o;59353:29::-;;;-1:-1:-1;;;;;59353:29:0;;:::o;58912:34::-;;;;:::o;45278:160::-;-1:-1:-1;;;;;45393:27:0;;;45369:4;45393:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;45278:160::o;60518:41::-;;;;;;:::o;45510:924::-;-1:-1:-1;;;;;45736:16:0;;45728:66;;;;-1:-1:-1;;;45728:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45835:12;:10;:12::i;:::-;-1:-1:-1;;;;;45827:20:0;:4;-1:-1:-1;;;;;45827:20:0;;:60;;;;45851:36;45868:4;45874:12;:10;:12::i;45851:36::-;45805:151;;;;-1:-1:-1;;;45805:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45969:16;45988:12;:10;:12::i;:::-;45969:31;;46013:96;46034:8;46044:4;46050:2;46054:21;46072:2;46054:17;:21::i;:::-;46077:25;46095:6;46077:17;:25::i;:::-;46104:4;46013:20;:96::i;:::-;46144:77;46168:6;46144:77;;;;;;;;;;;;;;;;;:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;46144:19:0;;;;;;;;;;;:77;:23;:77::i;:::-;46122:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;46122:19:0;;;;;;;;;;:99;;;;46252:17;;;;;;:29;;46274:6;46252:21;:29::i;:::-;46232:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;46232:17:0;;;;;;;;;;;;;:49;;;;46299:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46358:68;46389:8;46399:4;46405:2;46409;46413:6;46421:4;46358:30;:68::i;61121:31::-;;;-1:-1:-1;;;;;61121:31:0;;:::o;57536:244::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;57625:22:0;::::1;57617:73;;;;-1:-1:-1::0;;;57617:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57727:6;::::0;;57706:38:::1;::::0;-1:-1:-1;;;;;57706:38:0;;::::1;::::0;57727:6;::::1;::::0;57706:38:::1;::::0;::::1;57755:6;:17:::0;;-1:-1:-1;;;;;;57755:17:0::1;-1:-1:-1::0;;;;;57755:17:0;;;::::1;::::0;;;::::1;::::0;;57536:244::o;63844:122::-;56813:12;:10;:12::i;:::-;56803:6;;-1:-1:-1;;;;;56803:6:0;;;:22;;;56795:67;;;;;-1:-1:-1;;;56795:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56795:67:0;;;;;;;;;;;;;;;63926:14:::1;:32:::0;;-1:-1:-1;;;;;;63926:32:0::1;-1:-1:-1::0;;;;;63926:32:0;;;::::1;::::0;;;::::1;::::0;;63844:122::o;77699:257::-;77759:4;77776:21;77800:7;77808:3;77800:12;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77844:12:0;;;;-1:-1:-1;;;77844:12:0;;;;:37;;;;;;;;;77843:105;;;;-1:-1:-1;77900:23:0;;;-1:-1:-1;;;;;77934:12:0;77900:47;;:23;;:47;;;;-1:-1:-1;;77699:257:0:o;12357:181::-;12415:7;12447:5;;;12471:6;;;;12463:46;;;;;-1:-1:-1;;;12463:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;23845:151;23929:4;23953:35;23963:3;23983;23953:9;:35::i;23619:142::-;23696:4;23720:33;23728:3;23748;23720:7;:33::i;5497:422::-;5864:20;5903:8;;;5497:422::o;28763:106::-;28851:10;28763:106;:::o;48575:88::-;48642:13;;;;:4;;:13;;;;;:::i;24934:162::-;25013:7;25056:30;25061:3;25081;25056:4;:30::i;90107:400::-;90321:9;90316:184;90340:3;:10;90336:1;:14;90316:184;;;90376:39;90408:3;90412:1;90408:6;;;;;;;;;;;;;;90376:22;:31;;:39;;;;:::i;:::-;90372:117;;;90436:37;90466:3;90470:1;90466:6;;;;;;;;;;;;;;90436:22;:29;;:37;;;;:::i;:::-;;90372:117;90352:3;;90316:184;;;;90107:400;;;;;;:::o;13260:192::-;13346:7;13382:12;13374:6;;;;13366:29;;;;-1:-1:-1;;;13366:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;13418:5:0;;;13260:192::o;54417:799::-;54671:15;:2;-1:-1:-1;;;;;54671:13:0;;:15::i;:::-;54667:542;;;54724:2;-1:-1:-1;;;;;54707:43:0;;54751:8;54761:4;54767:3;54772:7;54781:4;54707:79;;;;;;;;;;;;;-1:-1:-1;;;;;54707:79:0;;;;;;-1:-1:-1;;;;;54707:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54707:79:0;;;54703:495;;;;:::i;:::-;;;;;;;;55064:14;;-1:-1:-1;;;55064:14:0;;;;;;;;;;;;;;;;;55071:6;;55064:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54703:495;55120:62;;-1:-1:-1;;;55120:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54703:495;-1:-1:-1;;;;;;54836:64:0;;-1:-1:-1;;;54836:64:0;54832:163;;54925:50;;-1:-1:-1;;;54925:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86046:1017;86179:7;86218:12;86246:7;86241:64;;86292:1;86281:12;86241:64;86317:19;86339:7;86347;86339:16;;;;;;;;;;;;;;;;;;;;;86414:15;;;;86339:16;;-1:-1:-1;86393:37:0;;-1:-1:-1;;;86414:15:0;;;;86393:20;:37::i;:::-;86466:27;;;;86366:64;;-1:-1:-1;;;;86466:27:0;;;;;-1:-1:-1;;;86508:32:0;;-1:-1:-1;;;;;86508:32:0;-1:-1:-1;;86504:94:0;;;-1:-1:-1;86585:1:0;86504:94;86610:21;86634:7;86642:9;86634:18;;;;;;;;;;;;;;;;;;;;;86713:17;;;;86634:18;;-1:-1:-1;86692:39:0;;-1:-1:-1;;;86713:17:0;;;;86692:20;:39::i;:::-;86769:29;;;;86663:68;;-1:-1:-1;;;;86769:29:0;;;;;-1:-1:-1;;;86813:34:0;;-1:-1:-1;;;;;86813:34:0;-1:-1:-1;;86809:98:0;;;-1:-1:-1;86894:1:0;86809:98;86939:116;87000:40;:18;87023:16;87000:22;:40::i;:::-;86940:36;:16;86961:14;86940:20;:36::i;86939:116::-;86919:136;86046:1017;-1:-1:-1;;;;;;;;;;;86046:1017:0:o;84432:703::-;84573:4;84654:29;84664:7;84673:9;84654;:29::i;:::-;84649:75;;-1:-1:-1;84707:5:0;84700:12;;84649:75;84787:27;84797:7;84806;84787:9;:27::i;:::-;84783:71;;;-1:-1:-1;84838:4:0;84831:11;;84783:71;84981:40;:22;85013:7;84981:31;:40::i;:::-;84977:126;;;-1:-1:-1;;;;;85045:46:0;;:35;:22;85072:7;85045:26;:35::i;:::-;-1:-1:-1;;;;;85045:46:0;;85038:53;;;;84977:126;-1:-1:-1;85122:5:0;84432:703;;;;;:::o;85346:256::-;85444:4;85504:23;85487:40;:13;;;;-1:-1:-1;;;85487:13:0;;;;:40;;;;;;;;;85486:108;;;;-1:-1:-1;;85546:24:0;;;-1:-1:-1;;;;;85580:12:0;85546:47;;:24;;:47;;85346:256::o;89296:608::-;89471:4;89550:7;89537:9;:20;89533:65;;;-1:-1:-1;89581:5:0;89574:12;;89533:65;89665:16;;;;-1:-1:-1;;;89665:16:0;;;;:27;;;:56;;-1:-1:-1;89696:14:0;;;;-1:-1:-1;;;89696:14:0;;;;:25;;89665:56;89661:101;;;-1:-1:-1;89745:5:0;89738:12;;89661:101;89776:14;;;;-1:-1:-1;;;89776:14:0;;;;:27;;;:56;;-1:-1:-1;89807:12:0;;;;-1:-1:-1;;;89807:12:0;;;;:25;;89776:56;89772:101;;;-1:-1:-1;89856:5:0;89849:12;;89772:101;-1:-1:-1;89892:4:0;89296:608;;;;;;;:::o;87221:1725::-;87311:7;87392:16;87411:43;87429:9;87440:7;87449:4;87411:17;:43::i;:::-;87392:62;;87467:17;87487:44;87527:3;87487:35;87500:21;;87487:8;:12;;:35;;;;:::i;:::-;:39;;:44::i;:::-;87467:64;;87542:21;87566:74;87626:3;87566:41;87585:21;;87579:3;:27;87566:8;:12;;:41;;;;:::i;:74::-;87660:4;;87690:10;;;87660:52;;;-1:-1:-1;;;87660:52:0;;87678:10;87660:52;;;;;;;-1:-1:-1;;;;;87690:10:0;;;87660:52;;;;;;;;;;;87542:98;;-1:-1:-1;87660:4:0;;;;:17;;:52;;;;;;;;;;;;;;;:4;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;87660:52:0;87653:60;;;;87731:4;;87761:14;;87731:60;;;-1:-1:-1;;;87731:60:0;;87749:10;87731:60;;;;-1:-1:-1;;;;;87761:14:0;;;87731:60;;;;;;;;;;;;:4;;;;;:17;;:60;;;;;;;;;;;;;;:4;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;87731:60:0;87724:68;;;;87863:19;87885:7;87893;87885:16;;;;;;;;;;;;;;;;;;87863:38;;87912:21;87936:7;87944:9;87936:18;;;;;;;;;;;;;;;;;;87912:42;;88025:32;88052:4;88025:26;:32::i;:::-;88068:34;88095:6;88068:26;:34::i;:::-;88204:17;;;;;88236:15;;;;88204:17;-1:-1:-1;;;88204:17:0;;;;;;;88236:15;;;;:35;-1:-1:-1;88232:95:0;;;-1:-1:-1;88300:15:0;;;;-1:-1:-1;;;88300:15:0;;;;88232:95;88425:16;88444;:9;88458:1;88444:13;:16::i;:::-;88425:35;;88524:24;88551:81;88609:12;88552:37;88573:15;;88552:16;;:20;;:37;;;;:::i;88551:81::-;88524:108;;88645:13;88661:146;88686:9;88710:7;88732:8;88755:16;88786:10;88661;:146::i;:::-;88861:52;;;;;;;;;;;;;;;;;;;;88645:162;;-1:-1:-1;88645:162:0;;88861:52;;;;;;;;;88933:5;87221:1725;-1:-1:-1;;;;;;;;;;;87221:1725:0:o;31306:120::-;30851:7;;;;30843:40;;;;;-1:-1:-1;;;30843:40:0;;;;;;;;;;;;-1:-1:-1;;;30843:40:0;;;;;;;;;;;;;;;31365:7:::1;:15:::0;;-1:-1:-1;;31365:15:0::1;::::0;;31396:22:::1;31405:12;:10;:12::i;:::-;31396:22;::::0;;-1:-1:-1;;;;;31396:22:0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;31306:120::o:0;23277:176::-;23366:4;23390:55;23395:3;23415;-1:-1:-1;;;;;23429:14:0;;23390:4;:55::i;63240:265::-;63341:7;63386:111;63424:58;63477:4;63424:48;63440:31;;63424:11;:15;;:48;;;;:::i;:::-;:52;;:58::i;:::-;63386:15;;;:19;:111::i;92970:587::-;93147:16;:3;-1:-1:-1;;;;;93147:14:0;;:16::i;:::-;93143:407;;;93202:115;;;-1:-1:-1;;;93202:115:0;;-1:-1:-1;;;93202:115:0;;;;;;-1:-1:-1;;;;;93202:30:0;;;;;:115;;;;;;;;;;;;;;:30;:115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93202:115:0;93180:359;;;93380:3;-1:-1:-1;;;;;93352:60:0;;93435:3;93461:10;93494;93352:171;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93180:359;92970:587;;;;:::o;71945:1565::-;72098:16;72165:1;72149:6;:13;:17;72127:109;;;;-1:-1:-1;;;72127:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72286:9;:16;72269:6;:13;:33;72247:129;;;;-1:-1:-1;;;72247:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72413:7;:14;72475:13;;72438:20;;-1:-1:-1;;;;;72461:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72461:28:0;;72438:51;;72500:23;72540:6;:13;-1:-1:-1;;;;;72526:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72526:28:0;;72500:54;;72572:9;72567:814;72591:6;:13;72587:1;:17;72567:814;;;60872:4;72652:31;;:9;72662:1;72652:12;;;;;;;;;;;;;;:31;;72626:121;;;;;-1:-1:-1;;;72626:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;72764:21;;:::i;:::-;72788:474;;;;;;;;72820:6;72827:1;72820:9;;;;;;;;;;;;;;72788:474;;;;72863:9;72873:1;72863:12;;;;;;;;;;;;;;;;;;;72788:474;;;;-1:-1:-1;;;;;72913:3:0;72788:474;;;;;-1:-1:-1;72788:474:0;;;;;;73009:1;72788:474;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60670:2;72788:474;;;;;;;;;73279:7;:21;;;;;;;;-1:-1:-1;73279:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;73279:21:0;;;;;;;;-1:-1:-1;;73279:21:0;-1:-1:-1;;;;;;;;73279:21:0;;;;;-1:-1:-1;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;;;;;;-1:-1:-1;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;-1:-1:-1;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;;;-1:-1:-1;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;;;;-1:-1:-1;;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;73279:21:0;;;;;;;;;;-1:-1:-1;;;;73279:21:0;-1:-1:-1;;;73279:21:0;;;;;;;;;;;;;;;;;;-1:-1:-1;73279:21:0;;;;;;;-1:-1:-1;;;;73279:21:0;;;;-1:-1:-1;;;73279:21:0;;;;;;;;;;;;;;;;;73340:1;73324:13;:17;73315:3;73319:1;73315:6;;;;;;;;;;;;;:26;;;;;73368:1;73356:6;73363:1;73356:9;;;;;;;;;;;;;;;;;:13;-1:-1:-1;72606:3:0;;72567:814;;;;73393:35;73404:6;73412:3;73417:6;73393:35;;;;;;;;;;;;:10;:35::i;:::-;73446:33;73456:3;73461:6;73469:9;73446:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73499:3:0;71945:1565;-1:-1:-1;;;;;71945:1565:0:o;31047:118::-;30575:7;;;;30574:8;30566:37;;;;;-1:-1:-1;;;30566:37:0;;;;;;;;;;;;-1:-1:-1;;;30566:37:0;;;;;;;;;;;;;;;31107:7:::1;:14:::0;;-1:-1:-1;;31107:14:0::1;31117:4;31107:14;::::0;;31137:20:::1;31144:12;:10;:12::i;85743:213::-:0;85811:4;;85849:35;;12821:136;12879:7;12906:43;12910:1;12913;12906:43;;;;;;;;;;;;;;;;;:3;:43::i;14658:132::-;14716:7;14743:39;14747:1;14750;14743:39;;;;;;;;;;;;;;;;;:3;:39::i;70823:927::-;70950:7;60872:4;70978:26;;;70970:67;;;;;-1:-1:-1;;;70970:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;71050:21;;:::i;:::-;71074:417;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;71178:3:0;71074:417;;;;;;;;-1:-1:-1;71074:417:0;;;;;;71266:1;71074:417;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60670:2;71074:417;;;;;;;;71504:7;:21;;;;;;;;-1:-1:-1;71504:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;71504:21:0;;;;;;;;-1:-1:-1;;71504:21:0;-1:-1:-1;;;;;;;;71504:21:0;;;;;-1:-1:-1;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;;;;;;-1:-1:-1;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;-1:-1:-1;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;;;-1:-1:-1;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;;;;-1:-1:-1;;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;71504:21:0;;;;;;;;;;-1:-1:-1;;;;71504:21:0;-1:-1:-1;;;71504:21:0;;;;;;;;;;;;;;;;;;-1:-1:-1;71504:21:0;;;;;;;-1:-1:-1;;;;71504:21:0;;;;-1:-1:-1;;;71504:21:0;;;;;;;;;;;;;;;;;71536:19;71575:1;71558:7;:14;;;;:18;71536:40;;71589:33;71595:6;71603:11;71616:1;71589:33;;;;;;;;;;;;:5;:33::i;:::-;71672:39;;;;;;;;;;;;;;71683:11;;71672:39;;;;;;;;71731:11;70823:927;-1:-1:-1;;;;;70823:927:0:o;55224:198::-;55344:16;;;55358:1;55344:16;;;;;;;;;55290;;;;55344;;;;;;;;;;;;-1:-1:-1;55344:16:0;55319:41;;55382:7;55371:5;55377:1;55371:8;;;;;;;;;;;;;;;;;:18;55409:5;55224:198;-1:-1:-1;;55224:198:0:o;53647:762::-;53876:15;:2;-1:-1:-1;;;;;53876:13:0;;:15::i;:::-;53872:530;;;53929:2;-1:-1:-1;;;;;53912:38:0;;53951:8;53961:4;53967:2;53971:6;53979:4;53912:72;;;;;;;;;;;;;-1:-1:-1;;;;;53912:72:0;;;;;;-1:-1:-1;;;;;53912:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53912:72:0;;;53908:483;;;;:::i;:::-;-1:-1:-1;;;;;;54034:59:0;;-1:-1:-1;;;54034:59:0;54030:158;;54118:50;;-1:-1:-1;;;54118:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21247:125;21318:4;21342:17;;;:12;;;;;:17;;;;;;:22;;;21247:125::o;19614:1549::-;19678:4;19813:17;;;:12;;;:17;;;;;;19847:13;;19843:1313;;20279:19;;-1:-1:-1;;20232:12:0;;;;20279:23;;;;20208:21;;20279:3;;:23;;20576;;;;;;;;;;;;;;;;20547:52;;20724:9;20694:3;:12;;20707:13;20694:27;;;;;;;;;;;;;;;;:39;;:27;;;;;:39;;;;;;;;;;;;;;;20814:14;;20801:28;;:12;;;:28;;;;;20832:17;;;20801:48;;20958:18;;20801:3;;20958:18;;;;;;;;;;;;;;-1:-1:-1;;20958:18:0;;;;;;;;;;;;;;;;;;;;;21054:17;;;:12;;;:17;;;;;;21047:24;;;;20958:18;-1:-1:-1;21088:11:0;;-1:-1:-1;;;;21088:11:0;19843:1313;21139:5;21132:12;;;;;22372:149;22438:7;22465:48;22470:3;22475;22465:48;;;;;;;;;;;;;;;;;:4;:48::i;13711:471::-;13769:7;14014:6;14010:47;;-1:-1:-1;14044:1:0;14037:8;;14010:47;14081:5;;;14085:1;14081;:5;:1;14105:5;;;;;:10;14097:56;;;;-1:-1:-1;;;14097:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83789:635;83872:35;;;;83910:12;-1:-1:-1;;;83872:35:0;;;-1:-1:-1;;;;;83872:35:0;:50;83868:401;;;83939:30;;;:34;;-1:-1:-1;;;;83939:34:0;-1:-1:-1;;;83939:34:0;;;83868:401;;;84029:30;;;;84098:22;;84062:1;84029:30;-1:-1:-1;;;84029:30:0;;;;;:34;;84098:22;;;84082:38;;;;84078:117;;;-1:-1:-1;84157:22:0;;;;84078:117;84211:30;;;:46;;;;;;-1:-1:-1;;;84211:46:0;-1:-1:-1;;;;84211:46:0;;;;;;;;;83868:401;84338:67;84392:12;84339:47;84370:15;;84339:26;;:30;;:47;;;;:::i;84338:67::-;84279:7;:35;;;:137;;;;;-1:-1:-1;;;;;84279:137:0;;;;;-1:-1:-1;;;;;84279:137:0;;;;;;83789:635;:::o;69627:1013::-;69817:7;69873:9;69858:26;;69845:9;:39;69837:48;;;;;;69930:7;69915:24;;69904:7;:35;69896:44;;;;;;69989:11;69974:28;;69959:11;:43;69951:52;;;;;;70016:21;;:::i;:::-;70040:448;;;;;;;;-1:-1:-1;70040:448:0;;;;;;;;;-1:-1:-1;;;;;70126:3:0;70040:448;;;;;;;;;;;;;;;70214:1;70040:448;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70501:7;:21;;;;;;;;-1:-1:-1;70501:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70501:21:0;;;;;;;;-1:-1:-1;;70501:21:0;-1:-1:-1;;;;;;;;70501:21:0;;;;;-1:-1:-1;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;;;;;;-1:-1:-1;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;-1:-1:-1;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;;;-1:-1:-1;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;;;;-1:-1:-1;;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70501:21:0;;;;;;;;;;-1:-1:-1;;;;70501:21:0;-1:-1:-1;;;70501:21:0;;;;;;;;;;;;;;;;;;-1:-1:-1;70501:21:0;;;;;;;-1:-1:-1;;;;70501:21:0;;;;-1:-1:-1;;;70501:21:0;;;;;;;;;;;;;;;;;70533:13;70566:1;70549:7;:14;;;;:18;70533:34;;70580:27;70586:6;70594:5;70601:1;70580:27;;;;;;;;;;;;:5;:27::i;:::-;70627:5;69627:1013;-1:-1:-1;;;;;;;69627:1013:0:o;18747:692::-;18823:4;18958:17;;;:12;;;:17;;;;;;18992:13;18988:444;;-1:-1:-1;;19077:38:0;;;;;;;;;;;;;;;;;;19059:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;19274:19;;19254:17;;;:12;;;:17;;;;;;;:39;19308:11;;18988:444;19388:5;19352:3;:12;;19376:1;19365:8;:12;19352:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;19415:5;19408:12;;;;;49998:715;-1:-1:-1;;;;;50133:16:0;;50125:62;;;;-1:-1:-1;;;50125:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50220:7;:14;50206:3;:10;:28;50198:81;;;;-1:-1:-1;;;50198:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50292:16;50311:12;:10;:12::i;:::-;50292:31;;50336:66;50357:8;50375:1;50379:2;50383:3;50388:7;50397:4;50336:20;:66::i;:::-;50420:6;50415:126;50436:3;:10;50432:1;:14;50415:126;;;50492:37;50507:9;:17;50517:3;50521:1;50517:6;;;;;;;;;;;;;;50507:17;;;;;;;;;;;:21;50525:2;-1:-1:-1;;;;;50507:21:0;-1:-1:-1;;;;;50507:21:0;;;;;;;;;;;;;50492:7;50500:1;50492:10;;;;;;;;;;;;;;:14;;:37;;;;:::i;:::-;50468:9;:17;50478:3;50482:1;50478:6;;;;;;;;;;;;;;;;;;;50468:17;;;;;;;;;;;;;-1:-1:-1;50468:17:0;;;-1:-1:-1;;;;;50468:21:0;;;;;;;;;:61;50448:3;;50415:126;;;;50594:2;-1:-1:-1;;;;;50558:53:0;50590:1;-1:-1:-1;;;;;50558:53:0;50572:8;-1:-1:-1;;;;;50558:53:0;;50598:3;50603:7;50558:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50624:81;50660:8;50678:1;50682:2;50686:3;50691:7;50700:4;50624:35;:81::i;15286:278::-;15372:7;15407:12;15400:5;15392:28;;;;-1:-1:-1;;;15392:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15431:9;15447:1;15443;:5;;;;;;;15286:278;-1:-1:-1;;;;;15286:278:0:o;49059:583::-;-1:-1:-1;;;;;49174:21:0;;49166:67;;;;-1:-1:-1;;;49166:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49246:16;49265:12;:10;:12::i;:::-;49246:31;;49290:107;49311:8;49329:1;49333:7;49342:21;49360:2;49342:17;:21::i;49290:107::-;49435:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;49435:22:0;;;;;;;;;;:34;;49462:6;49435:26;:34::i;:::-;49410:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;49410:22:0;;;;;;;;;;;;:59;;;;49485:57;;;;;;;;;;;;;49410:22;;49485:57;;;;;;;;;;;;49555:79;49586:8;49604:1;49608:7;49617:2;49621:6;49629:4;49555:30;:79::i;22634:319::-;22728:7;22767:17;;;:12;;;:17;;;;;;22818:12;22803:13;22795:36;;;;-1:-1:-1;;;22795:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22885:3;:12;;22909:1;22898:8;:12;22885:26;;;;;;;;;;;;;;;;;;:33;;;22878:40;;;22634:319;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;110:106;195:3;191:15;;163:53::o;224:739::-;;297:4;279:16;276:26;273:2;;;305:5;;273:2;339:1;-1:-1;;318:23;414:10;357:34;-1:-1;382:8;357:34;:::i;:::-;406:19;396:2;;429:5;;396:2;460;454:9;496:16;-1:-1;;492:24;339:1;454:9;468:49;543:4;537:11;624:16;-1:-1;;;;;624:16;617:4;609:6;605:17;602:39;576:18;568:6;565:30;556:91;553:2;;;655:5;;;;;;553:2;693:6;687:4;683:17;672:28;;725:3;719:10;705:24;;576:18;740:6;737:30;734:2;;;770:5;;;;;;734:2;;847:16;841:4;837:27;807:4;814:6;802:3;794:27;;829:36;826:2;;;868:5;;;;;826:2;89:7;73:14;-1:-1;;69:28;892:50;;807:4;892:50;460:2;881:62;900:3;-1:-1;;267:696;:::o

Swarm Source

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