ETH Price: $3,217.59 (+5.36%)

Token

Squiggly (~~)
 

Overview

Max Total Supply

100 ~~

Holders

54

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
4 ~~
0x2A538000A53f38D89F37Fa43A301CeE2c0F9E331
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Randomly generated and fully on-chain squiggly line art, the first project in the Atlantes series. Hard capped at 100.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
squigglyWTF

Compiler Version
v0.5.14+commit.01f1aaa4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

pragma solidity ^0.5.14;

/*
 * @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.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        return msg.sender;
    }

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


// File: node_modules\@openzeppelin\contracts\ownership\Ownable.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.
 *
 * 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 {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @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(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _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 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

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

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

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

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApprovalForAll}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApprovalForAll}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a {IERC721-safeTransferFrom}. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

/**
 * @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.
     *
     * _Available since v2.4.0._
     */
    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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing 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.
     */
    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.

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

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @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].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

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

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

    function increment(Counter storage counter) internal {
        counter._value += 1;
    }

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

/**
 * @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) external view 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 {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

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

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

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

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

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

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

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

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != _msgSender(), "ERC721: approve to caller");

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

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the _msgSender() to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransferFrom(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
        _transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _safeMint(address to, uint256 tokenId) internal {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

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

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

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

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This function is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }

        bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data);
        return (retval == _ERC721_RECEIVED);
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Enumerable is IERC721 {
    function totalSupply() public view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) public view returns (uint256);
}

/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => uint256[]) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev Constructor function.
     */
    constructor () public {
        // register the supported interface to conform to ERC721Enumerable via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev Gets the token ID at a given index of the tokens list of the requested owner.
     * @param owner address owning the tokens list to be accessed
     * @param index uint256 representing the index to be accessed of the requested tokens list
     * @return uint256 token ID at the given index of the tokens list owned by the requested address
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev Gets the total amount of tokens stored by the contract.
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev Gets the token ID at a given index of all the tokens in this contract
     * Reverts if the index is greater or equal to the total number of tokens.
     * @param index uint256 representing the index to be accessed of the tokens list
     * @return uint256 token ID at the given index of the tokens list
     */
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);

        _removeTokenFromOwnerEnumeration(from, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to address the beneficiary that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        super._mint(to, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);

        _addTokenToAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {ERC721-_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        _removeTokenFromOwnerEnumeration(owner, tokenId);
        // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
        _ownedTokensIndex[tokenId] = 0;

        _removeTokenFromAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Gets the list of token IDs of the requested owner.
     * @param owner address owning the tokens
     * @return uint256[] List of token IDs owned by the requested address
     */
    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
        return _ownedTokens[owner];
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
        _ownedTokens[to].push(tokenId);
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        _ownedTokens[from].length--;

        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
        // lastTokenId, or just over the end of the array if the token was the last one).
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length.sub(1);
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        _allTokens.length--;
        _allTokensIndex[tokenId] = 0;
    }
}

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;
    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

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

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }
     

    /**
     * @dev Internal function to set the token URI for a given token.
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to set its URI
     * @param uri string URI to assign
     */
    function _setTokenURI(uint256 tokenId, string memory uri) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = uri;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

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

/**
 * @title Full ERC721 Token
 * @dev This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology.
 *
 * See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
    constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks
    }
}

/**
 * @title Helps contracts guard against reentrancy attacks.
 * @author Remco Bloemen <remco@2Ï€.com>, Eenae <[email protected]>
 * @dev If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard {
    /// @dev counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    constructor() public {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @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() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter);
    }
}


/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}


library RandomSalt
{
	/**
	* Initialize the pool with the entropy of the blockhashes of the blocks in the closed interval [earliestBlock, latestBlock]
	* The argument "seed" is optional and can be left zero in most cases.
	* This extra seed allows you to select a different sequence of random numbers for the same block range.
	*/
	function init(uint256 earliestBlock, uint256 latestBlock, uint256 seed) internal view returns (bytes32[] memory) {
		require(block.number-1 >= latestBlock && latestBlock >= earliestBlock, "RandomSalt.init: invalid block interval");
		bytes32[] memory pool = new bytes32[](latestBlock-earliestBlock+2);
		bytes32 salt = keccak256(abi.encodePacked(block.number,seed));
		for(uint256 i=0; i<=latestBlock-earliestBlock; i++) {
			// Add some salt to each blockhash so that we don't reuse those hash chains
			// when this function gets called again in another block.
			pool[i+1] = keccak256(abi.encodePacked(blockhash(earliestBlock+i),salt));
		}
		return pool;
	}
	
	/**
	* Initialize the pool from the latest "num" blocks.
	*/
	function initLatest(uint256 num, uint256 seed) internal view returns (bytes32[] memory) {
		return init(block.number-num, block.number-1, seed);
	}
	
	/**
	* Advances to the next 256-bit random number in the pool of hash chains.
	*/
	function next(bytes32[] memory pool) internal pure returns (uint256) {
		require(pool.length > 1, "RandomSalt.next: invalid pool");
		uint256 roundRobinIdx = uint256(pool[0]) % (pool.length-1) + 1;
		bytes32 hash = keccak256(abi.encodePacked(pool[roundRobinIdx]));
		pool[0] = bytes32(uint256(pool[0])+1);
		pool[roundRobinIdx] = hash;
		return uint256(hash);
	}
	
	/**
	* Produces random integer values, uniformly distributed on the closed interval [a, b]
	*/
	function uniform(bytes32[] memory pool, int256 a, int256 b) internal pure returns (int256) {
		require(a <= b, "RandomSalt.uniform: invalid interval");
		return int256(next(pool)%uint256(b-a+1))+a;
	}
}

library Random {
    /**
    * Initialize the pool from some seed.
    */
    function init(uint256 seed) internal pure returns (bytes32[] memory) {
        bytes32[] memory hashchain = new bytes32[](1);
        hashchain[0] = bytes32(seed);
        return hashchain;
    }
    
    /**
    * Advances to the next 256-bit random number in the pool of hash chains.
    */
    function next(bytes32[] memory hashchain) internal pure returns (uint256) {
        require(hashchain.length == 1, "Random.next: invalid param");
        hashchain[0] = keccak256(abi.encodePacked(hashchain[0]));
        return uint256(hashchain[0]);
    }
    
    /**
    * Produces random integer values, uniformly distributed on the closed interval [a, b]
    */
    function uniform_int(bytes32[] memory hashchain, int256 a, int256 b) internal pure returns (int256) {
        require(a <= b, "Random.uniform_int: invalid interval");
        return int256(next(hashchain)%uint256(b-a+1))+a;
    }
    
    /**
    * Produces random integer values, uniformly distributed on the closed interval [a, b]
    */
    function uniform_uint(bytes32[] memory hashchain, uint256 a, uint256 b) internal pure returns (uint256) {
        require(a <= b, "Random.uniform_uint: invalid interval");
        return next(hashchain)%(b-a+1)+a;
    }
}
 
library Buffer {
    function hasCapacityFor(bytes memory buffer, uint256 needed) internal pure returns (bool) {
        uint256 size;
        uint256 used;
        assembly {
            size := mload(buffer)
            used := mload(add(buffer, 32))
        }
        return size >= 32 && used <= size - 32 && used + needed <= size - 32;
    }
    
    function toString(bytes memory buffer) internal pure returns (string memory) {
        require(hasCapacityFor(buffer, 0), "Buffer.toString: invalid buffer");
        string memory ret;
        assembly {
            ret := add(buffer, 32)
        }
        return ret;
    }
    
    function append(bytes memory buffer, string memory str) internal view {
        require(hasCapacityFor(buffer, bytes(str).length), "Buffer.append: no capacity");
        assembly {
            let len := mload(add(buffer, 32))
            pop(staticcall(gas, 0x4, add(str, 32), mload(str), add(len, add(buffer, 64)), mload(str)))
            mstore(add(buffer, 32), add(len, mload(str)))
        }
    }
    
    /**
     * value must be in the closed interval [-999, 999]
     * otherwise only the last 3 digits will be converted
     */
    function numbie(bytes memory buffer, int256 value) internal pure {
        require(hasCapacityFor(buffer, 4), "Buffer.numbie: no capacity");
        assembly {
            function numbx1(x, v) -> y {
                // v must be in the closed interval [0, 9]
                // otherwise it outputs junk
                mstore8(x, add(v, 48))
                y := add(x, 1)
            }
            function numbx2(x, v) -> y {
                // v must be in the closed interval [0, 99]
                // otherwise it outputs junk
                y := numbx1(numbx1(x, div(v, 10)), mod(v, 10))
            }
            function numbu3(x, v) -> y {
                // v must be in the closed interval [0, 999]
                // otherwise only the last 3 digits will be converted
                switch lt(v, 100)
                case 0 {
                    // without input value sanitation: y := numbx2(numbx1(x, div(v, 100)), mod(v, 100))
                    y := numbx2(numbx1(x, mod(div(v, 100), 10)), mod(v, 100))
                }
                default {
                    switch lt(v, 10)
                    case 0 { y := numbx2(x, v) }
                    default { y := numbx1(x, v) }
                }
            }
            function numbi3(x, v) -> y {
                // v must be in the closed interval [-999, 999]
                // otherwise only the last 3 digits will be converted
                if slt(v, 0) {
                    v := add(not(v), 1)
                    mstore8(x, 45)  // minus sign
                    x := add(x, 1)
                }
                y := numbu3(x, v)
            }
            let strIdx := add(mload(add(buffer, 32)), add(buffer, 64))
            strIdx := numbi3(strIdx, value)
            mstore(add(buffer, 32), sub(sub(strIdx, buffer), 64))
        }
    }
    
    function hexrgb(bytes memory buffer, uint256 r, uint256 g, uint256 b) internal pure {
        require(hasCapacityFor(buffer, 6), "Buffer.hexrgb: no capacity");
        assembly {
            function hexrgb(x, r, g, b) -> y {
                let rhi := and(shr(4, r), 0xf)
                let rlo := and(r, 0xf)
                let ghi := and(shr(4, g), 0xf)
                let glo := and(g, 0xf)
                let bhi := and(shr(4, b), 0xf)
                let blo := and(b, 0xf)
                mstore8(x,         add(add(rhi, mul(div(rhi, 10), 39)), 48))
                mstore8(add(x, 1), add(add(rlo, mul(div(rlo, 10), 39)), 48))
                mstore8(add(x, 2), add(add(ghi, mul(div(ghi, 10), 39)), 48))
                mstore8(add(x, 3), add(add(glo, mul(div(glo, 10), 39)), 48))
                mstore8(add(x, 4), add(add(bhi, mul(div(bhi, 10), 39)), 48))
                mstore8(add(x, 5), add(add(blo, mul(div(blo, 10), 39)), 48))
                y := add(x, 6)
            }
            let strIdx := add(mload(add(buffer, 32)), add(buffer, 64))
            strIdx := hexrgb(strIdx, r, g, b)
            mstore(add(buffer, 32), sub(sub(strIdx, buffer), 64))
        }
    }
}
 
contract squigglyWTF is ERC721Full, Ownable, ReentrancyGuard {
    using SafeMath for uint256;    
    using Roles for Roles.Role;

    Roles.Role private _auctioneers;
    
    uint8 public totalPromoClaimants;

    mapping(uint256 => address) internal promoClaimantStorage;
    mapping(address => uint256) addressToInkAll;
    mapping(uint8 => address) inkToAddress;
    mapping(uint256 => address) idToCreator;
    mapping(uint256 => uint256) idToSVGSeed;
    mapping(uint256 => string) idToPromoSVG;

    string public squigglyGalleryLink;
    string public referenceURI;
    
    uint8 public totalInk;
    uint8 public constant maximumInk = 100;
    uint8 public constant tokenLimit = 99;
    uint256 public priceOfInk;
    bool public auctionIsLive;
    bool public priceGoUp;
    bool public priceGoDown;
    bool public auctionStarted;
    uint256 public blockTimeCounter;

    constructor() ERC721Full("Squiggly", "~~") public {

    auctionStarted = false;
    auctionIsLive = false;
    priceGoUp = false;
    priceGoDown = false;
    totalPromoClaimants = 0;
    priceOfInk = 20000000000000000;
    referenceURI = "https://squigglywtf.azurewebsites.net/api/HttpTrigger?id=";
    _auctioneers.add(0x63a9dbCe75413036B2B778E670aaBd4493aAF9F3);
    
    }    
    
    function getNumber(uint seed, int min, int max) internal view returns (int256 randomNumber){

    bytes32[] memory pool = RandomSalt.initLatest(1, seed);        
		randomNumber = RandomSalt.uniform(pool, min, max); 
    }
    
    function renderFromSeed(uint256 seed) public view returns (string memory) {
        bytes32[] memory hashchain = Random.init(seed);
        
        bytes memory buffer = new bytes(8192);
        
        uint256 curveType = Random.uniform_uint(hashchain,1,5);
        uint8 squiggleCount = uint8(curveType) + 2;
        uint stopColorBW;
        
        Buffer.append(buffer, "<svg xmlns='http://www.w3.org/2000/svg' width='640' height='640' viewBox='0 0 640 640' style='stroke-width:0; background-color:#121212;'>");
        
        // Draw squiggles. Each squiggle is a pair of <radialGradient> and <path>.
        for(int i=0; i<squiggleCount; i++) {
        
            // append the <radialGradient>
            
            Buffer.append(buffer, "<radialGradient id='grad");
            Buffer.numbie(buffer, i);
            Buffer.append(buffer, "'><stop offset='0%' style='stop-color:#");
            // gradient start color:
            Buffer.hexrgb(buffer, Random.uniform_uint(hashchain,16,255), Random.uniform_uint(hashchain,16,255), Random.uniform_uint(hashchain,16,255));
            
            Buffer.append(buffer, ";stop-opacity:0' /><stop offset='100%' style='stop-color:#");
            // gradient stop color:
            stopColorBW = Random.uniform_uint(hashchain,16,255);
            Buffer.hexrgb(buffer, stopColorBW, stopColorBW, stopColorBW);
            Buffer.append(buffer, ";stop-opacity:1' /></radialGradient>");
            
            // append the <path>
            
            Buffer.append(buffer, "<path fill='url(#grad");
            Buffer.numbie(buffer, i);
            Buffer.append(buffer, ")' stroke='#");
            // path stroke color:
            Buffer.hexrgb(buffer, Random.uniform_uint(hashchain,16,255), Random.uniform_uint(hashchain,16,255), Random.uniform_uint(hashchain,16,255));
            Buffer.append(buffer, "' stroke-width='0' d='m ");
            // path command 'm': Move the current point by shifting the last known position of the path by dx along the x-axis and by dy along the y-axis.
            Buffer.numbie(buffer, Random.uniform_int(hashchain,240,400));  // move dx
            Buffer.append(buffer, " ");
            Buffer.numbie(buffer, Random.uniform_int(hashchain,240,400));  // move dy
            
            if(curveType == 1) {
                Buffer.append(buffer, ' c');
                
                for(int j=0; j<77; j++) {
                    // path command 'c': Draw a cubic Bézier curve.
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dx1
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dy1
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dx2
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dy2
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dx
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-77,77));  // curve dy
                }
                
            } else if(curveType == 2) {
                Buffer.append(buffer, " s");
                
                for(int j=0; j<91; j++) {
                    // path command 's': Draw a smooth cubic Bézier curve.
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-69,69));  // curve dx2
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-69,69));  // curve dy2
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-69,69));  // curve dx
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-69,69));  // curve dy
                }
                
            } else if(curveType == 3) {
                Buffer.append(buffer, ' q');
                
                for(int j=0; j<77; j++) {
                    // path command 'q': Draw a quadratic Bézier curve.
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-47,47));  // curve dx1
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-47,47));  // curve dy1
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-47,47));  // curve dx
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-47,47));  // curve dy
                }
                
            } else if(curveType == 4) {
                Buffer.append(buffer, ' t');
                
                for(int j=0; j<123; j++) {
                    // path command 't': Draw a smooth quadratic Bézier curve.
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-29,29));  // curve dx
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-29,29));  // curve dy
                }
                
            } else if(curveType == 5) {
                
                for(int j=0; j<99; j++) {
                    // no path command: No curve.
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-37,37));  // point dx
                    Buffer.append(buffer, " ");
                    Buffer.numbie(buffer, Random.uniform_int(hashchain,-37,37));  // point dy
                }
                
            }
            
            Buffer.append(buffer, "' />");
            
        }
        
        Buffer.append(buffer, "</svg>");
        
        return Buffer.toString(buffer);
    }

    function ribbonCut() public onlyOwner {
        auctionStarted = true;
    }    

    function startAuction() public nonReentrant {
        require(auctionStarted == true);
        require(auctionIsLive == false);
        require(totalSupply() <= tokenLimit, "Squiggly sale has concluded. Good luck prying one out of the hands of someone on the secondary market.");
        priceOfInk = calculateInkValue();
        blockTimeCounter = block.timestamp + 15000;
        auctionIsLive = true;
        
        inkToAddress[0] = msg.sender;
        inkToAddress[1] = msg.sender;
        addressToInkAll[msg.sender] = addressToInkAll[msg.sender] + 2;
        
        totalInk = 2;
    }
    
    function participateInAuction(uint8 ink) public nonReentrant payable {
        require(ink <= maximumInk - totalInk);
        require(msg.value >= ink * priceOfInk);
        require(auctionIsLive == true);
        require(block.timestamp < blockTimeCounter);

        for(uint8 i=totalInk; i < totalInk + ink; i++){
            inkToAddress[i] = msg.sender;
        }
        
        totalInk = totalInk + ink;
        
        addressToInkAll[msg.sender] = addressToInkAll[msg.sender] + ink;

        uint256 totalSquigglies = totalSupply();
 
        address(0x63a9dbCe75413036B2B778E670aaBd4493aAF9F3).transfer(msg.value/100*65);
        address payable luckyBastard = address(uint160(getLuckyBastard(totalSquigglies)));
        luckyBastard.transfer(msg.value/10);

    }
    
    function calculateInkValue() public view returns (uint256 priceOfInkCalc) {
        if (auctionIsLive == false) {
            if (priceGoUp == true) {
                priceOfInkCalc = priceOfInk*101/100;
            }
            else if (priceGoDown == true) {
                priceOfInkCalc = priceOfInk*99/100;
            }
            else {
                priceOfInkCalc = priceOfInk;
            }
        }
        else {
        priceOfInkCalc = priceOfInk;    
        }
    }
    
    function createSVG() private nonReentrant {
        
        require(totalSupply() <= tokenLimit, "Claimed. Sorry.");
        
        uint256 tokenId = totalSupply();
        
        int luckyCollectorID = getNumber(totalSupply(),0,totalInk - 1);
        address luckyCollectorAddress = inkToAddress[uint8(luckyCollectorID)];
        uint256 seedSVG = uint256(getNumber(1,1,99999999));
        
        idToSVGSeed[tokenId] = seedSVG;
        idToCreator[tokenId] = msg.sender;
        
        _mint(luckyCollectorAddress, tokenId);
        
    }
    
    function createPromo(string memory promoSVG) public onlyOwner {
        require(totalSupply() <= 4);
        
        uint256 tokenId = totalSupply();
        
        idToPromoSVG[tokenId] = promoSVG;
        idToCreator[tokenId] = msg.sender;
        addressToInkAll[msg.sender] = addressToInkAll[msg.sender] + 100;
        
        _mint(msg.sender, tokenId);
    }
    
    function endAuction() public {
        
        if (totalSupply() <= 19) {
        require(block.timestamp >= blockTimeCounter || totalInk == 100);    
        }
        else {
        require(block.timestamp >= blockTimeCounter);            
        }

        require(_auctioneers.has(msg.sender), "Only official Auctioneers can end an auction.");
        
        createSVG();
        auctionIsLive = false;

        for(uint8 i=0; i < 100; i++){
            inkToAddress[i] = 0x0000000000000000000000000000000000000000;
        }
                
        if (totalInk > 80) {
            priceGoUp = true;
            priceGoDown = false;
        }
        else if (totalInk < 60) {
            priceGoDown = true;
            priceGoUp = false;
        }
        else {
            priceGoUp = false;
            priceGoDown = false;
        }
        
        totalInk = 0;
        
        uint256 contractBalance = uint256(address(this).balance);
        uint256 promoRewards = contractBalance/5*2;
        uint256 endAuctionBounty = contractBalance/5*3;
        
    for (uint8 i = 0; i < totalPromoClaimants; i++) {
        address payable promoTransferAddress = address(uint160(promoClaimantStorage[i]));
        promoTransferAddress.transfer(promoRewards/totalPromoClaimants);
        }
        
        address(msg.sender).transfer(endAuctionBounty);    
    }    
    
    function getLuckyBastard(uint256 seed) public view returns (address luckyBastardWinner) {
        uint8 squigglyID = uint8(getNumber(seed, 0, int256(seed - 1)));
        luckyBastardWinner = (ownerOf(squigglyID));
    }

    
    function updateGalleryLink(string memory newURL) public onlyOwner {
        squigglyGalleryLink = newURL;
    }

    function addPromoClaimant(address newPromoClaimant, uint8 newPromoSlot) public onlyOwner {
        require(totalPromoClaimants <= 16);
        require(newPromoSlot <= 15);

        if (promoClaimantStorage[newPromoSlot] == address(0x0000000000000000000000000000000000000000)) {
        totalPromoClaimants = totalPromoClaimants + 1;    
        }
        
        promoClaimantStorage[newPromoSlot] = newPromoClaimant;
    }
    
    function addAuctioneer(address newAuctioneer) public onlyOwner {
        _auctioneers.add(newAuctioneer);
    }
    
    function removeAuctioneer(address newAuctioneer) public onlyOwner {
        _auctioneers.remove(newAuctioneer);
    }

    function integerToString(uint _i) internal pure returns (string memory) {
      if (_i == 0) {
         return "0";
      }
      uint j = _i;
      uint len;
      
      while (j != 0) {
         len++;
         j /= 10;
      }
      bytes memory bstr = new bytes(len);
      uint k = len - 1;
      
      while (_i != 0) {
         bstr[k--] = byte(uint8(48 + _i % 10));
         _i /= 10;
      }
      return string(bstr);
   }

    function tokenURI(uint256 id) external view returns (string memory) {
        require(_exists(id), "ERC721Metadata: URI query for nonexistent token");
        return string(abi.encodePacked(referenceURI, integerToString(uint256(id))));
    }
    
    function getAddressToInkAll(address userAddress) public view returns (uint256 allTimeInk) {
        return addressToInkAll[userAddress];
    }
    
    function getAddressToInk(address userAddress) public view returns (uint8 currentInkCount) {
        for(uint8 i=0; i < 100; i++){
            if(inkToAddress[i] == userAddress) {
                currentInkCount = currentInkCount + 1;
            }  
        }
    }
    
    function getInktoAddress(uint8 ink) public view returns (address userAddress) {
        return inkToAddress[ink];
    }
    
    function getIdToSVG(uint8 tokenId) public view returns (string memory squigglySVG) {
        if(tokenId <= 4){
        squigglySVG = idToPromoSVG[tokenId];
        }
        else {
        squigglySVG = renderFromSeed(idToSVGSeed[tokenId]);
        }
    }
    
    function getIdToCurveType(uint8 tokenId) public view returns (uint256 curveType) {
        bytes32[] memory hashchain = Random.init(idToSVGSeed[tokenId]);
        
        if(tokenId == 0){
        curveType = 4;
        }
        else if(tokenId == 1) {
        curveType = 1;    
        }
        else if(tokenId == 2) {
        curveType = 5;    
        }
        else if(tokenId == 3) {
        curveType = 2;    
        }
        else if(tokenId == 4) {
        curveType = 3;    
        }
        else {
        curveType = Random.uniform_uint(hashchain,1,5);
        }
    }
    
    function getIdToCreator(uint8 tokenId) public view returns (address userAddress) {
        return idToCreator[tokenId];
    }
    
    function updateURI(string memory newURI) public onlyOwner {
        referenceURI = newURI;
    }
    function readStats() public view returns (string memory auctionStatus, uint8 inkRemaining, uint256 artRemaining, int256 secondsRemaining) {

        artRemaining = 100 - totalSupply();
        inkRemaining = maximumInk - totalInk;
        secondsRemaining = int256(blockTimeCounter - block.timestamp);
        
        if (secondsRemaining > 0 && inkRemaining > 0) {
            secondsRemaining = secondsRemaining;
        }
        else if (secondsRemaining > 0 && totalSupply() > 19) {
            secondsRemaining = secondsRemaining;
        }
        else {
            secondsRemaining = 0;
        }

        if (artRemaining == 0) {
            auctionStatus = string('Art sale is over.');
        }
        else if (auctionIsLive == false) {
            auctionStatus = string(abi.encodePacked('Auction is not active. Next token is: ', integerToString(100 - artRemaining)));
        }
        else if (secondsRemaining <= 0) {
            auctionStatus = string('Waiting on Auctioneer to call End Auction.');
        }
        else {
            auctionStatus = string(abi.encodePacked('Auction for token #', integerToString(100 - artRemaining) ,' is live.'));
        }
        
    }    
    
}

Contract Security Audit

Contract ABI

[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"constant":false,"inputs":[{"internalType":"address","name":"newAuctioneer","type":"address"}],"name":"addAuctioneer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPromoClaimant","type":"address"},{"internalType":"uint8","name":"newPromoSlot","type":"uint8"}],"name":"addPromoClaimant","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"auctionIsLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"auctionStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"blockTimeCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"calculateInkValue","outputs":[{"internalType":"uint256","name":"priceOfInkCalc","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"promoSVG","type":"string"}],"name":"createPromo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"endAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getAddressToInk","outputs":[{"internalType":"uint8","name":"currentInkCount","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getAddressToInkAll","outputs":[{"internalType":"uint256","name":"allTimeInk","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"tokenId","type":"uint8"}],"name":"getIdToCreator","outputs":[{"internalType":"address","name":"userAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"tokenId","type":"uint8"}],"name":"getIdToCurveType","outputs":[{"internalType":"uint256","name":"curveType","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"tokenId","type":"uint8"}],"name":"getIdToSVG","outputs":[{"internalType":"string","name":"squigglySVG","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint8","name":"ink","type":"uint8"}],"name":"getInktoAddress","outputs":[{"internalType":"address","name":"userAddress","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"getLuckyBastard","outputs":[{"internalType":"address","name":"luckyBastardWinner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maximumInk","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint8","name":"ink","type":"uint8"}],"name":"participateInAuction","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"priceGoDown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"priceGoUp","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"priceOfInk","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"readStats","outputs":[{"internalType":"string","name":"auctionStatus","type":"string"},{"internalType":"uint8","name":"inkRemaining","type":"uint8"},{"internalType":"uint256","name":"artRemaining","type":"uint256"},{"internalType":"int256","name":"secondsRemaining","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"referenceURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAuctioneer","type":"address"}],"name":"removeAuctioneer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"renderFromSeed","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"ribbonCut","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"squigglyGalleryLink","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"startAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenLimit","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalInk","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalPromoClaimants","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"newURL","type":"string"}],"name":"updateGalleryLink","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"newURI","type":"string"}],"name":"updateURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060408051808201825260088152675371756967676c7960c01b602080830191909152825180840190935260028352613f3f60f11b90830152908181620000686301ffc9a760e01b6001600160e01b03620001d116565b620000836380ac58cd60e01b6001600160e01b03620001d116565b6200009e63780e9d6360e01b6001600160e01b03620001d116565b8151620000b390600990602085019062000351565b508051620000c990600a90602084019062000351565b50620000e5635b5e139f60e01b6001600160e01b03620001d116565b50505050620000f96200025660201b60201c565b600c80546001600160a01b0319166001600160a01b0392831617908190556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600d55601a805463ffffffff19169055600f805460ff1916905566470de4df8200006019556040805160608101909152603980825262004a69602083013980516200019b9160179160209091019062000351565b50620001cb7363a9dbce75413036b2b778e670aabd4493aaf9f3600e6200025b60201b62002fbe1790919060201c565b620003f3565b6001600160e01b0319808216141562000231576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b335b90565b6200027082826001600160e01b03620002e816565b15620002c3576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620003315760405162461bcd60e51b815260040180806020018281038252602281526020018062004a476022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200039457805160ff1916838001178555620003c4565b82800160010185558215620003c4579182015b82811115620003c4578251825591602001919060010190620003a7565b50620003d2929150620003d6565b5090565b6200025891905b80821115620003d25760008155600101620003dd565b61464480620004036000396000f3fe6080604052600436106102ff5760003560e01c80638da5cb5b11610190578063c87b56dd116100dc578063efd779bd11610095578063f628fbea1161006f578063f628fbea14610db9578063f80cf19414610dce578063fdbd9b8114610de3578063fe67a54b14610df8576102ff565b8063efd779bd14610d3e578063f0195cd114610d53578063f2fde38b14610d86576102ff565b8063c87b56dd14610c3a578063cbe01bc814610c64578063ce020cdd14610c97578063d237069414610cc1578063e985e9c514610cee578063ee2679bc14610d29576102ff565b8063a22cb46511610149578063b9df332311610123578063b9df332314610af6578063bed2b6ac14610b29578063c30f4a5a14610b5c578063c7c4a9e514610c0d576102ff565b8063a22cb465146109d5578063ad87780514610a10578063b88d4fde14610a25576102ff565b80638da5cb5b1461094c5780638f32d59b146109615780639416b7d81461097657806395d89b411461098b578063987dcb45146109a05780639ad96754146109b5576102ff565b806342842e0e1161024f5780636352211e11610208578063715018a6116101e2578063715018a6146108cb5780637a06f4a5146108e05780637cb351621461090d5780638409b5f014610937576102ff565b80636352211e146108595780636b64c7691461088357806370a0823114610898576102ff565b806342842e0e1461070557806347a9553d146107485780634913e6d21461075d5780634f6ccce714610805578063517626ec1461082f57806356c7627e14610844576102ff565b806318160ddd116102bc57806323b872dd1161029657806323b872dd146105275780632d20fb9d1461056a5780632f745c591461061b5780633a964fc714610654576102ff565b806318160ddd146104af5780631b2b151d146104d65780631eb9a82c14610512576102ff565b806301ffc9a71461030457806306fdde031461034c578063081812fc146103d6578063095ea7b31461041c5780630b413d0b146104575780630e81770f14610484575b600080fd5b34801561031057600080fd5b506103386004803603602081101561032757600080fd5b50356001600160e01b031916610e0d565b604080519115158252519081900360200190f35b34801561035857600080fd5b50610361610e30565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610400600480360360208110156103f957600080fd5b5035610ec7565b604080516001600160a01b039092168252519081900360200190f35b34801561042857600080fd5b506104556004803603604081101561043f57600080fd5b506001600160a01b038135169060200135610f29565b005b34801561046357600080fd5b506104006004803603602081101561047a57600080fd5b503560ff16611051565b34801561049057600080fd5b5061049961106f565b6040805160ff9092168252519081900360200190f35b3480156104bb57600080fd5b506104c4611078565b60408051918252519081900360200190f35b3480156104e257600080fd5b50610455600480360360408110156104f957600080fd5b5080356001600160a01b0316906020013560ff1661107e565b34801561051e57600080fd5b506104c4611153565b34801561053357600080fd5b506104556004803603606081101561054a57600080fd5b506001600160a01b038135811691602081013590911690604001356111c3565b34801561057657600080fd5b506104556004803603602081101561058d57600080fd5b810190602081018135600160201b8111156105a757600080fd5b8201836020820111156105b957600080fd5b803590602001918460018302840111600160201b831117156105da57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061121f945050505050565b34801561062757600080fd5b506104c46004803603604081101561063e57600080fd5b506001600160a01b0381351690602001356112ee565b34801561066057600080fd5b506104556004803603602081101561067757600080fd5b810190602081018135600160201b81111561069157600080fd5b8201836020820111156106a357600080fd5b803590602001918460018302840111600160201b831117156106c457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061136d945050505050565b34801561071157600080fd5b506104556004803603606081101561072857600080fd5b506001600160a01b038135811691602081013590911690604001356113c7565b34801561075457600080fd5b506103616113e2565b34801561076957600080fd5b50610772611470565b60405180806020018560ff1660ff168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156107c75781810151838201526020016107af565b50505050905090810190601f1680156107f45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561081157600080fd5b506104c46004803603602081101561082857600080fd5b503561167a565b34801561083b57600080fd5b506104996116e0565b34801561085057600080fd5b506104996116e5565b34801561086557600080fd5b506104006004803603602081101561087c57600080fd5b50356116ea565b34801561088f57600080fd5b50610455611744565b3480156108a457600080fd5b506104c4600480360360208110156108bb57600080fd5b50356001600160a01b0316611876565b3480156108d757600080fd5b506104556118de565b3480156108ec57600080fd5b506103616004803603602081101561090357600080fd5b503560ff1661196f565b34801561091957600080fd5b506104006004803603602081101561093057600080fd5b5035611a3b565b34801561094357600080fd5b50610499611a62565b34801561095857600080fd5b50610400611a6b565b34801561096d57600080fd5b50610338611a7a565b34801561098257600080fd5b50610361611aa0565b34801561099757600080fd5b50610361611afb565b3480156109ac57600080fd5b50610338611b5c565b610455600480360360208110156109cb57600080fd5b503560ff16611b65565b3480156109e157600080fd5b50610455600480360360408110156109f857600080fd5b506001600160a01b0381351690602001351515611ce1565b348015610a1c57600080fd5b506104c4611de6565b348015610a3157600080fd5b5061045560048036036080811015610a4857600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a8257600080fd5b820183602082011115610a9457600080fd5b803590602001918460018302840111600160201b83111715610ab557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611dec945050505050565b348015610b0257600080fd5b506104c460048036036020811015610b1957600080fd5b50356001600160a01b0316611e4a565b348015610b3557600080fd5b5061045560048036036020811015610b4c57600080fd5b50356001600160a01b0316611e65565b348015610b6857600080fd5b5061045560048036036020811015610b7f57600080fd5b810190602081018135600160201b811115610b9957600080fd5b820183602082011115610bab57600080fd5b803590602001918460018302840111600160201b83111715610bcc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ebd945050505050565b348015610c1957600080fd5b506104c460048036036020811015610c3057600080fd5b503560ff16611f17565b348015610c4657600080fd5b5061036160048036036020811015610c5d57600080fd5b5035611fb0565b348015610c7057600080fd5b5061045560048036036020811015610c8757600080fd5b50356001600160a01b03166120c7565b348015610ca357600080fd5b5061036160048036036020811015610cba57600080fd5b503561211f565b348015610ccd57600080fd5b5061040060048036036020811015610ce457600080fd5b503560ff166128f1565b348015610cfa57600080fd5b5061033860048036036040811015610d1157600080fd5b506001600160a01b038135811691602001351661290f565b348015610d3557600080fd5b5061033861293d565b348015610d4a57600080fd5b5061045561294d565b348015610d5f57600080fd5b5061049960048036036020811015610d7657600080fd5b50356001600160a01b03166129a9565b348015610d9257600080fd5b5061045560048036036020811015610da957600080fd5b50356001600160a01b03166129ee565b348015610dc557600080fd5b50610338612a3e565b348015610dda57600080fd5b506104c4612a4c565b348015610def57600080fd5b50610338612a52565b348015610e0457600080fd5b50610455612a61565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b820191906000526020600020905b815481529060010190602001808311610e9f57829003601f168201915b505050505090505b90565b6000610ed282612c71565b610f0d5760405162461bcd60e51b815260040180806020018281038252602c815260200180614454602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000610f34826116ea565b9050806001600160a01b0316836001600160a01b03161415610f875760405162461bcd60e51b81526004018080602001828103825260218152602001806145656021913960400191505060405180910390fd5b806001600160a01b0316610f99612c8e565b6001600160a01b03161480610fba5750610fba81610fb5612c8e565b61290f565b610ff55760405162461bcd60e51b815260040180806020018281038252603881526020018061434a6038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60ff166000908152601360205260409020546001600160a01b031690565b60185460ff1681565b60075490565b611086611a7a565b6110c5576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b600f54601060ff90911611156110da57600080fd5b600f8160ff1611156110eb57600080fd5b60ff81166000908152601060205260409020546001600160a01b031661112257600f805460ff8082166001011660ff199091161790555b60ff16600090815260106020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b601a5460009060ff166111bc57601a5460ff6101009091041615156001141561118d5760646019546065028161118557fe5b0490506111b7565b601a5462010000900460ff161515600114156111b25760646019546063028161118557fe5b506019545b610ec4565b5060195490565b6111d46111ce612c8e565b82612c92565b61120f5760405162461bcd60e51b81526004018080602001828103825260318152602001806145b36031913960400191505060405180910390fd5b61121a838383612d36565b505050565b611227611a7a565b611266576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b6004611270611078565b111561127b57600080fd5b6000611285611078565b600081815260156020908152604090912084519293506112a992909185019061400f565b50600081815260136020908152604080832080546001600160a01b031916339081179091558084526011909252909120805460640190556112ea9082612d55565b5050565b60006112f983611876565b82106113365760405162461bcd60e51b815260040180806020018281038252602b8152602001806140c8602b913960400191505060405180910390fd5b6001600160a01b038316600090815260056020526040902080548390811061135a57fe5b9060005260206000200154905092915050565b611375611a7a565b6113b4576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b80516112ea90601690602084019061400f565b61121a83838360405180602001604052806000815250611dec565b6016805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156114685780601f1061143d57610100808354040283529160200191611468565b820191906000526020600020905b81548152906001019060200180831161144b57829003601f168201915b505050505081565b6060600080600061147f611078565b6064039150601860009054906101000a900460ff16606403925042601b540390506000811380156114b3575060008360ff16115b156114bd576114e2565b6000811380156114d4575060136114d2611078565b115b156114de576114e2565b5060005b81611518576040518060400160405280601181526020017020b93a1039b0b6329034b99037bb32b91760791b8152509350611674565b601a5460ff166115a55761152e82606403612d72565b6040516020018060266141d4823960260182805190602001908083835b6020831061156a5780518252601f19909201916020918201910161154b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040529350611674565b600081136115cd576040518060600160405280602a8152602001614320602a91399350611674565b6115d982606403612d72565b60405160200180807241756374696f6e20666f7220746f6b656e202360681b81525060130182805190602001908083835b602083106116295780518252601f19909201916020918201910161160a565b6001836020036101000a03801982511681845116808217855250505050505090500180681034b9903634bb329760b91b81525060090191505060405160208183030381529060405293505b90919293565b6000611684611078565b82106116c15760405162461bcd60e51b815260040180806020018281038252602c8152602001806145e4602c913960400191505060405180910390fd5b600782815481106116ce57fe5b90600052602060002001549050919050565b606481565b606381565b6000818152600160205260408120546001600160a01b03168061173e5760405162461bcd60e51b81526004018080602001828103825260298152602001806143ac6029913960400191505060405180910390fd5b92915050565b600d8054600190810191829055601a546301000000900460ff1615151461176a57600080fd5b601a5460ff161561177a57600080fd5b6063611784611078565b11156117c15760405162461bcd60e51b81526004018080602001828103825260668152602001806142676066913960800191505060405180910390fd5b6117c9611153565b60195542613a9801601b55601a8054600160ff19918216179091557f7e7fa33969761a458e04f477e039a608702b4f924981d6653935a8319a08ad7b8054336001600160a01b031991821681179092557f71a67924699a20698523213e55fe499d539379d7769cd5567e2c45d583f815a380549091168217905560009081526011602052604090208054600290810190915560188054909216179055600d54811461187357600080fd5b50565b60006001600160a01b0382166118bd5760405162461bcd60e51b815260040180806020018281038252602a815260200180614382602a913960400191505060405180910390fd5b6001600160a01b038216600090815260036020526040902061173e90612e33565b6118e6611a7a565b611925576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b600c546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600c80546001600160a01b0319169055565b606060048260ff1611611a1f5760ff821660009081526015602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015611a135780601f106119e857610100808354040283529160200191611a13565b820191906000526020600020905b8154815290600101906020018083116119f657829003601f168201915b50505050509050610e2b565b60ff821660009081526014602052604090205461173e9061211f565b600080611a4d83600060018603612e37565b9050611a5b8160ff166116ea565b9392505050565b600f5460ff1681565b600c546001600160a01b031690565b600c546000906001600160a01b0316611a91612c8e565b6001600160a01b031614905090565b6017805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156114685780601f1061143d57610100808354040283529160200191611468565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b601a5460ff1681565b600d80546001019081905560185460ff90811660640381169083161115611b8b57600080fd5b6019548260ff1602341015611b9f57600080fd5b601a5460ff161515600114611bb357600080fd5b601b544210611bc157600080fd5b60185460ff165b60185460ff908116840181169082161015611c075760ff8116600090815260126020526040902080546001600160a01b03191633179055600101611bc8565b506018805460ff19811660ff91821685018216179091553360009081526011602052604081208054928516909201909155611c40611078565b6040519091507363a9dbce75413036b2b778e670aabd4493aaf9f3906041606434040280156108fc02916000818181858888f19350505050158015611c89573d6000803e3d6000fd5b506000611c9582611a3b565b6040519091506001600160a01b03821690600a340480156108fc02916000818181858888f19350505050158015611cd0573d6000803e3d6000fd5b505050600d5481146112ea57600080fd5b611ce9612c8e565b6001600160a01b0316826001600160a01b03161415611d4f576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060046000611d5c612c8e565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611da0612c8e565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b601b5481565b611dfd611df7612c8e565b83612c92565b611e385760405162461bcd60e51b81526004018080602001828103825260318152602001806145b36031913960400191505060405180910390fd5b611e4484848484612e5c565b50505050565b6001600160a01b031660009081526011602052604090205490565b611e6d611a7a565b611eac576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873600e8263ffffffff612eae16565b611ec5611a7a565b611f04576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b80516112ea90601790602084019061400f565b60ff8116600090815260146020526040812054606090611f3690612f15565b905060ff8316611f495760049150611faa565b8260ff1660011415611f5e5760019150611faa565b8260ff1660021415611f735760059150611faa565b8260ff1660031415611f885760029150611faa565b8260ff1660041415611f9d5760039150611faa565b611a5b8160016005612f5c565b50919050565b6060611fbb82612c71565b611ff65760405162461bcd60e51b815260040180806020018281038252602f815260200180614536602f913960400191505060405180910390fd5b601761200183612d72565b604051602001808380546001816001161561010002031660029004801561205f5780601f1061203d57610100808354040283529182019161205f565b820191906000526020600020905b81548152906001019060200180831161204b575b5050825160208401908083835b6020831061208b5780518252601f19909201916020918201910161206c565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529050919050565b6120cf611a7a565b61210e576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873600e8263ffffffff612fbe16565b60608061212b83612f15565b6040805161200080825261202082019092529192506060919060208201818038833901905050905060006121628360016005612f5c565b905060008160020190506000612190846040518060c001604052806089815260200161414b6089913961303f565b60005b8260ff168112156128b4576121dd856040518060400160405280601881526020017f3c72616469616c4772616469656e742069643d2767726164000000000000000081525061303f565b6121e785826130bf565b6122098560405180606001604052806027815260200161450f6027913961303f565b6122398561221a88601060ff612f5c565b61222789601060ff612f5c565b6122348a601060ff612f5c565b6131f4565b61225b856040518060600160405280603a81526020016143d5603a913961303f565b61226886601060ff612f5c565b9150612276858384856131f4565b612298856040518060600160405280602481526020016144306024913961303f565b6122cf85604051806040016040528060158152602001740f1c185d1a08199a5b1b0f49dd5c9b0a08d9dc9859605a1b81525061303f565b6122d985826130bf565b612307856040518060400160405280600c81526020016b2927207374726f6b653d272360a01b81525061303f565b6123188561221a88601060ff612f5c565b612357856040518060400160405280601881526020017f27207374726f6b652d77696474683d27302720643d276d20000000000000000081525061303f565b61236e856123698860f0610190613319565b6130bf565b61239185604051806040016040528060018152602001600160fd1b81525061303f565b6123a3856123698860f0610190613319565b8360011415612528576123d08560405180604001604052806002815260200161206360f01b81525061303f565b60005b604d811215612522576123ff86604051806040016040528060018152602001600160fd1b81525061303f565b6124118661236989604c19604d613319565b61243486604051806040016040528060018152602001600160fd1b81525061303f565b6124468661236989604c19604d613319565b61246986604051806040016040528060018152602001600160fd1b81525061303f565b61247b8661236989604c19604d613319565b61249e86604051806040016040528060018152602001600160fd1b81525061303f565b6124b08661236989604c19604d613319565b6124d386604051806040016040528060018152602001600160fd1b81525061303f565b6124e58661236989604c19604d613319565b61250886604051806040016040528060018152602001600160fd1b81525061303f565b61251a8661236989604c19604d613319565b6001016123d3565b50612886565b836002141561263d576125558560405180604001604052806002815260200161207360f01b81525061303f565b60005b605b8112156125225761258486604051806040016040528060018152602001600160fd1b81525061303f565b61259686612369896044196045613319565b6125b986604051806040016040528060018152602001600160fd1b81525061303f565b6125cb86612369896044196045613319565b6125ee86604051806040016040528060018152602001600160fd1b81525061303f565b61260086612369896044196045613319565b61262386604051806040016040528060018152602001600160fd1b81525061303f565b61263586612369896044196045613319565b600101612558565b83600314156127525761266a8560405180604001604052806002815260200161207160f01b81525061303f565b60005b604d8112156125225761269986604051806040016040528060018152602001600160fd1b81525061303f565b6126ab8661236989602e19602f613319565b6126ce86604051806040016040528060018152602001600160fd1b81525061303f565b6126e08661236989602e19602f613319565b61270386604051806040016040528060018152602001600160fd1b81525061303f565b6127158661236989602e19602f613319565b61273886604051806040016040528060018152602001600160fd1b81525061303f565b61274a8661236989602e19602f613319565b60010161266d565b83600414156127fd5761277f8560405180604001604052806002815260200161081d60f21b81525061303f565b60005b607b811215612522576127ae86604051806040016040528060018152602001600160fd1b81525061303f565b6127c08661236989601c19601d613319565b6127e386604051806040016040528060018152602001600160fd1b81525061303f565b6127f58661236989601c19601d613319565b600101612782565b83600514156128865760005b60638112156128845761283586604051806040016040528060018152602001600160fd1b81525061303f565b61284786612369896024196025613319565b61286a86604051806040016040528060018152602001600160fd1b81525061303f565b61287c86612369896024196025613319565b600101612809565b505b6128ac85604051806040016040528060048152602001631390179f60e11b81525061303f565b600101612193565b506128dd84604051806040016040528060068152602001651e17b9bb339f60d11b81525061303f565b6128e68461335a565b979650505050505050565b60ff166000908152601260205260409020546001600160a01b031690565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b601a546301000000900460ff1681565b612955611a7a565b612994576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b601a805463ff00000019166301000000179055565b6000805b60648160ff161015611faa5760ff81166000908152601260205260409020546001600160a01b03848116911614156129e6578160010191505b6001016129ad565b6129f6611a7a565b612a35576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873816133bf565b601a54610100900460ff1681565b60195481565b601a5462010000900460ff1681565b6013612a6b611078565b11612a9457601b5442101580612a86575060185460ff166064145b612a8f57600080fd5b612aa3565b601b54421015612aa357600080fd5b612ab4600e3363ffffffff61346016565b612aef5760405162461bcd60e51b815260040180806020018281038252602d815260200180614586602d913960400191505060405180910390fd5b612af76134c7565b601a805460ff1916905560005b60648160ff161015612b385760ff8116600090815260126020526040902080546001600160a01b0319169055600101612b04565b50601854605060ff9091161115612b6557601a805462ff00001961ff001990911661010017169055612b9f565b601854603c60ff9091161015612b9257601a805461ff001962ff0000199091166201000017169055612b9f565b601a805462ffff00191690555b6018805460ff19169055476000600582046002029050600060058381612bc157fe5b04600302905060005b600f5460ff9081169082161015612c435760ff808216600090815260106020526040902054600f546001600160a01b039091169182916108fc91168681612c0d57fe5b049081150290604051600060405180830381858888f19350505050158015612c39573d6000803e3d6000fd5b5050600101612bca565b50604051339082156108fc029083906000818181858888f19350505050158015611e44573d6000803e3d6000fd5b6000908152600160205260409020546001600160a01b0316151590565b3390565b6000612c9d82612c71565b612cd85760405162461bcd60e51b815260040180806020018281038252602c8152602001806142cd602c913960400191505060405180910390fd5b6000612ce3836116ea565b9050806001600160a01b0316846001600160a01b03161480612d1e5750836001600160a01b0316612d1384610ec7565b6001600160a01b0316145b80612d2e5750612d2e818561290f565b949350505050565b612d418383836135ca565b612d4b838261370e565b61121a8282613803565b612d5f8282613841565b612d698282613803565b6112ea81613972565b606081612d9757506040805180820190915260018152600360fc1b6020820152610e2b565b8160005b8115612daf57600101600a82049150612d9b565b6060816040519080825280601f01601f191660200182016040528015612ddc576020820181803883390190505b50905060001982015b8515612e2a57600a860660300160f81b82828060019003935081518110612e0857fe5b60200101906001600160f81b031916908160001a905350600a86049550612de5565b50949350505050565b5490565b60006060612e466001866139b6565b9050612e538185856139c8565b95945050505050565b612e67848484612d36565b612e7384848484613a19565b611e445760405162461bcd60e51b81526004018080602001828103825260328152602001806140f36032913960400191505060405180910390fd5b612eb88282613460565b612ef35760405162461bcd60e51b815260040180806020018281038252602181526020018061440f6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b604080516001808252818301909252606091829190602080830190803883390190505090508260001b81600081518110612f4b57fe5b602090810291909101015292915050565b600081831115612f9d5760405162461bcd60e51b81526004018080602001828103825260258152602001806141fa6025913960400191505060405180910390fd5b82838303600101612fad86613b70565b81612fb457fe5b0601949350505050565b612fc88282613460565b1561301a576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b61304a828251613c3b565b61309b576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e617070656e643a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6020820151815160408401820183516020850160045afa5090510160209190910152565b6130ca826004613c3b565b61311b576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e6e756d6269653a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6131ce565b600060308301825350600101919050565b6000611a5b600a8406613147600a860485613120565b613120565b600060648310801561318657600a841080156131735761316c8585613120565b9250613180565b61317d8585613131565b92505b506131a2565b612d2e6064850661319d600a606488040686613120565b613131565b5092915050565b6000808312156131c457911960010191602d82536001820191505b611a5b838361314c565b604082016020830151016131e282826131a9565b90506040838203036020840152505050565b6131ff846006613c3b565b613250576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e6865787267623a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6132ef565b6000600f8360041c16600f8416600f8660041c16600f8716600f8960041c16600f8a1660306027600a880402870101885360306027600a870402860101600189015360306027600a860402850101600289015360306027600a850402840101600389015360306027600a840402830101600489015360306027600a8304028201016005890153600688019650505050505050949350505050565b6040840160208501510161330582848684613255565b905060408582030360208601525050505050565b600081831315612f9d5760405162461bcd60e51b81526004018080602001828103825260248152602001806144806024913960400191505060405180910390fd5b6060613367826000613c3b565b6133b8576040805162461bcd60e51b815260206004820152601f60248201527f4275666665722e746f537472696e673a20696e76616c69642062756666657200604482015290519081900360640190fd5b5060200190565b6001600160a01b0381166134045760405162461bcd60e51b81526004018080602001828103825260268152602001806141256026913960400191505060405180910390fd5b600c546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b0382166134a75760405162461bcd60e51b81526004018080602001828103825260228152602001806144c46022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600d80546001019081905560636134dc611078565b1115613521576040805162461bcd60e51b815260206004820152600f60248201526e21b630b4b6b2b2171029b7b9393c9760891b604482015290519081900360640190fd5b600061352b611078565b9050600061354f61353a611078565b60185460009060001960ff9182160116612e37565b60ff81166000908152601260205260408120549192506001600160a01b03909116906135816001806305f5e0ff612e37565b60008581526014602090815260408083208490556013909152902080546001600160a01b0319163317905590506135b88285612d55565b50505050600d54811461187357600080fd5b826001600160a01b03166135dd826116ea565b6001600160a01b0316146136225760405162461bcd60e51b81526004018080602001828103825260298152602001806144e66029913960400191505060405180910390fd5b6001600160a01b0382166136675760405162461bcd60e51b815260040180806020018281038252602481526020018061421f6024913960400191505060405180910390fd5b61367081613c72565b6001600160a01b038316600090815260036020526040902061369190613cad565b6001600160a01b03821660009081526003602052604090206136b290613cc4565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461373890600163ffffffff613ccd16565b6000838152600660205260409020549091508082146137d3576001600160a01b038416600090815260056020526040812080548490811061377557fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106137b357fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b03841660009081526005602052604090208054906137fc90600019830161408d565b5050505050565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6001600160a01b03821661389c576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6138a581612c71565b156138f7576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b03871690811790915583526003909152902061393690613cc4565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b6060611a5b8343036001430384613d0f565b600081831315613a095760405162461bcd60e51b81526004018080602001828103825260248152602001806142436024913960400191505060405180910390fd5b82838303600101612fad86613e29565b6000613a2d846001600160a01b0316613f41565b613a3957506001612d2e565b6000846001600160a01b031663150b7a02613a52612c8e565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ad7578181015183820152602001613abf565b50505050905090810190601f168015613b045780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015613b2657600080fd5b505af1158015613b3a573d6000803e3d6000fd5b505050506040513d6020811015613b5057600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b60008151600114613bc8576040805162461bcd60e51b815260206004820152601a60248201527f52616e646f6d2e6e6578743a20696e76616c696420706172616d000000000000604482015290519081900360640190fd5b81600081518110613bd557fe5b6020026020010151604051602001808281526020019150506040516020818303038152906040528051906020012082600081518110613c1057fe5b60200260200101818152505081600081518110613c2957fe5b602002602001015160001c9050919050565b8151602080840151600092918210801590613c595750602082038111155b8015612e53575060208203848201111595945050505050565b6000818152600260205260409020546001600160a01b03161561187357600090815260026020526040902080546001600160a01b0319169055565b8054613cc090600163ffffffff613ccd16565b9055565b80546001019055565b6000611a5b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613f78565b6060826001430310158015613d245750838310155b613d5f5760405162461bcd60e51b81526004018080602001828103825260278152602001806142f96027913960400191505060405180910390fd5b6060848403600201604051908082528060200260200182016040528015613d90578160200160208202803883390190505b5060408051436020808301919091528183018790528251808303840181526060909201909252805191012090915060005b8686038111613e1e578087014082604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120838260010181518110613e0b57fe5b6020908102919091010152600101613dc1565b509095945050505050565b60006001825111613e81576040805162461bcd60e51b815260206004820152601d60248201527f52616e646f6d53616c742e6e6578743a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6000600183510383600081518110613e9557fe5b602002602001015160001c81613ea757fe5b0660010190506000838281518110613ebb57fe5b60200260200101516040516020018082815260200191505060405160208183030381529060405280519060200120905083600081518110613ef857fe5b602002602001015160001c60010160001b84600081518110613f1657fe5b60200260200101818152505080848381518110613f2f57fe5b60209081029190910101529392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612d2e5750141592915050565b600081848411156140075760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613fcc578181015183820152602001613fb4565b50505050905090810190601f168015613ff95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061405057805160ff191683800117855561407d565b8280016001018555821561407d579182015b8281111561407d578251825591602001919060010190614062565b506140899291506140ad565b5090565b81548183558181111561121a5760008381526020902061121a9181019083015b610ec491905b8082111561408957600081556001016140b356fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d2736343027206865696768743d27363430272076696577426f783d27302030203634302036343027207374796c653d277374726f6b652d77696474683a303b206261636b67726f756e642d636f6c6f723a233132313231323b273e41756374696f6e206973206e6f74206163746976652e204e65787420746f6b656e2069733a2052616e646f6d2e756e69666f726d5f75696e743a20696e76616c696420696e74657276616c4552433732313a207472616e7366657220746f20746865207a65726f206164647265737352616e646f6d53616c742e756e69666f726d3a20696e76616c696420696e74657276616c5371756967676c792073616c652068617320636f6e636c756465642e20476f6f64206c75636b20707279696e67206f6e65206f7574206f66207468652068616e6473206f6620736f6d656f6e65206f6e20746865207365636f6e64617279206d61726b65742e4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e52616e646f6d53616c742e696e69743a20696e76616c696420626c6f636b20696e74657276616c57616974696e67206f6e2041756374696f6e65657220746f2063616c6c20456e642041756374696f6e2e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e3b73746f702d6f7061636974793a3027202f3e3c73746f70206f66667365743d273130302527207374796c653d2773746f702d636f6c6f723a23526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c653b73746f702d6f7061636974793a3127202f3e3c2f72616469616c4772616469656e743e4552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e52616e646f6d2e756e69666f726d5f696e743a20696e76616c696420696e74657276616c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572526f6c65733a206163636f756e7420697320746865207a65726f20616464726573734552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e273e3c73746f70206f66667365743d27302527207374796c653d2773746f702d636f6c6f723a234552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724f6e6c79206f6666696369616c2041756374696f6e656572732063616e20656e6420616e2061756374696f6e2e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e6473a265627a7a72315820090c926cad1236c8fa50d210a85f7af1a80ccc93ea9fab64443e7095fc378e0864736f6c634300050e0032526f6c65733a206163636f756e7420697320746865207a65726f206164647265737368747470733a2f2f7371756967676c797774662e617a75726577656273697465732e6e65742f6170692f48747470547269676765723f69643d

Deployed Bytecode

0x6080604052600436106102ff5760003560e01c80638da5cb5b11610190578063c87b56dd116100dc578063efd779bd11610095578063f628fbea1161006f578063f628fbea14610db9578063f80cf19414610dce578063fdbd9b8114610de3578063fe67a54b14610df8576102ff565b8063efd779bd14610d3e578063f0195cd114610d53578063f2fde38b14610d86576102ff565b8063c87b56dd14610c3a578063cbe01bc814610c64578063ce020cdd14610c97578063d237069414610cc1578063e985e9c514610cee578063ee2679bc14610d29576102ff565b8063a22cb46511610149578063b9df332311610123578063b9df332314610af6578063bed2b6ac14610b29578063c30f4a5a14610b5c578063c7c4a9e514610c0d576102ff565b8063a22cb465146109d5578063ad87780514610a10578063b88d4fde14610a25576102ff565b80638da5cb5b1461094c5780638f32d59b146109615780639416b7d81461097657806395d89b411461098b578063987dcb45146109a05780639ad96754146109b5576102ff565b806342842e0e1161024f5780636352211e11610208578063715018a6116101e2578063715018a6146108cb5780637a06f4a5146108e05780637cb351621461090d5780638409b5f014610937576102ff565b80636352211e146108595780636b64c7691461088357806370a0823114610898576102ff565b806342842e0e1461070557806347a9553d146107485780634913e6d21461075d5780634f6ccce714610805578063517626ec1461082f57806356c7627e14610844576102ff565b806318160ddd116102bc57806323b872dd1161029657806323b872dd146105275780632d20fb9d1461056a5780632f745c591461061b5780633a964fc714610654576102ff565b806318160ddd146104af5780631b2b151d146104d65780631eb9a82c14610512576102ff565b806301ffc9a71461030457806306fdde031461034c578063081812fc146103d6578063095ea7b31461041c5780630b413d0b146104575780630e81770f14610484575b600080fd5b34801561031057600080fd5b506103386004803603602081101561032757600080fd5b50356001600160e01b031916610e0d565b604080519115158252519081900360200190f35b34801561035857600080fd5b50610361610e30565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610400600480360360208110156103f957600080fd5b5035610ec7565b604080516001600160a01b039092168252519081900360200190f35b34801561042857600080fd5b506104556004803603604081101561043f57600080fd5b506001600160a01b038135169060200135610f29565b005b34801561046357600080fd5b506104006004803603602081101561047a57600080fd5b503560ff16611051565b34801561049057600080fd5b5061049961106f565b6040805160ff9092168252519081900360200190f35b3480156104bb57600080fd5b506104c4611078565b60408051918252519081900360200190f35b3480156104e257600080fd5b50610455600480360360408110156104f957600080fd5b5080356001600160a01b0316906020013560ff1661107e565b34801561051e57600080fd5b506104c4611153565b34801561053357600080fd5b506104556004803603606081101561054a57600080fd5b506001600160a01b038135811691602081013590911690604001356111c3565b34801561057657600080fd5b506104556004803603602081101561058d57600080fd5b810190602081018135600160201b8111156105a757600080fd5b8201836020820111156105b957600080fd5b803590602001918460018302840111600160201b831117156105da57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061121f945050505050565b34801561062757600080fd5b506104c46004803603604081101561063e57600080fd5b506001600160a01b0381351690602001356112ee565b34801561066057600080fd5b506104556004803603602081101561067757600080fd5b810190602081018135600160201b81111561069157600080fd5b8201836020820111156106a357600080fd5b803590602001918460018302840111600160201b831117156106c457600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061136d945050505050565b34801561071157600080fd5b506104556004803603606081101561072857600080fd5b506001600160a01b038135811691602081013590911690604001356113c7565b34801561075457600080fd5b506103616113e2565b34801561076957600080fd5b50610772611470565b60405180806020018560ff1660ff168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156107c75781810151838201526020016107af565b50505050905090810190601f1680156107f45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561081157600080fd5b506104c46004803603602081101561082857600080fd5b503561167a565b34801561083b57600080fd5b506104996116e0565b34801561085057600080fd5b506104996116e5565b34801561086557600080fd5b506104006004803603602081101561087c57600080fd5b50356116ea565b34801561088f57600080fd5b50610455611744565b3480156108a457600080fd5b506104c4600480360360208110156108bb57600080fd5b50356001600160a01b0316611876565b3480156108d757600080fd5b506104556118de565b3480156108ec57600080fd5b506103616004803603602081101561090357600080fd5b503560ff1661196f565b34801561091957600080fd5b506104006004803603602081101561093057600080fd5b5035611a3b565b34801561094357600080fd5b50610499611a62565b34801561095857600080fd5b50610400611a6b565b34801561096d57600080fd5b50610338611a7a565b34801561098257600080fd5b50610361611aa0565b34801561099757600080fd5b50610361611afb565b3480156109ac57600080fd5b50610338611b5c565b610455600480360360208110156109cb57600080fd5b503560ff16611b65565b3480156109e157600080fd5b50610455600480360360408110156109f857600080fd5b506001600160a01b0381351690602001351515611ce1565b348015610a1c57600080fd5b506104c4611de6565b348015610a3157600080fd5b5061045560048036036080811015610a4857600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b811115610a8257600080fd5b820183602082011115610a9457600080fd5b803590602001918460018302840111600160201b83111715610ab557600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611dec945050505050565b348015610b0257600080fd5b506104c460048036036020811015610b1957600080fd5b50356001600160a01b0316611e4a565b348015610b3557600080fd5b5061045560048036036020811015610b4c57600080fd5b50356001600160a01b0316611e65565b348015610b6857600080fd5b5061045560048036036020811015610b7f57600080fd5b810190602081018135600160201b811115610b9957600080fd5b820183602082011115610bab57600080fd5b803590602001918460018302840111600160201b83111715610bcc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611ebd945050505050565b348015610c1957600080fd5b506104c460048036036020811015610c3057600080fd5b503560ff16611f17565b348015610c4657600080fd5b5061036160048036036020811015610c5d57600080fd5b5035611fb0565b348015610c7057600080fd5b5061045560048036036020811015610c8757600080fd5b50356001600160a01b03166120c7565b348015610ca357600080fd5b5061036160048036036020811015610cba57600080fd5b503561211f565b348015610ccd57600080fd5b5061040060048036036020811015610ce457600080fd5b503560ff166128f1565b348015610cfa57600080fd5b5061033860048036036040811015610d1157600080fd5b506001600160a01b038135811691602001351661290f565b348015610d3557600080fd5b5061033861293d565b348015610d4a57600080fd5b5061045561294d565b348015610d5f57600080fd5b5061049960048036036020811015610d7657600080fd5b50356001600160a01b03166129a9565b348015610d9257600080fd5b5061045560048036036020811015610da957600080fd5b50356001600160a01b03166129ee565b348015610dc557600080fd5b50610338612a3e565b348015610dda57600080fd5b506104c4612a4c565b348015610def57600080fd5b50610338612a52565b348015610e0457600080fd5b50610455612a61565b6001600160e01b0319811660009081526020819052604090205460ff165b919050565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b820191906000526020600020905b815481529060010190602001808311610e9f57829003601f168201915b505050505090505b90565b6000610ed282612c71565b610f0d5760405162461bcd60e51b815260040180806020018281038252602c815260200180614454602c913960400191505060405180910390fd5b506000908152600260205260409020546001600160a01b031690565b6000610f34826116ea565b9050806001600160a01b0316836001600160a01b03161415610f875760405162461bcd60e51b81526004018080602001828103825260218152602001806145656021913960400191505060405180910390fd5b806001600160a01b0316610f99612c8e565b6001600160a01b03161480610fba5750610fba81610fb5612c8e565b61290f565b610ff55760405162461bcd60e51b815260040180806020018281038252603881526020018061434a6038913960400191505060405180910390fd5b60008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60ff166000908152601360205260409020546001600160a01b031690565b60185460ff1681565b60075490565b611086611a7a565b6110c5576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b600f54601060ff90911611156110da57600080fd5b600f8160ff1611156110eb57600080fd5b60ff81166000908152601060205260409020546001600160a01b031661112257600f805460ff8082166001011660ff199091161790555b60ff16600090815260106020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b601a5460009060ff166111bc57601a5460ff6101009091041615156001141561118d5760646019546065028161118557fe5b0490506111b7565b601a5462010000900460ff161515600114156111b25760646019546063028161118557fe5b506019545b610ec4565b5060195490565b6111d46111ce612c8e565b82612c92565b61120f5760405162461bcd60e51b81526004018080602001828103825260318152602001806145b36031913960400191505060405180910390fd5b61121a838383612d36565b505050565b611227611a7a565b611266576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b6004611270611078565b111561127b57600080fd5b6000611285611078565b600081815260156020908152604090912084519293506112a992909185019061400f565b50600081815260136020908152604080832080546001600160a01b031916339081179091558084526011909252909120805460640190556112ea9082612d55565b5050565b60006112f983611876565b82106113365760405162461bcd60e51b815260040180806020018281038252602b8152602001806140c8602b913960400191505060405180910390fd5b6001600160a01b038316600090815260056020526040902080548390811061135a57fe5b9060005260206000200154905092915050565b611375611a7a565b6113b4576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b80516112ea90601690602084019061400f565b61121a83838360405180602001604052806000815250611dec565b6016805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156114685780601f1061143d57610100808354040283529160200191611468565b820191906000526020600020905b81548152906001019060200180831161144b57829003601f168201915b505050505081565b6060600080600061147f611078565b6064039150601860009054906101000a900460ff16606403925042601b540390506000811380156114b3575060008360ff16115b156114bd576114e2565b6000811380156114d4575060136114d2611078565b115b156114de576114e2565b5060005b81611518576040518060400160405280601181526020017020b93a1039b0b6329034b99037bb32b91760791b8152509350611674565b601a5460ff166115a55761152e82606403612d72565b6040516020018060266141d4823960260182805190602001908083835b6020831061156a5780518252601f19909201916020918201910161154b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040529350611674565b600081136115cd576040518060600160405280602a8152602001614320602a91399350611674565b6115d982606403612d72565b60405160200180807241756374696f6e20666f7220746f6b656e202360681b81525060130182805190602001908083835b602083106116295780518252601f19909201916020918201910161160a565b6001836020036101000a03801982511681845116808217855250505050505090500180681034b9903634bb329760b91b81525060090191505060405160208183030381529060405293505b90919293565b6000611684611078565b82106116c15760405162461bcd60e51b815260040180806020018281038252602c8152602001806145e4602c913960400191505060405180910390fd5b600782815481106116ce57fe5b90600052602060002001549050919050565b606481565b606381565b6000818152600160205260408120546001600160a01b03168061173e5760405162461bcd60e51b81526004018080602001828103825260298152602001806143ac6029913960400191505060405180910390fd5b92915050565b600d8054600190810191829055601a546301000000900460ff1615151461176a57600080fd5b601a5460ff161561177a57600080fd5b6063611784611078565b11156117c15760405162461bcd60e51b81526004018080602001828103825260668152602001806142676066913960800191505060405180910390fd5b6117c9611153565b60195542613a9801601b55601a8054600160ff19918216179091557f7e7fa33969761a458e04f477e039a608702b4f924981d6653935a8319a08ad7b8054336001600160a01b031991821681179092557f71a67924699a20698523213e55fe499d539379d7769cd5567e2c45d583f815a380549091168217905560009081526011602052604090208054600290810190915560188054909216179055600d54811461187357600080fd5b50565b60006001600160a01b0382166118bd5760405162461bcd60e51b815260040180806020018281038252602a815260200180614382602a913960400191505060405180910390fd5b6001600160a01b038216600090815260036020526040902061173e90612e33565b6118e6611a7a565b611925576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b600c546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600c80546001600160a01b0319169055565b606060048260ff1611611a1f5760ff821660009081526015602090815260409182902080548351601f600260001961010060018616150201909316929092049182018490048402810184019094528084529091830182828015611a135780601f106119e857610100808354040283529160200191611a13565b820191906000526020600020905b8154815290600101906020018083116119f657829003601f168201915b50505050509050610e2b565b60ff821660009081526014602052604090205461173e9061211f565b600080611a4d83600060018603612e37565b9050611a5b8160ff166116ea565b9392505050565b600f5460ff1681565b600c546001600160a01b031690565b600c546000906001600160a01b0316611a91612c8e565b6001600160a01b031614905090565b6017805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156114685780601f1061143d57610100808354040283529160200191611468565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ebc5780601f10610e9157610100808354040283529160200191610ebc565b601a5460ff1681565b600d80546001019081905560185460ff90811660640381169083161115611b8b57600080fd5b6019548260ff1602341015611b9f57600080fd5b601a5460ff161515600114611bb357600080fd5b601b544210611bc157600080fd5b60185460ff165b60185460ff908116840181169082161015611c075760ff8116600090815260126020526040902080546001600160a01b03191633179055600101611bc8565b506018805460ff19811660ff91821685018216179091553360009081526011602052604081208054928516909201909155611c40611078565b6040519091507363a9dbce75413036b2b778e670aabd4493aaf9f3906041606434040280156108fc02916000818181858888f19350505050158015611c89573d6000803e3d6000fd5b506000611c9582611a3b565b6040519091506001600160a01b03821690600a340480156108fc02916000818181858888f19350505050158015611cd0573d6000803e3d6000fd5b505050600d5481146112ea57600080fd5b611ce9612c8e565b6001600160a01b0316826001600160a01b03161415611d4f576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b8060046000611d5c612c8e565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611da0612c8e565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b601b5481565b611dfd611df7612c8e565b83612c92565b611e385760405162461bcd60e51b81526004018080602001828103825260318152602001806145b36031913960400191505060405180910390fd5b611e4484848484612e5c565b50505050565b6001600160a01b031660009081526011602052604090205490565b611e6d611a7a565b611eac576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873600e8263ffffffff612eae16565b611ec5611a7a565b611f04576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b80516112ea90601790602084019061400f565b60ff8116600090815260146020526040812054606090611f3690612f15565b905060ff8316611f495760049150611faa565b8260ff1660011415611f5e5760019150611faa565b8260ff1660021415611f735760059150611faa565b8260ff1660031415611f885760029150611faa565b8260ff1660041415611f9d5760039150611faa565b611a5b8160016005612f5c565b50919050565b6060611fbb82612c71565b611ff65760405162461bcd60e51b815260040180806020018281038252602f815260200180614536602f913960400191505060405180910390fd5b601761200183612d72565b604051602001808380546001816001161561010002031660029004801561205f5780601f1061203d57610100808354040283529182019161205f565b820191906000526020600020905b81548152906001019060200180831161204b575b5050825160208401908083835b6020831061208b5780518252601f19909201916020918201910161206c565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040529050919050565b6120cf611a7a565b61210e576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873600e8263ffffffff612fbe16565b60608061212b83612f15565b6040805161200080825261202082019092529192506060919060208201818038833901905050905060006121628360016005612f5c565b905060008160020190506000612190846040518060c001604052806089815260200161414b6089913961303f565b60005b8260ff168112156128b4576121dd856040518060400160405280601881526020017f3c72616469616c4772616469656e742069643d2767726164000000000000000081525061303f565b6121e785826130bf565b6122098560405180606001604052806027815260200161450f6027913961303f565b6122398561221a88601060ff612f5c565b61222789601060ff612f5c565b6122348a601060ff612f5c565b6131f4565b61225b856040518060600160405280603a81526020016143d5603a913961303f565b61226886601060ff612f5c565b9150612276858384856131f4565b612298856040518060600160405280602481526020016144306024913961303f565b6122cf85604051806040016040528060158152602001740f1c185d1a08199a5b1b0f49dd5c9b0a08d9dc9859605a1b81525061303f565b6122d985826130bf565b612307856040518060400160405280600c81526020016b2927207374726f6b653d272360a01b81525061303f565b6123188561221a88601060ff612f5c565b612357856040518060400160405280601881526020017f27207374726f6b652d77696474683d27302720643d276d20000000000000000081525061303f565b61236e856123698860f0610190613319565b6130bf565b61239185604051806040016040528060018152602001600160fd1b81525061303f565b6123a3856123698860f0610190613319565b8360011415612528576123d08560405180604001604052806002815260200161206360f01b81525061303f565b60005b604d811215612522576123ff86604051806040016040528060018152602001600160fd1b81525061303f565b6124118661236989604c19604d613319565b61243486604051806040016040528060018152602001600160fd1b81525061303f565b6124468661236989604c19604d613319565b61246986604051806040016040528060018152602001600160fd1b81525061303f565b61247b8661236989604c19604d613319565b61249e86604051806040016040528060018152602001600160fd1b81525061303f565b6124b08661236989604c19604d613319565b6124d386604051806040016040528060018152602001600160fd1b81525061303f565b6124e58661236989604c19604d613319565b61250886604051806040016040528060018152602001600160fd1b81525061303f565b61251a8661236989604c19604d613319565b6001016123d3565b50612886565b836002141561263d576125558560405180604001604052806002815260200161207360f01b81525061303f565b60005b605b8112156125225761258486604051806040016040528060018152602001600160fd1b81525061303f565b61259686612369896044196045613319565b6125b986604051806040016040528060018152602001600160fd1b81525061303f565b6125cb86612369896044196045613319565b6125ee86604051806040016040528060018152602001600160fd1b81525061303f565b61260086612369896044196045613319565b61262386604051806040016040528060018152602001600160fd1b81525061303f565b61263586612369896044196045613319565b600101612558565b83600314156127525761266a8560405180604001604052806002815260200161207160f01b81525061303f565b60005b604d8112156125225761269986604051806040016040528060018152602001600160fd1b81525061303f565b6126ab8661236989602e19602f613319565b6126ce86604051806040016040528060018152602001600160fd1b81525061303f565b6126e08661236989602e19602f613319565b61270386604051806040016040528060018152602001600160fd1b81525061303f565b6127158661236989602e19602f613319565b61273886604051806040016040528060018152602001600160fd1b81525061303f565b61274a8661236989602e19602f613319565b60010161266d565b83600414156127fd5761277f8560405180604001604052806002815260200161081d60f21b81525061303f565b60005b607b811215612522576127ae86604051806040016040528060018152602001600160fd1b81525061303f565b6127c08661236989601c19601d613319565b6127e386604051806040016040528060018152602001600160fd1b81525061303f565b6127f58661236989601c19601d613319565b600101612782565b83600514156128865760005b60638112156128845761283586604051806040016040528060018152602001600160fd1b81525061303f565b61284786612369896024196025613319565b61286a86604051806040016040528060018152602001600160fd1b81525061303f565b61287c86612369896024196025613319565b600101612809565b505b6128ac85604051806040016040528060048152602001631390179f60e11b81525061303f565b600101612193565b506128dd84604051806040016040528060068152602001651e17b9bb339f60d11b81525061303f565b6128e68461335a565b979650505050505050565b60ff166000908152601260205260409020546001600160a01b031690565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b601a546301000000900460ff1681565b612955611a7a565b612994576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b601a805463ff00000019166301000000179055565b6000805b60648160ff161015611faa5760ff81166000908152601260205260409020546001600160a01b03848116911614156129e6578160010191505b6001016129ad565b6129f6611a7a565b612a35576040805162461bcd60e51b815260206004820181905260248201526000805160206144a4833981519152604482015290519081900360640190fd5b611873816133bf565b601a54610100900460ff1681565b60195481565b601a5462010000900460ff1681565b6013612a6b611078565b11612a9457601b5442101580612a86575060185460ff166064145b612a8f57600080fd5b612aa3565b601b54421015612aa357600080fd5b612ab4600e3363ffffffff61346016565b612aef5760405162461bcd60e51b815260040180806020018281038252602d815260200180614586602d913960400191505060405180910390fd5b612af76134c7565b601a805460ff1916905560005b60648160ff161015612b385760ff8116600090815260126020526040902080546001600160a01b0319169055600101612b04565b50601854605060ff9091161115612b6557601a805462ff00001961ff001990911661010017169055612b9f565b601854603c60ff9091161015612b9257601a805461ff001962ff0000199091166201000017169055612b9f565b601a805462ffff00191690555b6018805460ff19169055476000600582046002029050600060058381612bc157fe5b04600302905060005b600f5460ff9081169082161015612c435760ff808216600090815260106020526040902054600f546001600160a01b039091169182916108fc91168681612c0d57fe5b049081150290604051600060405180830381858888f19350505050158015612c39573d6000803e3d6000fd5b5050600101612bca565b50604051339082156108fc029083906000818181858888f19350505050158015611e44573d6000803e3d6000fd5b6000908152600160205260409020546001600160a01b0316151590565b3390565b6000612c9d82612c71565b612cd85760405162461bcd60e51b815260040180806020018281038252602c8152602001806142cd602c913960400191505060405180910390fd5b6000612ce3836116ea565b9050806001600160a01b0316846001600160a01b03161480612d1e5750836001600160a01b0316612d1384610ec7565b6001600160a01b0316145b80612d2e5750612d2e818561290f565b949350505050565b612d418383836135ca565b612d4b838261370e565b61121a8282613803565b612d5f8282613841565b612d698282613803565b6112ea81613972565b606081612d9757506040805180820190915260018152600360fc1b6020820152610e2b565b8160005b8115612daf57600101600a82049150612d9b565b6060816040519080825280601f01601f191660200182016040528015612ddc576020820181803883390190505b50905060001982015b8515612e2a57600a860660300160f81b82828060019003935081518110612e0857fe5b60200101906001600160f81b031916908160001a905350600a86049550612de5565b50949350505050565b5490565b60006060612e466001866139b6565b9050612e538185856139c8565b95945050505050565b612e67848484612d36565b612e7384848484613a19565b611e445760405162461bcd60e51b81526004018080602001828103825260328152602001806140f36032913960400191505060405180910390fd5b612eb88282613460565b612ef35760405162461bcd60e51b815260040180806020018281038252602181526020018061440f6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b604080516001808252818301909252606091829190602080830190803883390190505090508260001b81600081518110612f4b57fe5b602090810291909101015292915050565b600081831115612f9d5760405162461bcd60e51b81526004018080602001828103825260258152602001806141fa6025913960400191505060405180910390fd5b82838303600101612fad86613b70565b81612fb457fe5b0601949350505050565b612fc88282613460565b1561301a576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b61304a828251613c3b565b61309b576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e617070656e643a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6020820151815160408401820183516020850160045afa5090510160209190910152565b6130ca826004613c3b565b61311b576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e6e756d6269653a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6131ce565b600060308301825350600101919050565b6000611a5b600a8406613147600a860485613120565b613120565b600060648310801561318657600a841080156131735761316c8585613120565b9250613180565b61317d8585613131565b92505b506131a2565b612d2e6064850661319d600a606488040686613120565b613131565b5092915050565b6000808312156131c457911960010191602d82536001820191505b611a5b838361314c565b604082016020830151016131e282826131a9565b90506040838203036020840152505050565b6131ff846006613c3b565b613250576040805162461bcd60e51b815260206004820152601a60248201527f4275666665722e6865787267623a206e6f206361706163697479000000000000604482015290519081900360640190fd5b6132ef565b6000600f8360041c16600f8416600f8660041c16600f8716600f8960041c16600f8a1660306027600a880402870101885360306027600a870402860101600189015360306027600a860402850101600289015360306027600a850402840101600389015360306027600a840402830101600489015360306027600a8304028201016005890153600688019650505050505050949350505050565b6040840160208501510161330582848684613255565b905060408582030360208601525050505050565b600081831315612f9d5760405162461bcd60e51b81526004018080602001828103825260248152602001806144806024913960400191505060405180910390fd5b6060613367826000613c3b565b6133b8576040805162461bcd60e51b815260206004820152601f60248201527f4275666665722e746f537472696e673a20696e76616c69642062756666657200604482015290519081900360640190fd5b5060200190565b6001600160a01b0381166134045760405162461bcd60e51b81526004018080602001828103825260268152602001806141256026913960400191505060405180910390fd5b600c546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c80546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b0382166134a75760405162461bcd60e51b81526004018080602001828103825260228152602001806144c46022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b600d80546001019081905560636134dc611078565b1115613521576040805162461bcd60e51b815260206004820152600f60248201526e21b630b4b6b2b2171029b7b9393c9760891b604482015290519081900360640190fd5b600061352b611078565b9050600061354f61353a611078565b60185460009060001960ff9182160116612e37565b60ff81166000908152601260205260408120549192506001600160a01b03909116906135816001806305f5e0ff612e37565b60008581526014602090815260408083208490556013909152902080546001600160a01b0319163317905590506135b88285612d55565b50505050600d54811461187357600080fd5b826001600160a01b03166135dd826116ea565b6001600160a01b0316146136225760405162461bcd60e51b81526004018080602001828103825260298152602001806144e66029913960400191505060405180910390fd5b6001600160a01b0382166136675760405162461bcd60e51b815260040180806020018281038252602481526020018061421f6024913960400191505060405180910390fd5b61367081613c72565b6001600160a01b038316600090815260036020526040902061369190613cad565b6001600160a01b03821660009081526003602052604090206136b290613cc4565b60008181526001602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b03821660009081526005602052604081205461373890600163ffffffff613ccd16565b6000838152600660205260409020549091508082146137d3576001600160a01b038416600090815260056020526040812080548490811061377557fe5b906000526020600020015490508060056000876001600160a01b03166001600160a01b0316815260200190815260200160002083815481106137b357fe5b600091825260208083209091019290925591825260069052604090208190555b6001600160a01b03841660009081526005602052604090208054906137fc90600019830161408d565b5050505050565b6001600160a01b0390911660009081526005602081815260408084208054868652600684529185208290559282526001810183559183529091200155565b6001600160a01b03821661389c576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b6138a581612c71565b156138f7576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260016020908152604080832080546001600160a01b0319166001600160a01b03871690811790915583526003909152902061393690613cc4565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880155565b6060611a5b8343036001430384613d0f565b600081831315613a095760405162461bcd60e51b81526004018080602001828103825260248152602001806142436024913960400191505060405180910390fd5b82838303600101612fad86613e29565b6000613a2d846001600160a01b0316613f41565b613a3957506001612d2e565b6000846001600160a01b031663150b7a02613a52612c8e565b8887876040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ad7578181015183820152602001613abf565b50505050905090810190601f168015613b045780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015613b2657600080fd5b505af1158015613b3a573d6000803e3d6000fd5b505050506040513d6020811015613b5057600080fd5b50516001600160e01b031916630a85bd0160e11b14915050949350505050565b60008151600114613bc8576040805162461bcd60e51b815260206004820152601a60248201527f52616e646f6d2e6e6578743a20696e76616c696420706172616d000000000000604482015290519081900360640190fd5b81600081518110613bd557fe5b6020026020010151604051602001808281526020019150506040516020818303038152906040528051906020012082600081518110613c1057fe5b60200260200101818152505081600081518110613c2957fe5b602002602001015160001c9050919050565b8151602080840151600092918210801590613c595750602082038111155b8015612e53575060208203848201111595945050505050565b6000818152600260205260409020546001600160a01b03161561187357600090815260026020526040902080546001600160a01b0319169055565b8054613cc090600163ffffffff613ccd16565b9055565b80546001019055565b6000611a5b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613f78565b6060826001430310158015613d245750838310155b613d5f5760405162461bcd60e51b81526004018080602001828103825260278152602001806142f96027913960400191505060405180910390fd5b6060848403600201604051908082528060200260200182016040528015613d90578160200160208202803883390190505b5060408051436020808301919091528183018790528251808303840181526060909201909252805191012090915060005b8686038111613e1e578087014082604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120838260010181518110613e0b57fe5b6020908102919091010152600101613dc1565b509095945050505050565b60006001825111613e81576040805162461bcd60e51b815260206004820152601d60248201527f52616e646f6d53616c742e6e6578743a20696e76616c696420706f6f6c000000604482015290519081900360640190fd5b6000600183510383600081518110613e9557fe5b602002602001015160001c81613ea757fe5b0660010190506000838281518110613ebb57fe5b60200260200101516040516020018082815260200191505060405160208183030381529060405280519060200120905083600081518110613ef857fe5b602002602001015160001c60010160001b84600081518110613f1657fe5b60200260200101818152505080848381518110613f2f57fe5b60209081029190910101529392505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708115801590612d2e5750141592915050565b600081848411156140075760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613fcc578181015183820152602001613fb4565b50505050905090810190601f168015613ff95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061405057805160ff191683800117855561407d565b8280016001018555821561407d579182015b8281111561407d578251825591602001919060010190614062565b506140899291506140ad565b5090565b81548183558181111561121a5760008381526020902061121a9181019083015b610ec491905b8082111561408957600081556001016140b356fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573733c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f323030302f737667272077696474683d2736343027206865696768743d27363430272076696577426f783d27302030203634302036343027207374796c653d277374726f6b652d77696474683a303b206261636b67726f756e642d636f6c6f723a233132313231323b273e41756374696f6e206973206e6f74206163746976652e204e65787420746f6b656e2069733a2052616e646f6d2e756e69666f726d5f75696e743a20696e76616c696420696e74657276616c4552433732313a207472616e7366657220746f20746865207a65726f206164647265737352616e646f6d53616c742e756e69666f726d3a20696e76616c696420696e74657276616c5371756967676c792073616c652068617320636f6e636c756465642e20476f6f64206c75636b20707279696e67206f6e65206f7574206f66207468652068616e6473206f6620736f6d656f6e65206f6e20746865207365636f6e64617279206d61726b65742e4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e52616e646f6d53616c742e696e69743a20696e76616c696420626c6f636b20696e74657276616c57616974696e67206f6e2041756374696f6e65657220746f2063616c6c20456e642041756374696f6e2e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e3b73746f702d6f7061636974793a3027202f3e3c73746f70206f66667365743d273130302527207374796c653d2773746f702d636f6c6f723a23526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c653b73746f702d6f7061636974793a3127202f3e3c2f72616469616c4772616469656e743e4552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e52616e646f6d2e756e69666f726d5f696e743a20696e76616c696420696e74657276616c4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572526f6c65733a206163636f756e7420697320746865207a65726f20616464726573734552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e273e3c73746f70206f66667365743d27302527207374796c653d2773746f702d636f6c6f723a234552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724f6e6c79206f6666696369616c2041756374696f6e656572732063616e20656e6420616e2061756374696f6e2e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e6473a265627a7a72315820090c926cad1236c8fa50d210a85f7af1a80ccc93ea9fab64443e7095fc378e0864736f6c634300050e0032

Deployed Bytecode Sourcemap

56329:17071:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18251:135;;8:9:-1;5:2;;;30:1;27;20:12;5:2;18251:135:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18251:135:0;-1:-1:-1;;;;;;18251:135:0;;:::i;:::-;;;;;;;;;;;;;;;;;;44719:85;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44719:85:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;44719:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23112:204;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23112:204:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23112:204:0;;:::i;:::-;;;;-1:-1:-1;;;;;23112:204:0;;;;;;;;;;;;;;22394:425;;8:9:-1;5:2;;;30:1;27;20:12;5:2;22394:425:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;22394:425:0;;;;;;;;:::i;:::-;;71921:127;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71921:127:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71921:127:0;;;;:::i;56932:21::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56932:21:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;36563:96;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36563:96:0;;;:::i;:::-;;;;;;;;;;;;;;;;69042:433;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69042:433:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69042:433:0;;-1:-1:-1;;;;;69042:433:0;;;;;;;;:::i;65772:502::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65772:502:0;;;:::i;24795:292::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24795:292:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;24795:292:0;;;;;;;;;;;;;;;;;:::i;66863:378::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66863:378:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;66863:378:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;66863:378:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;66863:378:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;66863:378:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;66863:378:0;;-1:-1:-1;66863:378:0;;-1:-1:-1;;;;;66863:378:0:i;36172:232::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;36172:232:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;36172:232:0;;;;;;;;:::i;68921:113::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68921:113:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;68921:113:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;68921:113:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;68921:113:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;68921:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;68921:113:0;;-1:-1:-1;68921:113:0;;-1:-1:-1;;;;;68921:113:0:i;25749:134::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;25749:134:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;25749:134:0;;;;;;;;;;;;;;;;;:::i;56853:33::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56853:33:0;;;:::i;72164:1223::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72164:1223:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;72164:1223:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37005:199;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37005:199:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;37005:199:0;;:::i;56960:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56960:38:0;;;:::i;57005:37::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57005:37:0;;;:::i;21735:228::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21735:228:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21735:228:0;;:::i;64343:609::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64343:609:0;;;:::i;21298:211::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;21298:211:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21298:211:0;-1:-1:-1;;;;;21298:211:0;;:::i;2859:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2859:140:0;;;:::i;71028:263::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71028:263:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71028:263:0;;;;:::i;68685:222::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;68685:222:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68685:222:0;;:::i;56513:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56513:32:0;;;:::i;2048:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2048:79:0;;;:::i;2414:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;2414:94:0;;;:::i;56893:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56893:26:0;;;:::i;44919:89::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;44919:89:0;;;:::i;57081:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57081:25:0;;;:::i;64964:796::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64964:796:0;;;;:::i;23617:254::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;23617:254:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;23617:254:0;;;;;;;;;;:::i;57204:31::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57204:31:0;;;:::i;26620:272::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;26620:272:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;26620:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;26620:272:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;26620:272:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;26620:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;26620:272:0;;-1:-1:-1;26620:272:0;;-1:-1:-1;;;;;26620:272:0:i;70456:144::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70456:144:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70456:144:0;-1:-1:-1;;;;;70456:144:0;;:::i;69612:119::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69612:119:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69612:119:0;-1:-1:-1;;;;;69612:119:0;;:::i;72060:98::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;72060:98:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;72060:98:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;72060:98:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;72060:98:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;72060:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;72060:98:0;;-1:-1:-1;72060:98:0;;-1:-1:-1;;;;;72060:98:0:i;71303:606::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71303:606:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71303:606:0;;;;:::i;70200:244::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70200:244:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70200:244:0;;:::i;69487:113::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;69487:113:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69487:113:0;-1:-1:-1;;;;;69487:113:0;;:::i;57885:6360::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57885:6360:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57885:6360:0;;:::i;70895:121::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70895:121:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70895:121:0;;;;:::i;24201:147::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;24201:147:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;24201:147:0;;;;;;;;;;:::i;57171:26::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57171:26:0;;;:::i;64253:78::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64253:78:0;;;:::i;70612:271::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;70612:271:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70612:271:0;-1:-1:-1;;;;;70612:271:0;;:::i;3154:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;3154:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3154:109:0;-1:-1:-1;;;;;3154:109:0;;:::i;57113:21::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57113:21:0;;;:::i;57049:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57049:25:0;;;:::i;57141:23::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57141:23:0;;;:::i;67253:1416::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67253:1416:0;;;:::i;18251:135::-;-1:-1:-1;;;;;;18345:33:0;;18321:4;18345:33;;;;;;;;;;;;;18251:135;;;;:::o;44719:85::-;44791:5;44784:12;;;;;;;;-1:-1:-1;;44784:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44758:13;;44784:12;;44791:5;;44784:12;;44791:5;44784:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44719:85;;:::o;23112:204::-;23171:7;23199:16;23207:7;23199;:16::i;:::-;23191:73;;;;-1:-1:-1;;;23191:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23284:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;23284:24:0;;23112:204::o;22394:425::-;22458:13;22474:16;22482:7;22474;:16::i;:::-;22458:32;;22515:5;-1:-1:-1;;;;;22509:11:0;:2;-1:-1:-1;;;;;22509:11:0;;;22501:57;;;;-1:-1:-1;;;22501:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22595:5;-1:-1:-1;;;;;22579:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;22579:21:0;;:62;;;;22604:37;22621:5;22628:12;:10;:12::i;:::-;22604:16;:37::i;:::-;22571:154;;;;-1:-1:-1;;;22571:154:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22738:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;22738:29:0;-1:-1:-1;;;;;22738:29:0;;;;;;;;;22783:28;;22738:24;;22783:28;;;;;;;22394:425;;;:::o;71921:127::-;72020:20;;71981:19;72020:20;;;:11;:20;;;;;;-1:-1:-1;;;;;72020:20:0;;71921:127::o;56932:21::-;;;;;;:::o;36563:96::-;36634:10;:17;36563:96;:::o;69042:433::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;69150:19;;69173:2;69150:19;;;;:25;;69142:34;;;;;;69211:2;69195:12;:18;;;;69187:27;;;;;;69231:34;;;69277:42;69231:34;;;:20;:34;;;;;;-1:-1:-1;;;;;69231:34:0;69227:167;;69355:19;;;;;;;;:23;69333:45;-1:-1:-1;;69333:45:0;;;;;;69227:167;69414:34;;;;;;:20;:34;;;;;:53;;-1:-1:-1;;;;;;69414:53:0;-1:-1:-1;;;;;69414:53:0;;;;;;;;;;69042:433::o;65772:502::-;65861:13;;65822:22;;65861:13;;65857:410;;65904:9;;;;;;;;:17;;:9;:17;65900:287;;;65974:3;65959:10;;65970:3;65959:14;:18;;;;;;65942:35;;65900:287;;;66016:11;;;;;;;:19;;66031:4;66016:19;66012:175;;;66087:3;66073:10;;66084:2;66073:13;:17;;;;66012:175;-1:-1:-1;66161:10:0;;66012:175;65857:410;;;-1:-1:-1;66241:10:0;;65772:502;:::o;24795:292::-;24939:41;24958:12;:10;:12::i;:::-;24972:7;24939:18;:41::i;:::-;24931:103;;;;-1:-1:-1;;;24931:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25047:32;25061:4;25067:2;25071:7;25047:13;:32::i;:::-;24795:292;;;:::o;66863:378::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;66961:1;66944:13;:11;:13::i;:::-;:18;;66936:27;;;;;;66984:15;67002:13;:11;:13::i;:::-;67036:21;;;;:12;:21;;;;;;;;:32;;66984:31;;-1:-1:-1;67036:32:0;;:21;;:32;;;;:::i;:::-;-1:-1:-1;67079:20:0;;;;:11;:20;;;;;;;;:33;;-1:-1:-1;;;;;;67079:33:0;67102:10;67079:33;;;;;;67153:27;;;:15;:27;;;;;;;;67183:3;67153:33;67123:63;;67207:26;;67091:7;67207:5;:26::i;:::-;2317:1;66863:378;:::o;36172:232::-;36252:7;36288:16;36298:5;36288:9;:16::i;:::-;36280:5;:24;36272:80;;;;-1:-1:-1;;;36272:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36370:19:0;;;;;;:12;:19;;;;;:26;;36390:5;;36370:26;;;;;;;;;;;;;;36363:33;;36172:232;;;;:::o;68921:113::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;68998:28;;;;:19;;:28;;;;;:::i;25749:134::-;25836:39;25853:4;25859:2;25863:7;25836:39;;;;;;;;;;;;:16;:39::i;56853:33::-;;;;;;;;;;;;;;;-1:-1:-1;;56853:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;72164:1223::-;72206:27;72235:18;72255:20;72277:23;72336:13;:11;:13::i;:::-;72330:3;:19;72315:34;;72388:8;;;;;;;;;;;56995:3;72375:21;72360:36;;72452:15;72433:16;;:34;72407:61;;72512:1;72493:16;:20;:40;;;;;72532:1;72517:12;:16;;;72493:40;72489:295;;;;;;72635:1;72616:16;:20;:42;;;;;72656:2;72640:13;:11;:13::i;:::-;:18;72616:42;72612:172;;;;;;-1:-1:-1;72771:1:0;72612:172;72800:17;72796:574;;72850:27;;;;;;;;;;;;;-1:-1:-1;;;72850:27:0;;;72834:43;;72796:574;;;72908:13;;;;72904:466;;73029:35;73051:12;73045:3;:18;73029:15;:35::i;:::-;72970:95;;;;;;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;72970:95:0;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;72970:95:0;;;72947:119;;72904:466;;;73117:1;73097:16;:21;73093:277;;73151:52;;;;;;;;;;;;;;;;;73135:68;;73093:277;;;73308:35;73330:12;73324:3;:18;73308:15;:35::i;:::-;73268:89;;;;;;-1:-1:-1;;;73268:89:0;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;73268:89:0;;;;;;;-1:-1:-1;;;73268:89:0;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;73268:89:0;;;73245:113;;73093:277;72164:1223;;;;:::o;37005:199::-;37063:7;37099:13;:11;:13::i;:::-;37091:5;:21;37083:78;;;;-1:-1:-1;;;37083:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37179:10;37190:5;37179:17;;;;;;;;;;;;;;;;37172:24;;37005:199;;;:::o;56960:38::-;56995:3;56960:38;:::o;57005:37::-;57040:2;57005:37;:::o;21735:228::-;21790:7;21826:20;;;:11;:20;;;;;;-1:-1:-1;;;;;21826:20:0;21865:19;21857:73;;;;-1:-1:-1;;;21857:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21950:5;21735:228;-1:-1:-1;;21735:228:0:o;64343:609::-;47517:13;:18;;47534:1;47517:18;;;;;;;64406:14;;;;;;;:22;;;64398:31;;;;;;64448:13;;;;:22;64440:31;;;;;;57040:2;64490:13;:11;:13::i;:::-;:27;;64482:142;;;;-1:-1:-1;;;64482:142:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64648:19;:17;:19::i;:::-;64635:10;:32;64697:15;64715:5;64697:23;64678:16;:42;64731:13;:20;;64747:4;-1:-1:-1;;64731:20:0;;;;;;;64772:15;:28;;64790:10;-1:-1:-1;;;;;;64772:28:0;;;;;;;;64811:15;:28;;;;;;;;;-1:-1:-1;64880:27:0;;;:15;64772;64880:27;64772:15;64880:27;;;;64910:1;64880:31;;;64850:61;;;64932:8;:12;;;;;;;;47629:13;;47613:29;;47605:38;;;;;;64343:609;:::o;21298:211::-;21353:7;-1:-1:-1;;;;;21381:19:0;;21373:74;;;;-1:-1:-1;;;21373:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;21467:24:0;;;;;;:17;:24;;;;;:34;;:32;:34::i;2859:140::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;2942:6;;2921:40;;2958:1;;-1:-1:-1;;;;;2942:6:0;;2921:40;;2958:1;;2921:40;2972:6;:19;;-1:-1:-1;;;;;;2972:19:0;;;2859:140::o;71028:263::-;71084:25;71136:1;71125:7;:12;;;71122:162;;71163:21;;;;;;;:12;:21;;;;;;;;;71149:35;;;;;;-1:-1:-1;;71149:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71163:21;;71149:35;;71163:21;71149:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71122:162;;;71251:20;;;;;;;:11;:20;;;;;;71236:36;;:14;:36::i;68685:222::-;68745:26;68784:16;68809:36;68819:4;68825:1;68842;68835:4;:8;68809:9;:36::i;:::-;68784:62;;68879:19;68887:10;68879:19;;:7;:19::i;:::-;68857:42;68685:222;-1:-1:-1;;;68685:222:0:o;56513:32::-;;;;;;:::o;2048:79::-;2113:6;;-1:-1:-1;;;;;2113:6:0;2048:79;:::o;2414:94::-;2494:6;;2454:4;;-1:-1:-1;;;;;2494:6:0;2478:12;:10;:12::i;:::-;-1:-1:-1;;;;;2478:22:0;;2471:29;;2414:94;:::o;56893:26::-;;;;;;;;;;;;;;;-1:-1:-1;;56893:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44919:89;44993:7;44986:14;;;;;;;;-1:-1:-1;;44986:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44960:13;;44986:14;;44993:7;;44986:14;;44993:7;44986:14;;;;;;;;;;;;;;;;;;;;;;;;57081:25;;;;;;:::o;64964:796::-;47517:13;:18;;47534:1;47517:18;;;;;65072:8;;;;;;56995:3;65059:21;65052:28;;;;;;;65044:37;;;;;;65119:10;;65113:3;:16;;;65100:9;:29;;65092:38;;;;;;65149:13;;;;:21;;:13;:21;65141:30;;;;;;65208:16;;65190:15;:34;65182:43;;;;;;65250:8;;;;65238:101;65264:8;;;;;;:14;;65260:18;;;;;;65238:101;;;65299:15;;;;;;;:12;:15;;;;;:28;;-1:-1:-1;;;;;;65299:28:0;65317:10;65299:28;;;;65280:3;65238:101;;;-1:-1:-1;65370:8:0;;;-1:-1:-1;;65359:25:0;;65370:8;;;;:14;;65359:25;;;;;;65451:10;-1:-1:-1;65435:27:0;;;:15;:27;;;;;;;:33;;;;;;65405:63;;;65507:13;:11;:13::i;:::-;65534:78;;65481:39;;-1:-1:-1;65542:42:0;;65609:2;65605:3;65595:9;:13;:16;65534:78;;;;;;;;;65595:16;65542:42;65534:78;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65534:78:0;65623:28;65670:32;65686:15;65670;:32::i;:::-;65715:35;;65623:81;;-1:-1:-1;;;;;;65715:21:0;;;65747:2;65737:9;:12;65715:35;;;;;;;;;65737:12;65715:21;:35;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65715:35:0;47593:1;;47629:13;;47613:12;:29;47605:38;;;;;23617:254;23703:12;:10;:12::i;:::-;-1:-1:-1;;;;;23697:18:0;:2;-1:-1:-1;;;;;23697:18:0;;;23689:56;;;;;-1:-1:-1;;;23689:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;23797:8;23758:18;:32;23777:12;:10;:12::i;:::-;-1:-1:-1;;;;;23758:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;23758:32:0;;;:36;;;;;;;;;;;;:47;;-1:-1:-1;;23758:47:0;;;;;;;;;;;23836:12;:10;:12::i;:::-;23821:42;;;;;;;;;;-1:-1:-1;;;;;23821:42:0;;;;;;;;;;;;;;23617:254;;:::o;57204:31::-;;;;:::o;26620:272::-;26735:41;26754:12;:10;:12::i;:::-;26768:7;26735:18;:41::i;:::-;26727:103;;;;-1:-1:-1;;;26727:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26841:43;26859:4;26865:2;26869:7;26878:5;26841:17;:43::i;:::-;26620:272;;;;:::o;70456:144::-;-1:-1:-1;;;;;70564:28:0;70526:18;70564:28;;;:15;:28;;;;;;;70456:144::o;69612:119::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;69689:34;:12;69709:13;69689:34;:19;:34;:::i;72060:98::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;72129:21;;;;:12;;:21;;;;;:::i;71303:606::-;71436:20;;;71365:17;71436:20;;;:11;:20;;;;;;71395:26;;71424:33;;:11;:33::i;:::-;71395:62;-1:-1:-1;71481:12:0;;;71478:424;;71517:1;71505:13;;71478:424;;;71548:7;:12;;71559:1;71548:12;71545:357;;;71585:1;71573:13;;71545:357;;;71620:7;:12;;71631:1;71620:12;71617:285;;;71657:1;71645:13;;71617:285;;;71692:7;:12;;71703:1;71692:12;71689:213;;;71729:1;71717:13;;71689:213;;;71764:7;:12;;71775:1;71764:12;71761:141;;;71801:1;71789:13;;71761:141;;;71856:34;71876:9;71886:1;71888;71856:19;:34::i;71761:141::-;71303:606;;;;:::o;70200:244::-;70253:13;70287:11;70295:2;70287:7;:11::i;:::-;70279:71;;;;-1:-1:-1;;;70279:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70392:12;70406:28;70430:2;70406:15;:28::i;:::-;70375:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70375:60:0;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;70375:60:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;70375:60:0;;;70361:75;;70200:244;;;:::o;69487:113::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;69561:31;:12;69578:13;69561:31;:16;:31;:::i;57885:6360::-;57944:13;57970:26;57999:17;58011:4;57999:11;:17::i;:::-;58059:15;;;58069:4;58059:15;;;;;;;;;57970:46;;-1:-1:-1;58037:19:0;;58059:15;;;;21:6:-1;;104:10;58059:15:0;87:34:-1;135:17;;-1:-1;58059:15:0;58037:37;;58095:17;58115:34;58135:9;58145:1;58147;58115:19;:34::i;:::-;58095:54;;58160:19;58188:9;58201:1;58182:20;58160:42;;58213:16;58250:162;58264:6;58250:162;;;;;;;;;;;;;;;;;:13;:162::i;:::-;58521:5;58517:5618;58532:13;58530:15;;:1;:15;58517:5618;;;58635:49;58649:6;58635:49;;;;;;;;;;;;;;;;;:13;:49::i;:::-;58699:24;58713:6;58721:1;58699:13;:24::i;:::-;58738:64;58752:6;58738:64;;;;;;;;;;;;;;;;;:13;:64::i;:::-;58855:138;58869:6;58877:37;58897:9;58907:2;58910:3;58877:19;:37::i;:::-;58916;58936:9;58946:2;58949:3;58916:19;:37::i;:::-;58955;58975:9;58985:2;58988:3;58955:19;:37::i;:::-;58855:13;:138::i;:::-;59022:83;59036:6;59022:83;;;;;;;;;;;;;;;;;:13;:83::i;:::-;59171:37;59191:9;59201:2;59204:3;59171:19;:37::i;:::-;59157:51;;59223:60;59237:6;59245:11;59258;59271;59223:13;:60::i;:::-;59298:61;59312:6;59298:61;;;;;;;;;;;;;;;;;:13;:61::i;:::-;59436:46;59450:6;59436:46;;;;;;;;;;;;;-1:-1:-1;;;59436:46:0;;;:13;:46::i;:::-;59497:24;59511:6;59519:1;59497:13;:24::i;:::-;59536:37;59550:6;59536:37;;;;;;;;;;;;;-1:-1:-1;;;59536:37:0;;;:13;:37::i;:::-;59623:138;59637:6;59645:37;59665:9;59675:2;59678:3;59645:19;:37::i;59623:138::-;59776:49;59790:6;59776:49;;;;;;;;;;;;;;;;;:13;:49::i;:::-;59996:60;60010:6;60018:37;60037:9;60047:3;60051;60018:18;:37::i;:::-;59996:13;:60::i;:::-;60083:26;60097:6;60083:26;;;;;;;;;;;;;-1:-1:-1;;;60083:26:0;;;:13;:26::i;:::-;60124:60;60138:6;60146:37;60165:9;60175:3;60179;60146:18;:37::i;60124:60::-;60228:9;60241:1;60228:14;60225:3827;;;60263:27;60277:6;60263:27;;;;;;;;;;;;;-1:-1:-1;;;60263:27:0;;;:13;:27::i;:::-;60331:5;60327:982;60342:2;60340:1;:4;60327:982;;;60444:26;60458:6;60444:26;;;;;;;;;;;;;-1:-1:-1;;;60444:26:0;;;:13;:26::i;:::-;60493:59;60507:6;60515:36;60534:9;-1:-1:-1;;60548:2:0;60515:18;:36::i;60493:59::-;60589:26;60603:6;60589:26;;;;;;;;;;;;;-1:-1:-1;;;60589:26:0;;;:13;:26::i;:::-;60638:59;60652:6;60660:36;60679:9;-1:-1:-1;;60693:2:0;60660:18;:36::i;60638:59::-;60734:26;60748:6;60734:26;;;;;;;;;;;;;-1:-1:-1;;;60734:26:0;;;:13;:26::i;:::-;60783:59;60797:6;60805:36;60824:9;-1:-1:-1;;60838:2:0;60805:18;:36::i;60783:59::-;60879:26;60893:6;60879:26;;;;;;;;;;;;;-1:-1:-1;;;60879:26:0;;;:13;:26::i;:::-;60928:59;60942:6;60950:36;60969:9;-1:-1:-1;;60983:2:0;60950:18;:36::i;60928:59::-;61024:26;61038:6;61024:26;;;;;;;;;;;;;-1:-1:-1;;;61024:26:0;;;:13;:26::i;:::-;61073:59;61087:6;61095:36;61114:9;-1:-1:-1;;61128:2:0;61095:18;:36::i;61073:59::-;61168:26;61182:6;61168:26;;;;;;;;;;;;;-1:-1:-1;;;61168:26:0;;;:13;:26::i;:::-;61217:59;61231:6;61239:36;61258:9;-1:-1:-1;;61272:2:0;61239:18;:36::i;61217:59::-;60346:3;;60327:982;;;;60225:3827;;;61351:9;61364:1;61351:14;61348:2704;;;61386:27;61400:6;61386:27;;;;;;;;;;;;;-1:-1:-1;;;61386:27:0;;;:13;:27::i;:::-;61454:5;61450:699;61465:2;61463:1;:4;61450:699;;;61574:26;61588:6;61574:26;;;;;;;;;;;;;-1:-1:-1;;;61574:26:0;;;:13;:26::i;:::-;61623:59;61637:6;61645:36;61664:9;-1:-1:-1;;61678:2:0;61645:18;:36::i;61623:59::-;61719:26;61733:6;61719:26;;;;;;;;;;;;;-1:-1:-1;;;61719:26:0;;;:13;:26::i;:::-;61768:59;61782:6;61790:36;61809:9;-1:-1:-1;;61823:2:0;61790:18;:36::i;61768:59::-;61864:26;61878:6;61864:26;;;;;;;;;;;;;-1:-1:-1;;;61864:26:0;;;:13;:26::i;:::-;61913:59;61927:6;61935:36;61954:9;-1:-1:-1;;61968:2:0;61935:18;:36::i;61913:59::-;62008:26;62022:6;62008:26;;;;;;;;;;;;;-1:-1:-1;;;62008:26:0;;;:13;:26::i;:::-;62057:59;62071:6;62079:36;62098:9;-1:-1:-1;;62112:2:0;62079:18;:36::i;62057:59::-;61469:3;;61450:699;;61348:2704;62191:9;62204:1;62191:14;62188:1864;;;62226:27;62240:6;62226:27;;;;;;;;;;;;;-1:-1:-1;;;62226:27:0;;;:13;:27::i;:::-;62294:5;62290:696;62305:2;62303:1;:4;62290:696;;;62411:26;62425:6;62411:26;;;;;;;;;;;;;-1:-1:-1;;;62411:26:0;;;:13;:26::i;:::-;62460:59;62474:6;62482:36;62501:9;-1:-1:-1;;62515:2:0;62482:18;:36::i;62460:59::-;62556:26;62570:6;62556:26;;;;;;;;;;;;;-1:-1:-1;;;62556:26:0;;;:13;:26::i;:::-;62605:59;62619:6;62627:36;62646:9;-1:-1:-1;;62660:2:0;62627:18;:36::i;62605:59::-;62701:26;62715:6;62701:26;;;;;;;;;;;;;-1:-1:-1;;;62701:26:0;;;:13;:26::i;:::-;62750:59;62764:6;62772:36;62791:9;-1:-1:-1;;62805:2:0;62772:18;:36::i;62750:59::-;62845:26;62859:6;62845:26;;;;;;;;;;;;;-1:-1:-1;;;62845:26:0;;;:13;:26::i;:::-;62894:59;62908:6;62916:36;62935:9;-1:-1:-1;;62949:2:0;62916:18;:36::i;62894:59::-;62309:3;;62290:696;;62188:1864;63028:9;63041:1;63028:14;63025:1027;;;63063:27;63077:6;63063:27;;;;;;;;;;;;;-1:-1:-1;;;63063:27:0;;;:13;:27::i;:::-;63131:5;63127:414;63142:3;63140:1;:5;63127:414;;;63256:26;63270:6;63256:26;;;;;;;;;;;;;-1:-1:-1;;;63256:26:0;;;:13;:26::i;:::-;63305:59;63319:6;63327:36;63346:9;-1:-1:-1;;63360:2:0;63327:18;:36::i;63305:59::-;63400:26;63414:6;63400:26;;;;;;;;;;;;;-1:-1:-1;;;63400:26:0;;;:13;:26::i;:::-;63449:59;63463:6;63471:36;63490:9;-1:-1:-1;;63504:2:0;63471:18;:36::i;63449:59::-;63147:3;;63127:414;;63025:1027;63583:9;63596:1;63583:14;63580:472;;;63640:5;63636:383;63651:2;63649:1;:4;63636:383;;;63734:26;63748:6;63734:26;;;;;;;;;;;;;-1:-1:-1;;;63734:26:0;;;:13;:26::i;:::-;63783:59;63797:6;63805:36;63824:9;-1:-1:-1;;63838:2:0;63805:18;:36::i;63783:59::-;63878:26;63892:6;63878:26;;;;;;;;;;;;;-1:-1:-1;;;63878:26:0;;;:13;:26::i;:::-;63927:59;63941:6;63949:36;63968:9;-1:-1:-1;;63982:2:0;63949:18;:36::i;63927:59::-;63655:3;;63636:383;;;;63580:472;64080:29;64094:6;64080:29;;;;;;;;;;;;;-1:-1:-1;;;64080:29:0;;;:13;:29::i;:::-;58547:3;;58517:5618;;;;64155:31;64169:6;64155:31;;;;;;;;;;;;;-1:-1:-1;;;64155:31:0;;;:13;:31::i;:::-;64214:23;64230:6;64214:15;:23::i;:::-;64207:30;57885:6360;-1:-1:-1;;;;;;;57885:6360:0:o;70895:121::-;70991:17;;70952:19;70991:17;;;:12;:17;;;;;;-1:-1:-1;;;;;70991:17:0;;70895:121::o;24201:147::-;-1:-1:-1;;;;;24305:25:0;;;24281:4;24305:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;24201:147::o;57171:26::-;;;;;;;;;:::o;64253:78::-;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;64302:14;:21;;-1:-1:-1;;64302:21:0;;;;;64253:78::o;70612:271::-;70679:21;;70713:163;70732:3;70728:1;:7;;;70713:163;;;70759:15;;;;;;;:12;:15;;;;;;-1:-1:-1;;;;;70759:30:0;;;:15;;:30;70756:107;;;70828:15;70846:1;70828:19;70810:37;;70756:107;70737:3;;70713:163;;3154:109;2260:9;:7;:9::i;:::-;2252:54;;;;;-1:-1:-1;;;2252:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2252:54:0;;;;;;;;;;;;;;;3227:28;3246:8;3227:18;:28::i;57113:21::-;;;;;;;;;:::o;57049:25::-;;;;:::o;57141:23::-;;;;;;;;;:::o;67253:1416::-;67324:2;67307:13;:11;:13::i;:::-;:19;67303:209;;67366:16;;67347:15;:35;;:54;;;-1:-1:-1;67386:8:0;;;;67398:3;67386:15;67347:54;67339:63;;;;;;67303:209;;;67471:16;;67452:15;:35;;67444:44;;;;;;67532:28;:12;67549:10;67532:28;:16;:28;:::i;:::-;67524:86;;;;-1:-1:-1;;;67524:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67631:11;:9;:11::i;:::-;67653:13;:21;;-1:-1:-1;;67653:21:0;;;67669:5;67687:115;67706:3;67702:1;:7;;;67687:115;;;67730:15;;;67748:42;67730:15;;;:12;:15;;;;;:60;;-1:-1:-1;;;;;;67730:60:0;;;;67711:3;67687:115;;;-1:-1:-1;67834:8:0;;67845:2;67834:8;;;;:13;67830:300;;;67864:9;:16;;-1:-1:-1;;;;67864:16:0;;;;;67895:19;;;67830:300;;;67945:8;;67956:2;67945:8;;;;:13;67941:189;;;67975:11;:18;;-1:-1:-1;;;;67975:18:0;;;;;68008:17;;;67941:189;;;68067:9;:17;;-1:-1:-1;;68099:19:0;;;67941:189;68150:8;:12;;-1:-1:-1;;68150:12:0;;;68217:21;68161:1;68289;68217:21;68273:17;68291:1;68273:19;68250:42;;68303:24;68346:1;68330:15;:17;;;;;;68348:1;68330:19;;-1:-1:-1;68371:7:0;68366:225;68388:19;;;;;;68384:23;;;;68366:225;;;68480:23;;;;68425:36;68480:23;;;:20;:23;;;;;;68559:19;;-1:-1:-1;;;;;68480:23:0;;;;;;68516:63;;68559:19;68546:12;68559:19;68546:32;;;;;68516:63;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;68409:3:0;;68366:225;;;-1:-1:-1;68611:46:0;;68619:10;;68611:46;;;;;68640:16;;68611:46;;;;68640:16;68619:10;68611:46;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;28085:155:0;28142:4;28175:20;;;:11;:20;;;;;;-1:-1:-1;;;;;28175:20:0;28213:19;;;28085:155::o;807:98::-;887:10;807:98;:::o;28610:333::-;28695:4;28720:16;28728:7;28720;:16::i;:::-;28712:73;;;;-1:-1:-1;;;28712:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28796:13;28812:16;28820:7;28812;:16::i;:::-;28796:32;;28858:5;-1:-1:-1;;;;;28847:16:0;:7;-1:-1:-1;;;;;28847:16:0;;:51;;;;28891:7;-1:-1:-1;;;;;28867:31:0;:20;28879:7;28867:11;:20::i;:::-;-1:-1:-1;;;;;28867:31:0;;28847:51;:87;;;;28902:32;28919:5;28926:7;28902:16;:32::i;:::-;28839:96;28610:333;-1:-1:-1;;;;28610:333:0:o;37588:245::-;37674:38;37694:4;37700:2;37704:7;37674:19;:38::i;:::-;37725:47;37758:4;37764:7;37725:32;:47::i;:::-;37785:40;37813:2;37817:7;37785:27;:40::i;38098:202::-;38162:24;38174:2;38178:7;38162:11;:24::i;:::-;38199:40;38227:2;38231:7;38199:27;:40::i;:::-;38252;38284:7;38252:31;:40::i;69739:453::-;69796:13;69824:7;69820:45;;-1:-1:-1;69845:10:0;;;;;;;;;;;;-1:-1:-1;;;69845:10:0;;;;;;69820:45;69882:2;69873:6;69918:61;69925:6;;69918:61;;69945:5;;69967:2;69962:7;;;;69918:61;;;69987:17;70017:3;70007:14;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;104:10;70007:14:0;87:34:-1;135:17;;-1:-1;70007:14:0;-1:-1:-1;69987:34:0;-1:-1:-1;;;70039:7:0;;70063:95;70070:7;;70063:95;;70124:2;70119;:7;70114:2;:12;70103:25;;70091:4;70096:3;;;;;;;70091:9;;;;;;;;;;;:37;-1:-1:-1;;;;;70091:37:0;;;;;;;;-1:-1:-1;70146:2:0;70140:8;;;;70063:95;;;-1:-1:-1;70180:4:0;69739:453;-1:-1:-1;;;;69739:453:0:o;17020:114::-;17112:14;;17020:114::o;57648:225::-;57719:19;57748:21;57772:30;57794:1;57797:4;57772:21;:30::i;:::-;57748:54;;57830:34;57849:4;57855:3;57860;57830:18;:34::i;:::-;57815:49;57648:225;-1:-1:-1;;;;;57648:225:0:o;27611:272::-;27721:32;27735:4;27741:2;27745:7;27721:13;:32::i;:::-;27772:48;27795:4;27801:2;27805:7;27814:5;27772:22;:48::i;:::-;27764:111;;;;-1:-1:-1;;;27764:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48165:183;48245:18;48249:4;48255:7;48245:3;:18::i;:::-;48237:64;;;;-1:-1:-1;;;48237:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48312:20:0;48335:5;48312:20;;;;;;;;;;;:28;;-1:-1:-1;;48312:28:0;;;48165:183::o;50743:199::-;50852:16;;;50866:1;50852:16;;;;;;;;;50794;;;;50852;;;;;;;105:10:-1;50852:16:0;88:34:-1;136:17;;-1:-1;50852:16:0;50823:45;;50902:4;50894:13;;50879:9;50889:1;50879:12;;;;;;;;;;;;;;;;;:28;50925:9;50743:199;-1:-1:-1;;50743:199:0:o;51780:222::-;51875:7;51908:1;51903;:6;;51895:56;;;;-1:-1:-1;;;51895:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51993:1;51988;51986;:3;51990:1;51986:5;51969:15;51974:9;51969:4;:15::i;:::-;:23;;;;;;:25;;51780:222;-1:-1:-1;;;;51780:222:0:o;47907:178::-;47985:18;47989:4;47995:7;47985:3;:18::i;:::-;47984:19;47976:63;;;;;-1:-1:-1;;;47976:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48050:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;48050:27:0;48073:4;48050:27;;;47907:178::o;52670:410::-;52759:41;52774:6;52788:3;52782:17;52759:14;:41::i;:::-;52751:80;;;;;-1:-1:-1;;;52751:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;52895:2;52887:6;52883:15;52877:22;52997:3;52991:10;52985:2;52977:6;52973:15;52968:3;52964:25;52958:3;52952:10;52947:2;52942:3;52938:12;52933:3;52928;52917:85;-1:-1:-1;53050:10:0;;53041:20;53036:2;53024:15;;;;53017:45;52851:222::o;53226:1872::-;53310:25;53325:6;53333:1;53310:14;:25::i;:::-;53302:64;;;;;-1:-1:-1;;;53302:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53401:221;;;;53571:2;53568:1;53564:10;53561:1;53553:22;-1:-1:-1;53605:1:0;53598:9;;53428:194;-1:-1:-1;53428:194:0;53636:214;;53794:41;53831:2;53828:1;53824:10;53801:21;53818:2;53815:1;53811:10;53808:1;53801:21;;;53794:41;;53864:625;;54056:3;54050:10;;54078:211;;;;54351:2;54345:9;;54376:28;;;;54441:12;54451:1;54448;54441:12;;;54436:17;;54338:117;;54376:28;54390:12;54400:1;54397;54390:12;;;54385:17;;54338:117;;54043:431;;54078:211;54218:52;54265:3;54262:1;54258:11;54225:31;54252:2;54246:3;54243:1;54239:11;54235:20;54232:1;54225:31;;;54218:52;;54043:431;;53891:598;;;;;54503:393;;54695:1;54692;54688:9;54685:2;;;54730:6;;54738:1;54726:14;;54773:2;54770:1;54762:14;54825:1;54822;54818:9;54813:14;;54685:2;54869:12;54879:1;54876;54869:12;;54530:366;54964:2;54956:6;54952:15;54946:2;54938:6;54934:15;54928:22;54924:44;54992:21;55007:5;54999:6;54992:21;;;54982:31;;55076:2;55067:6;55059;55055:19;55051:28;55046:2;55038:6;55034:15;55027:53;53386:1705;;;:::o;55110:1211::-;55213:25;55228:6;55236:1;55213:14;:25::i;:::-;55205:64;;;;;-1:-1:-1;;;55205:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55304:813;;;;55382:3;55378:1;55375;55371:9;55367:19;55422:3;55419:1;55415:11;55470:3;55466:1;55463;55459:9;55455:19;55510:3;55507:1;55503:11;55558:3;55554:1;55551;55547:9;55543:19;55598:3;55595:1;55591:11;55676:2;55670;55665;55660:3;55656:12;55652:21;55647:3;55643:31;55639:40;55628:1;55620:60;55754:2;55748;55743;55738:3;55734:12;55730:21;55725:3;55721:31;55717:40;55713:1;55710;55706:9;55698:60;55832:2;55826;55821;55816:3;55812:12;55808:21;55803:3;55799:31;55795:40;55791:1;55788;55784:9;55776:60;55910:2;55904;55899;55894:3;55890:12;55886:21;55881:3;55877:31;55873:40;55869:1;55866;55862:9;55854:60;55988:2;55982;55977;55972:3;55968:12;55964:21;55959:3;55955:31;55951:40;55947:1;55944;55940:9;55932:60;56066:2;56060;56055;56050:3;56046:12;56042:21;56037:3;56033:31;56029:40;56025:1;56022;56018:9;56010:60;56100:1;56097;56093:9;56088:14;;55337:780;;;;;;;;;;;;;;56185:2;56177:6;56173:15;56167:2;56159:6;56155:15;56149:22;56145:44;56213:23;56234:1;56231;56228;56220:6;56213:23;;;56203:33;;56299:2;56290:6;56282;56278:19;56274:28;56269:2;56261:6;56257:15;56250:53;55289:1025;;;;;:::o;51428:232::-;51520:6;51552:1;51547;:6;;51539:55;;;;-1:-1:-1;;;51539:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52377:281;52439:13;52473:25;52488:6;52496:1;52473:14;:25::i;:::-;52465:69;;;;;-1:-1:-1;;;52465:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52616:2:0;52604:15;;52377:281::o;3369:229::-;-1:-1:-1;;;;;3443:22:0;;3435:73;;;;-1:-1:-1;;;3435:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3545:6;;3524:38;;-1:-1:-1;;;;;3524:38:0;;;;3545:6;;3524:38;;3545:6;;3524:38;3573:6;:17;;-1:-1:-1;;;;;;3573:17:0;-1:-1:-1;;;;;3573:17:0;;;;;;;;;;3369:229::o;48443:203::-;48515:4;-1:-1:-1;;;;;48540:21:0;;48532:68;;;;-1:-1:-1;;;48532:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;48618:20:0;:11;:20;;;;;;;;;;;;;;;48443:203::o;66286:565::-;47517:13;:18;;47534:1;47517:18;;;;;57040:2;66357:13;:11;:13::i;:::-;:27;;66349:55;;;;;-1:-1:-1;;;66349:55:0;;;;;;;;;;;;-1:-1:-1;;;66349:55:0;;;;;;;;;;;;;;;66425:15;66443:13;:11;:13::i;:::-;66425:31;;66477:20;66500:39;66510:13;:11;:13::i;:::-;66526:8;;66524:1;;-1:-1:-1;;66526:8:0;;;;:12;66500:39;:9;:39::i;:::-;66582:37;;;66550:29;66582:37;;;:12;:37;;;;;;66477:62;;-1:-1:-1;;;;;;66582:37:0;;;;66656:23;66582:37;;66670:8;66656:9;:23::i;:::-;66701:20;;;;:11;:20;;;;;;;;:30;;;66742:11;:20;;;;;:33;;-1:-1:-1;;;;;;66742:33:0;66765:10;66742:33;;;66630:50;-1:-1:-1;66796:37:0;66802:21;66713:7;66796:5;:37::i;:::-;47593:1;;;;47629:13;;47613:12;:29;47605:38;;;;;32306:459;32420:4;-1:-1:-1;;;;;32400:24:0;:16;32408:7;32400;:16::i;:::-;-1:-1:-1;;;;;32400:24:0;;32392:78;;;;-1:-1:-1;;;32392:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32489:16:0;;32481:65;;;;-1:-1:-1;;;32481:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32559:23;32574:7;32559:14;:23::i;:::-;-1:-1:-1;;;;;32595:23:0;;;;;;:17;:23;;;;;:35;;:33;:35::i;:::-;-1:-1:-1;;;;;32641:21:0;;;;;;:17;:21;;;;;:33;;:31;:33::i;:::-;32687:20;;;;:11;:20;;;;;;:25;;-1:-1:-1;;;;;;32687:25:0;-1:-1:-1;;;;;32687:25:0;;;;;;;;;32730:27;;32687:20;;32730:27;;;;;;;32306:459;;;:::o;40773:1148::-;-1:-1:-1;;;;;41064:18:0;;41039:22;41064:18;;;:12;:18;;;;;:25;:32;;41094:1;41064:32;:29;:32;:::i;:::-;41107:18;41128:26;;;:17;:26;;;;;;41039:57;;-1:-1:-1;41261:28:0;;;41257:328;;-1:-1:-1;;;;;41328:18:0;;41306:19;41328:18;;;:12;:18;;;;;:34;;41347:14;;41328:34;;;;;;;;;;;;;;41306:56;;41412:11;41379:12;:18;41392:4;-1:-1:-1;;;;;41379:18:0;-1:-1:-1;;;;;41379:18:0;;;;;;;;;;;;41398:10;41379:30;;;;;;;;;;;;;;;;;;;:44;;;;41496:30;;;:17;:30;;;;;:43;;;41257:328;-1:-1:-1;;;;;41674:18:0;;;;;;:12;:18;;;;;:27;;;;;-1:-1:-1;;41674:27:0;;;:::i;:::-;;40773:1148;;;;:::o;39595:186::-;-1:-1:-1;;;;;39709:16:0;;;;;;;:12;:16;;;;;;;;:23;;39680:26;;;:17;:26;;;;;:52;;;39743:16;;;39:1:-1;23:18;;45:23;;39743:30:0;;;;;;;;39595:186::o;30695:335::-;-1:-1:-1;;;;;30767:16:0;;30759:61;;;;;-1:-1:-1;;;30759:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30840:16;30848:7;30840;:16::i;:::-;30839:17;30831:58;;;;;-1:-1:-1;;;30831:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30902:20;;;;:11;:20;;;;;;;;:25;;-1:-1:-1;;;;;;30902:25:0;-1:-1:-1;;;;;30902:25:0;;;;;;;;30938:21;;:17;:21;;;;;:33;;:31;:33::i;:::-;30989;;31014:7;;-1:-1:-1;;;;;30989:33:0;;;31006:1;;30989:33;;31006:1;;30989:33;30695:335;;:::o;39982:164::-;40086:10;:17;;40059:24;;;;:15;:24;;;;;:44;;;39:1:-1;23:18;;45:23;;40114:24:0;;;;;;;39982:164::o;49736:149::-;49806:16;49836:44;49854:3;49841:12;:16;49872:1;49859:12;:14;49875:4;49836;:44::i;50451:203::-;50534:6;50560:1;50555;:6;;50547:55;;;;-1:-1:-1;;;50547:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50648:1;50642;50640;:3;50644:1;50640:5;50621:10;50626:4;50621;:10::i;33367:358::-;33489:4;33516:15;:2;-1:-1:-1;;;;;33516:13:0;;:15::i;:::-;33511:60;;-1:-1:-1;33555:4:0;33548:11;;33511:60;33583:13;33615:2;-1:-1:-1;;;;;33599:36:0;;33636:12;:10;:12::i;:::-;33650:4;33656:7;33665:5;33599:72;;;;;;;;;;;;;-1:-1:-1;;;;;33599:72:0;-1:-1:-1;;;;;33599:72:0;;;;;;-1:-1:-1;;;;;33599:72:0;-1:-1:-1;;;;;33599:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;33599:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;33599:72:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33599:72:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33599:72:0;-1:-1:-1;;;;;;33690:26:0;-1:-1:-1;;;33690:26:0;;-1:-1:-1;;33367:358:0;;;;;;:::o;51049:259::-;51114:7;51142:9;:16;51162:1;51142:21;51134:60;;;;;-1:-1:-1;;;51134:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51247:9;51257:1;51247:12;;;;;;;;;;;;;;51230:30;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;51230:30:0;;;51220:41;;;;;;51205:9;51215:1;51205:12;;;;;;;;;;;;;:56;;;;;51287:9;51297:1;51287:12;;;;;;;;;;;;;;51279:21;;51272:28;;51049:259;;;:::o;52032:333::-;52211:13;;52264:2;52252:15;;;52246:22;52116:4;;52211:13;52296:10;;;;;:31;;;52325:2;52318:4;:9;52310:4;:17;;52296:31;:61;;;;;52355:2;52348:4;:9;52338:6;52331:4;:13;:26;;52289:68;52032:333;-1:-1:-1;;;;;52032:333:0:o;33893:175::-;33993:1;33957:24;;;:15;:24;;;;;;-1:-1:-1;;;;;33957:24:0;:38;33953:108;;34047:1;34012:24;;;:15;:24;;;;;:37;;-1:-1:-1;;;;;;34012:37:0;;;33893:175::o;17241:110::-;17322:14;;:21;;17341:1;17322:21;:18;:21;:::i;:::-;17305:38;;17241:110::o;17142:91::-;17206:19;;17224:1;17206:19;;;17142:91::o;8794:136::-;8852:7;8879:43;8883:1;8886;8879:43;;;;;;;;;;;;;;;;;:3;:43::i;48994:671::-;49089:16;49138:11;49133:1;49120:12;:14;:29;;:61;;;;;49168:13;49153:11;:28;;49120:61;49112:113;;;;-1:-1:-1;;;49112:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49230:21;49280:13;49268:11;:25;49294:1;49268:27;49254:42;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;49254:42:0;-1:-1:-1;49326:35:0;;;49343:12;49326:35;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;49326:35:0;;;;;;;49316:46;;;;;49230:66;;-1:-1:-1;49301:12:0;49367:278;49399:13;49387:11;:25;49384:1;:28;49367:278;;49630:1;49616:13;:15;49606:26;49633:4;49589:49;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;49589::0;;;49579:60;;;;;;49567:4;49572:1;49574;49572:3;49567:9;;;;;;;;;;;;;;;;;:72;49414:3;;49367:278;;;-1:-1:-1;49656:4:0;;48994:671;-1:-1:-1;;;;;48994:671:0:o;49977:369::-;50037:7;50073:1;50059:4;:11;:15;50051:57;;;;;-1:-1:-1;;;50051:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50113:21;50169:1;50157:4;:11;:13;50145:4;50150:1;50145:7;;;;;;;;;;;;;;50137:16;;:34;;;;;;50174:1;50137:38;50113:62;;50180:12;50222:4;50227:13;50222:19;;;;;;;;;;;;;;50205:37;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;50205:37:0;;;50195:48;;;;;;50180:63;;50274:4;50279:1;50274:7;;;;;;;;;;;;;;50266:16;;50283:1;50266:18;50258:27;;50248:4;50253:1;50248:7;;;;;;;;;;;;;:37;;;;;50312:4;50290;50295:13;50290:19;;;;;;;;;;;;;;;;;:26;50336:4;49977:369;-1:-1:-1;;;49977:369:0:o;13482:810::-;13542:4;14201:20;;14044:66;14241:15;;;;;:42;;-1:-1:-1;14260:23:0;;;14233:51;-1:-1:-1;;13482:810:0:o;9267:192::-;9353:7;9389:12;9381:6;;;;9373:29;;;;-1:-1:-1;;;9373:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;9373:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9425:5:0;;;9267:192::o;56329:17071::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56329:17071:0;;;-1:-1:-1;56329:17071:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://090c926cad1236c8fa50d210a85f7af1a80ccc93ea9fab64443e7095fc378e08
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.