ETH Price: $2,363.49 (+0.99%)

Token

Flames by Fabled Fractals | Official Collection (FLAME)
 

Overview

Max Total Supply

77 FLAME

Holders

33

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
jibjab.eth
Balance
3 FLAME
0x09306cFea01e396F89De0Ee00474657b4C86D55b
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
FabledFractals

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-02-19
*/

// SPDX-License-Identifier: MIT
/*
███████╗ █████╗ ██████╗ ██╗     ███████╗██████╗     ███████╗██████╗  █████╗  ██████╗████████╗ █████╗ ██╗     ███████╗
██╔════╝██╔══██╗██╔══██╗██║     ██╔════╝██╔══██╗    ██╔════╝██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██║     ██╔════╝
█████╗  ███████║██████╔╝██║     █████╗  ██║  ██║    █████╗  ██████╔╝███████║██║        ██║   ███████║██║     ███████╗
██╔══╝  ██╔══██║██╔══██╗██║     ██╔══╝  ██║  ██║    ██╔══╝  ██╔══██╗██╔══██║██║        ██║   ██╔══██║██║     ╚════██║
██║     ██║  ██║██████╔╝███████╗███████╗██████╔╝    ██║     ██║  ██║██║  ██║╚██████╗   ██║   ██║  ██║███████╗███████║
╚═╝     ╚═╝  ╚═╝╚═════╝ ╚══════╝╚══════╝╚═════╝     ╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝   ╚═╝   ╚═╝  ╚═╝╚══════╝╚══════╝

v1.9.1
*/
pragma solidity ^0.8.0;

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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


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

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

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


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

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

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}


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

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

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

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

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

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


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

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


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

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

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

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

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

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

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

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

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

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

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

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

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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


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

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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


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


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => 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;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @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 {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @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 whites 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 = ERC721.balanceOf(from) - 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
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @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 - 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
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


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


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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


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

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

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

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

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

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

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}



contract FabledFractals is ERC721("Flames by Fabled Fractals | Official Collection", "FLAME"), ERC721Enumerable, Ownable {
    using SafeMath for uint256;
    using Strings for uint256;

    uint256 private cur_phase = 0;
    uint256 public constant MAX_SUPPLY = 10000;
    uint256 public constant MAX_GIVEAWAY = 100;
    uint256 public constant AIRDROP_MAX_SUPPLY = 5000;
    uint256 public constant SALE_SUPPLY = 5000;
    uint256 public constant WHITELIST_PURCHASE_LIMIT = 4;
    uint256 public constant SALE_PURCHASE_LIMIT = 10;
    uint256 public constant DEVELOPER_FRACTALS_EACH = 6;
    uint256 public constant BASE_PRICE = 100000000000000000; // 0.1 ETH

    address public constant DEV1_ADDRESS = 0xDa17AA88e60CEf4007Cf10aA94191EcF15bA26f3;
    address public constant DEV2_ADDRESS = 0x6e306a7d34860B0D45346a870f6110483fc5F280;
    address public constant DEV3_ADDRESS = 0x03D5a39CD7517bc568aA8B23C4302fA4c67DC204;

    string public constant BASE_URI = "https://storage.googleapis.com/flames/metadata/";

    //
    // https://ethereum.stackexchange.com/questions/55474/verification-of-externally-created-ecdsa-signatures-in-solidity
    //

    function recover(bytes32 hash, bytes memory sig)
        internal
        pure
        returns (address)
    {
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Check the signature length
        if (sig.length != 65) {
            return (address(0));
        }

        // Divide the signature in r, s and v variables
        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            r := mload(add(sig, 32))
            s := mload(add(sig, 64))
            v := byte(0, mload(add(sig, 96)))
        }

        // Version of signature should be 27 or 28, but 0 and 1 are also possible versions
        if (v < 27) {
            v += 27;
        }

        // If the version is correct return the signer address
        if (v != 27 && v != 28) {
            return (address(0));
        } else {
            // solium-disable-next-line arg-overflow
            return ecrecover(hash, v, r, s);
        }
    }

    function verifySignature(bytes memory sig) public view returns (bool) {
        bytes32 message = getAddressHash();
        address addr = 0x9EB0F5610D94141c051E19A110FB725cc2493766; // public key
        return recover(message, sig) == addr;
    }

    function getAddressHash() public view returns (bytes32) {
        return keccak256(abi.encodePacked(msg.sender));
    }

    function getAddress() public view returns (address) {
        return msg.sender;
    }

    address[] private whitelist_addresses;
    mapping(address => uint256) private whitelist_limits;

    uint256 private TOTAL_GIVEAWAY = 0;
    bool private DEV_FRACTALS_MINTED = false;
    address[] private giveaway_addresses;
    mapping(address => uint256) private giveaway_limits;

    address[] private airdrop_addresses;
    mapping(address => uint256) private airdrop_limits;

    //
    // Helpers
    //

    // helper to check if value is in a list, O(n)
    function addrInArray(address a, address[] memory list) 
        internal
        pure
        returns (bool)
    {
        for (uint i=0; i < list.length; i++) {
            if (a == list[i]) {
                return true;
            }
        }
        return false;
    }

    // Step phase of the contract minting to ensure that there is no funny business from the developers
    // Cant go back in phases! 
    function stepPhase()        
        external 
        onlyOwner 
    {
        require(cur_phase <= 3, "No phase beyond phase 3");
        cur_phase += 1;        
    }

    // Get the current phase
    function getPhase() 
        view
        external
        returns (uint256)
    {
        return cur_phase;
    }

    function getGiveawayCount() 
        view
        external
        returns (uint256)
    {
        if (addrInArray(msg.sender, giveaway_addresses)) {
            return giveaway_limits[msg.sender];
        } else {
            return 0;
        }
    }

    function getRemainingPresaleCount() 
        view
        external
        returns (uint256)
    {
        // naive logic, if sender not in current WL minters, they have all left
        if (addrInArray(msg.sender, whitelist_addresses)) {
            return whitelist_limits[msg.sender];
        } else {
            return WHITELIST_PURCHASE_LIMIT;
        }
    }


    // Function to withdraw collected amount during minting by the owners
    function withdraw() 
        public 
        onlyOwner 
    {
        uint balance = address(this).balance;
        require(balance > 0, "Balance should be more then zero");
        payable(DEV1_ADDRESS).transfer(balance * 2 / 5);
        payable(DEV2_ADDRESS).transfer(balance * 2 / 5);
        payable(DEV3_ADDRESS).transfer(balance * 1 / 5);
    }

    // Function to get token URI of given token ID
    function tokenURI(uint256 _tokenId)
        public 
        view 
        virtual 
        override 
        returns (string memory) 
    {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");
        return string(abi.encodePacked(BASE_URI, _tokenId.toString(), ".json"));
    }

    //
    // PHASE 0 METHODS
    //

    // set giveaway information 
    function setGiveaway(address[] calldata addresses, uint256[] calldata counts)        
        external 
        onlyOwner 
    {
        require(cur_phase == 0 || cur_phase == 1 || cur_phase == 2, "Giveaways can't be set in airdrop phase");
        require(addresses.length == counts.length, "Ensure input arrays are equal in size");

        uint256 total_giveaway = TOTAL_GIVEAWAY;

        for (uint i = 0; i < counts.length; i++) {
            total_giveaway += counts[i];
        }

        require(total_giveaway <= MAX_GIVEAWAY, "Transaction exceeds contract giveaway limits");

        for (uint i = 0; i < addresses.length; i++) {
            if (addrInArray(addresses[i], giveaway_addresses) == true) {
                giveaway_limits[addresses[i]] += counts[i];
            } else {
                giveaway_addresses.push(addresses[i]);
                giveaway_limits[addresses[i]] = counts[i];
            }
        }

        TOTAL_GIVEAWAY = total_giveaway;
    }

    function mintDevFractals() 
        external
        onlyOwner
    {
        require(cur_phase == 0, 'Can only mint dev fractals in presale');
        require(DEV_FRACTALS_MINTED == false, 'Dev fractals already minted');
        // mint dev allocation of fractals (18)
        for (uint i = 0; i < DEVELOPER_FRACTALS_EACH; i++) {
            _safeMint(DEV1_ADDRESS, totalSupply());
            _safeMint(DEV2_ADDRESS, totalSupply());
            _safeMint(DEV3_ADDRESS, totalSupply());
        }

        airdrop_addresses.push(DEV1_ADDRESS);
        airdrop_limits[msg.sender] = DEVELOPER_FRACTALS_EACH;

        airdrop_addresses.push(DEV2_ADDRESS);
        airdrop_limits[msg.sender] = DEVELOPER_FRACTALS_EACH;

        airdrop_addresses.push(DEV3_ADDRESS);
        airdrop_limits[msg.sender] = DEVELOPER_FRACTALS_EACH;

        DEV_FRACTALS_MINTED = true;
    }

    //
    // PHASE 1 METHODS
    //

    /*
     * Function to mint new NFTs during the presale
     * It is payable. Amount is calculated as per (NFTPrice.mul(_numOfTokens))
    */
    function presaleMintNFT(uint256 _numOfTokens, bytes memory sig)
        public
        payable
    {
        require(cur_phase == 1, 'Can only mint in presale');
        require(verifySignature(sig) == true, "You are not a member of the presale");

        // check if address in whitelist limits, if not add it and continue checks
        if (addrInArray(msg.sender, whitelist_addresses) == false) {
            whitelist_addresses.push(msg.sender);
            whitelist_limits[msg.sender] = WHITELIST_PURCHASE_LIMIT;
        }

        require(whitelist_limits[msg.sender] >= _numOfTokens, "Purchase exceeds your presale allocation");
        require(totalSupply().add(_numOfTokens) <= SALE_SUPPLY, "Purchase would exceed max public supply");
        require(BASE_PRICE.mul(_numOfTokens) == msg.value, "Ether value sent is not correct");

        // mint nfts
        for(uint i = 0; i < _numOfTokens; i++) {
            _safeMint(msg.sender, totalSupply());
            whitelist_limits[msg.sender] -= 1;
        }

        // add to tracker for airdrop
        if (addrInArray(msg.sender, airdrop_addresses) == true) {
            airdrop_limits[msg.sender] += _numOfTokens;
        } else {
            airdrop_addresses.push(msg.sender);
            airdrop_limits[msg.sender] = _numOfTokens;
        }
    }


    function giveawayMintNFT(uint256 _numOfTokens)
        public
        payable
    {
        require(cur_phase == 1 || cur_phase == 2, 'Can only mint giveaways in presale and sale');
        require(addrInArray(msg.sender, giveaway_addresses) == true, "You are not a member of the giveaway");
        require(giveaway_limits[msg.sender] >= _numOfTokens, "Purchase exceeds your giveaway allocation");
        require(totalSupply().add(_numOfTokens) <= SALE_SUPPLY, "Purchase would exceed max public supply");
        require(msg.value == 0, "Ether value should be 0");

        // mint nfts
        for(uint i = 0; i < _numOfTokens; i++) {
            _safeMint(msg.sender, totalSupply());
            giveaway_limits[msg.sender] -= 1;
        }

        // add to tracker for airdrop
        if (cur_phase != 3) {
            if (addrInArray(msg.sender, airdrop_addresses) == true) {
                airdrop_limits[msg.sender] += _numOfTokens;
            } else {
                airdrop_addresses.push(msg.sender);
                airdrop_limits[msg.sender] = _numOfTokens;
            }
        }
    }


    //
    // PHASE 2
    //

    function mintNFT(uint256 _numOfTokens)
        public
        payable
    {
        require(cur_phase == 2, 'Can only mint during sale');
        require(_numOfTokens <= SALE_PURCHASE_LIMIT, "Request amount of NFTs exceeds single transaction limit");
        require(totalSupply().add(_numOfTokens) <= SALE_SUPPLY, "Purchase would exceed max public supply");
        require(BASE_PRICE.mul(_numOfTokens) == msg.value, "Ether value sent is not correct");

        // mint nfts
        for(uint i = 0; i < _numOfTokens; i++) {
            _safeMint(msg.sender, totalSupply());
        }

        // add to tracker for airdrop
        if (cur_phase != 3) {
            if (addrInArray(msg.sender, airdrop_addresses) == true) {
                airdrop_limits[msg.sender] += _numOfTokens;
            } else {
                airdrop_addresses.push(msg.sender);
                airdrop_limits[msg.sender] = _numOfTokens;
            }
        }
    }

    //
    // PHASE 3
    //


    function airdropNFT(uint256 _numOfTokens)
        public
        payable
    {
        require(cur_phase == 3, 'Can only mint airdrops after drop');
        require(addrInArray(msg.sender, airdrop_addresses) == true, "You are not a member of the airdrop");
        require(airdrop_limits[msg.sender] >= _numOfTokens, "Purchase exceeds your airdrop allocation");
        require(totalSupply().add(_numOfTokens) <= MAX_SUPPLY, "Purchase would exceed max supply");
        require(msg.value == 0, "Ether value should be 0");

        // mint nfts
        for(uint i = 0; i < _numOfTokens; i++) {
            _safeMint(msg.sender, totalSupply());
            airdrop_limits[msg.sender] -= 1;
        }
    }

  
    // Standard functions to be overridden in ERC721Enumerable
    function supportsInterface(bytes4 _interfaceId) 
        public
        view 
        override (ERC721, ERC721Enumerable) 
        returns (bool) 
    {
        return super.supportsInterface(_interfaceId);
    }

   
    function _beforeTokenTransfer(address _from, address _to, uint256 _tokenId) 
        internal 
        override(ERC721, ERC721Enumerable) 
    {
        super._beforeTokenTransfer(_from, _to, _tokenId);
    }

}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"AIRDROP_MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_URI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV1_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV2_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV3_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEVELOPER_FRACTALS_EACH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GIVEAWAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_PURCHASE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_PURCHASE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numOfTokens","type":"uint256"}],"name":"airdropNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAddressHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGiveawayCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPhase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRemainingPresaleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numOfTokens","type":"uint256"}],"name":"giveawayMintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintDevFractals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numOfTokens","type":"uint256"}],"name":"mintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numOfTokens","type":"uint256"},{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"presaleMintNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"name":"setGiveaway","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stepPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"sig","type":"bytes"}],"name":"verifySignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600b819055600e55600f805460ff191690553480156200002557600080fd5b506040518060600160405280602f815260200162003824602f913960405180604001604052806005815260200164464c414d4560d81b81525081600090805190602001906200007692919062000105565b5080516200008c90600190602084019062000105565b505050620000a9620000a3620000af60201b60201c565b620000b3565b620001e8565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200011390620001ab565b90600052602060002090601f01602090048101928262000137576000855562000182565b82601f106200015257805160ff191683800117855562000182565b8280016001018555821562000182579182015b828111156200018257825182559160200191906001019062000165565b506200019092915062000194565b5090565b5b8082111562000190576000815560010162000195565b600181811c90821680620001c057607f821691505b60208210811415620001e257634e487b7160e01b600052602260045260246000fd5b50919050565b61362c80620001f86000396000f3fe6080604052600436106102725760003560e01c80638da5cb5b1161014f578063be837ea8116100c1578063e985e9c51161007a578063e985e9c514610691578063eced0280146106da578063f2fde38b146106ef578063f80af9841461070f578063f86325ed1461072f578063fadce9e91461074b57600080fd5b8063be837ea81461060a578063c87b56dd1461061f578063c9ed3fdb1461063f578063cbf6fff91461054b578063d47845e414610654578063dbddb26a1461067c57600080fd5b806395d89b411161011357806395d89b4114610576578063a22cb4651461058b578063b527c36d146105ab578063b75421a7146105c0578063b88d4fde146105d5578063bb029ba5146105f557600080fd5b80638da5cb5b146105075780638fc58f231461052557806392642744146105385780639358cdb31461054b578063937a00751461056157600080fd5b806338cc4831116101e85780634d3740a0116101ac5780634d3740a01461046a5780634f6ccce71461047f578063589c024d1461049f5780636352211e146104b257806370a08231146104d2578063715018a6146104f257600080fd5b806338cc4831146103f85780633bda89061461040b5780633ccfd60b1461042057806342842e0e146104355780634c5b7a291461045557600080fd5b8063165def1c1161023a578063165def1c14610348578063173bcf961461035b57806318160ddd1461038357806323b872dd146103a25780632f745c59146103c257806332cb6b0c146103e257600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063095ea7b314610306578063109a988d14610328575b600080fd5b34801561028357600080fd5b50610297610292366004612eda565b610773565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610784565b6040516102a39190612f4f565b3480156102da57600080fd5b506102ee6102e9366004612f62565b610816565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b50610326610321366004612f97565b6108b0565b005b34801561033457600080fd5b5061032661034336600461300d565b6109c6565b61032661035636600461311c565b610d67565b34801561036757600080fd5b506102ee73da17aa88e60cef4007cf10aa94191ecf15ba26f381565b34801561038f57600080fd5b506008545b6040519081526020016102a3565b3480156103ae57600080fd5b506103266103bd366004613163565b61111e565b3480156103ce57600080fd5b506103946103dd366004612f97565b61114f565b3480156103ee57600080fd5b5061039461271081565b34801561040457600080fd5b50336102ee565b34801561041757600080fd5b506103946111e5565b34801561042c57600080fd5b50610326611221565b34801561044157600080fd5b50610326610450366004613163565b6113a0565b34801561046157600080fd5b50610394606481565b34801561047657600080fd5b506103946113bb565b34801561048b57600080fd5b5061039461049a366004612f62565b61143e565b6103266104ad366004612f62565b6114d1565b3480156104be57600080fd5b506102ee6104cd366004612f62565b611830565b3480156104de57600080fd5b506103946104ed36600461319f565b6118a7565b3480156104fe57600080fd5b5061032661192e565b34801561051357600080fd5b50600a546001600160a01b03166102ee565b610326610533366004612f62565b611964565b610326610546366004612f62565b611be5565b34801561055757600080fd5b5061039461138881565b34801561056d57600080fd5b50610394600481565b34801561058257600080fd5b506102c1611d66565b34801561059757600080fd5b506103266105a63660046131ba565b611d75565b3480156105b757600080fd5b50610394611e3a565b3480156105cc57600080fd5b50610326611ebd565b3480156105e157600080fd5b506103266105f03660046131f6565b611f54565b34801561060157600080fd5b50610326611f8c565b34801561061657600080fd5b50610394600a81565b34801561062b57600080fd5b506102c161063a366004612f62565b6121b9565b34801561064b57600080fd5b50610394600681565b34801561066057600080fd5b506102ee736e306a7d34860b0d45346a870f6110483fc5f28081565b34801561068857600080fd5b506102c1612281565b34801561069d57600080fd5b506102976106ac36600461325e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106e657600080fd5b50600b54610394565b3480156106fb57600080fd5b5061032661070a36600461319f565b61229d565b34801561071b57600080fd5b5061029761072a366004613291565b612335565b34801561073b57600080fd5b5061039467016345785d8a000081565b34801561075757600080fd5b506102ee7303d5a39cd7517bc568aa8b23c4302fa4c67dc20481565b600061077e82612374565b92915050565b606060008054610793906132c6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bf906132c6565b801561080c5780601f106107e15761010080835404028352916020019161080c565b820191906000526020600020905b8154815290600101906020018083116107ef57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108945760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108bb82611830565b9050806001600160a01b0316836001600160a01b031614156109295760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161088b565b336001600160a01b0382161480610945575061094581336106ac565b6109b75760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161088b565b6109c18383612399565b505050565b600a546001600160a01b031633146109f05760405162461bcd60e51b815260040161088b90613301565b600b541580610a015750600b546001145b80610a0e5750600b546002145b610a6a5760405162461bcd60e51b815260206004820152602760248201527f4769766561776179732063616e27742062652073657420696e2061697264726f6044820152667020706861736560c81b606482015260840161088b565b828114610ac75760405162461bcd60e51b815260206004820152602560248201527f456e7375726520696e707574206172726179732061726520657175616c20696e6044820152642073697a6560d81b606482015260840161088b565b600e5460005b82811015610b0d57838382818110610ae757610ae7613336565b9050602002013582610af99190613362565b915080610b058161337a565b915050610acd565b506064811115610b745760405162461bcd60e51b815260206004820152602c60248201527f5472616e73616374696f6e206578636565647320636f6e74726163742067697660448201526b6561776179206c696d69747360a01b606482015260840161088b565b60005b84811015610d5d57610c09868683818110610b9457610b94613336565b9050602002016020810190610ba9919061319f565b6010805480602002602001604051908101604052809291908181526020018280548015610bff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610be1575b5050505050612407565b151560011415610c9157838382818110610c2557610c25613336565b9050602002013560116000888885818110610c4257610c42613336565b9050602002016020810190610c57919061319f565b6001600160a01b03166001600160a01b031681526020019081526020016000206000828254610c869190613362565b90915550610d4b9050565b6010868683818110610ca557610ca5613336565b9050602002016020810190610cba919061319f565b81546001810183556000928352602090922090910180546001600160a01b0319166001600160a01b03909216919091179055838382818110610cfe57610cfe613336565b9050602002013560116000888885818110610d1b57610d1b613336565b9050602002016020810190610d30919061319f565b6001600160a01b031681526020810191909152604001600020555b80610d558161337a565b915050610b77565b50600e5550505050565b600b54600114610db95760405162461bcd60e51b815260206004820152601860248201527f43616e206f6e6c79206d696e7420696e2070726573616c650000000000000000604482015260640161088b565b610dc281612335565b1515600114610e1f5760405162461bcd60e51b815260206004820152602360248201527f596f7520617265206e6f742061206d656d626572206f66207468652070726573604482015262616c6560e81b606482015260840161088b565b610e8133600c805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b610ed857600c8054600181019091557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b031916339081179091556000908152600d60205260409020600490555b336000908152600d6020526040902054821115610f485760405162461bcd60e51b815260206004820152602860248201527f5075726368617365206578636565647320796f75722070726573616c6520616c6044820152673637b1b0ba34b7b760c11b606482015260840161088b565b611388610f5e83610f5860085490565b9061246d565b1115610f7c5760405162461bcd60e51b815260040161088b90613395565b34610f8f67016345785d8a000084612480565b14610fdc5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604482015260640161088b565b60005b8281101561103157610ff933610ff460085490565b61248c565b336000908152600d602052604081208054600192906110199084906133dc565b909155508190506110298161337a565b915050610fdf565b50611094336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114156110c85733600090815260136020526040812080548492906110bd908490613362565b9091555061111a9050565b60128054600181019091557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319163390811790915560009081526013602052604090208290555b5050565b61112833826124a6565b6111445760405162461bcd60e51b815260040161088b906133f3565b6109c183838361259d565b600061115a836118a7565b82106111bc5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161088b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6040516bffffffffffffffffffffffff193360601b16602082015260009060340160405160208183030381529060405280519060200120905090565b600a546001600160a01b0316331461124b5760405162461bcd60e51b815260040161088b90613301565b47806112995760405162461bcd60e51b815260206004820181905260248201527f42616c616e63652073686f756c64206265206d6f7265207468656e207a65726f604482015260640161088b565b73da17aa88e60cef4007cf10aa94191ecf15ba26f36108fc60056112be846002613444565b6112c89190613479565b6040518115909202916000818181858888f193505050501580156112f0573d6000803e3d6000fd5b50736e306a7d34860b0d45346a870f6110483fc5f2806108fc6005611316846002613444565b6113209190613479565b6040518115909202916000818181858888f19350505050158015611348573d6000803e3d6000fd5b507303d5a39cd7517bc568aa8b23c4302fa4c67dc2046108fc600561136e846001613444565b6113789190613479565b6040518115909202916000818181858888f1935050505015801561111a573d6000803e3d6000fd5b6109c183838360405180602001604052806000815250611f54565b600061141f336010805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1561143857503360009081526011602052604090205490565b50600090565b600061144960085490565b82106114ac5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161088b565b600882815481106114bf576114bf613336565b90600052602060002001549050919050565b600b54600114806114e45750600b546002145b6115445760405162461bcd60e51b815260206004820152602b60248201527f43616e206f6e6c79206d696e742067697665617761797320696e20707265736160448201526a6c6520616e642073616c6560a81b606482015260840161088b565b6115a6336010805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b15156001146116035760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f742061206d656d626572206f662074686520676976656044820152636177617960e01b606482015260840161088b565b336000908152601160205260409020548111156116745760405162461bcd60e51b815260206004820152602960248201527f5075726368617365206578636565647320796f75722067697665617761792061604482015268363637b1b0ba34b7b760b91b606482015260840161088b565b61138861168482610f5860085490565b11156116a25760405162461bcd60e51b815260040161088b90613395565b34156116ea5760405162461bcd60e51b8152602060048201526017602482015276045746865722076616c75652073686f756c64206265203604c1b604482015260640161088b565b60005b8181101561173a5761170233610ff460085490565b3360009081526011602052604081208054600192906117229084906133dc565b909155508190506117328161337a565b9150506116ed565b50600b5460031461182d576117a7336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114156117db5733600090815260136020526040812080548392906117d0908490613362565b9091555061182d9050565b60128054600181019091557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319163390811790915560009081526013602052604090208190555b50565b6000818152600260205260408120546001600160a01b03168061077e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161088b565b60006001600160a01b0382166119125760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161088b565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146119585760405162461bcd60e51b815260040161088b90613301565b6119626000612748565b565b600b546003146119c05760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e742061697264726f70732061667465722064726f6044820152600760fc1b606482015260840161088b565b611a22336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114611a7f5760405162461bcd60e51b815260206004820152602360248201527f596f7520617265206e6f742061206d656d626572206f662074686520616972646044820152620726f760ec1b606482015260840161088b565b33600090815260136020526040902054811115611aef5760405162461bcd60e51b815260206004820152602860248201527f5075726368617365206578636565647320796f75722061697264726f7020616c6044820152673637b1b0ba34b7b760c11b606482015260840161088b565b612710611aff82610f5860085490565b1115611b4d5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015260640161088b565b3415611b955760405162461bcd60e51b8152602060048201526017602482015276045746865722076616c75652073686f756c64206265203604c1b604482015260640161088b565b60005b8181101561111a57611bad33610ff460085490565b336000908152601360205260408120805460019290611bcd9084906133dc565b90915550819050611bdd8161337a565b915050611b98565b600b54600214611c375760405162461bcd60e51b815260206004820152601960248201527f43616e206f6e6c79206d696e7420647572696e672073616c6500000000000000604482015260640161088b565b600a811115611cae5760405162461bcd60e51b815260206004820152603760248201527f5265717565737420616d6f756e74206f66204e4654732065786365656473207360448201527f696e676c65207472616e73616374696f6e206c696d6974000000000000000000606482015260840161088b565b611388611cbe82610f5860085490565b1115611cdc5760405162461bcd60e51b815260040161088b90613395565b34611cef67016345785d8a000083612480565b14611d3c5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604482015260640161088b565b60005b8181101561173a57611d5433610ff460085490565b80611d5e8161337a565b915050611d3f565b606060018054610793906132c6565b6001600160a01b038216331415611dce5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161088b565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611e9e33600c805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b15611eb75750336000908152600d602052604090205490565b50600490565b600a546001600160a01b03163314611ee75760405162461bcd60e51b815260040161088b90613301565b6003600b541115611f3a5760405162461bcd60e51b815260206004820152601760248201527f4e6f207068617365206265796f6e642070686173652033000000000000000000604482015260640161088b565b6001600b6000828254611f4d9190613362565b9091555050565b611f5e33836124a6565b611f7a5760405162461bcd60e51b815260040161088b906133f3565b611f868484848461279a565b50505050565b600a546001600160a01b03163314611fb65760405162461bcd60e51b815260040161088b90613301565b600b54156120145760405162461bcd60e51b815260206004820152602560248201527f43616e206f6e6c79206d696e7420646576206672616374616c7320696e2070726044820152646573616c6560d81b606482015260840161088b565b600f5460ff16156120675760405162461bcd60e51b815260206004820152601b60248201527f446576206672616374616c7320616c7265616479206d696e7465640000000000604482015260640161088b565b60005b60068110156120e85761209473da17aa88e60cef4007cf10aa94191ecf15ba26f3610ff460085490565b6120b5736e306a7d34860b0d45346a870f6110483fc5f280610ff460085490565b6120d67303d5a39cd7517bc568aa8b23c4302fa4c67dc204610ff460085490565b806120e08161337a565b91505061206a565b5060128054600181810183557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344491820180546001600160a01b031990811673da17aa88e60cef4007cf10aa94191ecf15ba26f317909155336000818152601360205260408120600680825587548087018955870180548616736e306a7d34860b0d45346a870f6110483fc5f28017905580825587548087019098559690950180549093167303d5a39cd7517bc568aa8b23c4302fa4c67dc204179092559052919055600f805460ff19169091179055565b6000818152600260205260409020546060906001600160a01b03166122385760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161088b565b6040518060600160405280602f81526020016135c8602f913961225a836127cd565b60405160200161226b92919061348d565b6040516020818303038152906040529050919050565b6040518060600160405280602f81526020016135c8602f913981565b600a546001600160a01b031633146122c75760405162461bcd60e51b815260040161088b90613301565b6001600160a01b03811661232c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161088b565b61182d81612748565b6000806123406111e5565b9050739eb0f5610d94141c051e19a110fb725cc24937668061236283866128cb565b6001600160a01b031614949350505050565b60006001600160e01b0319821663780e9d6360e01b148061077e575061077e826129a2565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906123ce82611830565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000805b82518110156124635782818151811061242657612426613336565b60200260200101516001600160a01b0316846001600160a01b0316141561245157600191505061077e565b8061245b8161337a565b91505061240b565b5060009392505050565b60006124798284613362565b9392505050565b60006124798284613444565b61111a8282604051806020016040528060008152506129f2565b6000818152600260205260408120546001600160a01b031661251f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161088b565b600061252a83611830565b9050806001600160a01b0316846001600160a01b031614806125655750836001600160a01b031661255a84610816565b6001600160a01b0316145b8061259557506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166125b082611830565b6001600160a01b0316146126185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161088b565b6001600160a01b03821661267a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161088b565b612685838383612a25565b612690600082612399565b6001600160a01b03831660009081526003602052604081208054600192906126b99084906133dc565b90915550506001600160a01b03821660009081526003602052604081208054600192906126e7908490613362565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127a584848461259d565b6127b184848484612a30565b611f865760405162461bcd60e51b815260040161088b906134cc565b6060816127f15750506040805180820190915260018152600360fc1b602082015290565b8160005b811561281b57806128058161337a565b91506128149050600a83613479565b91506127f5565b60008167ffffffffffffffff81111561283657612836613079565b6040519080825280601f01601f191660200182016040528015612860576020820181803683370190505b5090505b8415612595576128756001836133dc565b9150612882600a8661351e565b61288d906030613362565b60f81b8183815181106128a2576128a2613336565b60200101906001600160f81b031916908160001a9053506128c4600a86613479565b9450612864565b60008060008084516041146128e6576000935050505061077e565b50505060208201516040830151606084015160001a601b8110156129125761290f601b82613532565b90505b8060ff16601b1415801561292a57508060ff16601c14155b1561293b576000935050505061077e565b60408051600081526020810180835288905260ff831691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561298e573d6000803e3d6000fd5b50505060206040510351935050505061077e565b60006001600160e01b031982166380ac58cd60e01b14806129d357506001600160e01b03198216635b5e139f60e01b145b8061077e57506301ffc9a760e01b6001600160e01b031983161461077e565b6129fc8383612b2e565b612a096000848484612a30565b6109c15760405162461bcd60e51b815260040161088b906134cc565b6109c1838383612c7c565b60006001600160a01b0384163b15612b2357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a74903390899088908890600401613557565b6020604051808303816000875af1925050508015612aaf575060408051601f3d908101601f19168201909252612aac91810190613594565b60015b612b09573d808015612add576040519150601f19603f3d011682016040523d82523d6000602084013e612ae2565b606091505b508051612b015760405162461bcd60e51b815260040161088b906134cc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612595565b506001949350505050565b6001600160a01b038216612b845760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161088b565b6000818152600260205260409020546001600160a01b031615612be95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161088b565b612bf560008383612a25565b6001600160a01b0382166000908152600360205260408120805460019290612c1e908490613362565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316612cd757612cd281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612cfa565b816001600160a01b0316836001600160a01b031614612cfa57612cfa8382612d34565b6001600160a01b038216612d11576109c181612dd1565b826001600160a01b0316826001600160a01b0316146109c1576109c18282612e80565b60006001612d41846118a7565b612d4b91906133dc565b600083815260076020526040902054909150808214612d9e576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612de3906001906133dc565b60008381526009602052604081205460088054939450909284908110612e0b57612e0b613336565b906000526020600020015490508060088381548110612e2c57612e2c613336565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612e6457612e646135b1565b6001900381819060005260206000200160009055905550505050565b6000612e8b836118a7565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b03198116811461182d57600080fd5b600060208284031215612eec57600080fd5b813561247981612ec4565b60005b83811015612f12578181015183820152602001612efa565b83811115611f865750506000910152565b60008151808452612f3b816020860160208601612ef7565b601f01601f19169290920160200192915050565b6020815260006124796020830184612f23565b600060208284031215612f7457600080fd5b5035919050565b80356001600160a01b0381168114612f9257600080fd5b919050565b60008060408385031215612faa57600080fd5b612fb383612f7b565b946020939093013593505050565b60008083601f840112612fd357600080fd5b50813567ffffffffffffffff811115612feb57600080fd5b6020830191508360208260051b850101111561300657600080fd5b9250929050565b6000806000806040858703121561302357600080fd5b843567ffffffffffffffff8082111561303b57600080fd5b61304788838901612fc1565b9096509450602087013591508082111561306057600080fd5b5061306d87828801612fc1565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126130a057600080fd5b813567ffffffffffffffff808211156130bb576130bb613079565b604051601f8301601f19908116603f011681019082821181831017156130e3576130e3613079565b816040528381528660208588010111156130fc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561312f57600080fd5b82359150602083013567ffffffffffffffff81111561314d57600080fd5b6131598582860161308f565b9150509250929050565b60008060006060848603121561317857600080fd5b61318184612f7b565b925061318f60208501612f7b565b9150604084013590509250925092565b6000602082840312156131b157600080fd5b61247982612f7b565b600080604083850312156131cd57600080fd5b6131d683612f7b565b9150602083013580151581146131eb57600080fd5b809150509250929050565b6000806000806080858703121561320c57600080fd5b61321585612f7b565b935061322360208601612f7b565b925060408501359150606085013567ffffffffffffffff81111561324657600080fd5b6132528782880161308f565b91505092959194509250565b6000806040838503121561327157600080fd5b61327a83612f7b565b915061328860208401612f7b565b90509250929050565b6000602082840312156132a357600080fd5b813567ffffffffffffffff8111156132ba57600080fd5b6125958482850161308f565b600181811c908216806132da57607f821691505b602082108114156132fb57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156133755761337561334c565b500190565b600060001982141561338e5761338e61334c565b5060010190565b60208082526027908201527f507572636861736520776f756c6420657863656564206d6178207075626c696360408201526620737570706c7960c81b606082015260800190565b6000828210156133ee576133ee61334c565b500390565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600081600019048311821515161561345e5761345e61334c565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261348857613488613463565b500490565b6000835161349f818460208801612ef7565b8351908301906134b3818360208801612ef7565b64173539b7b760d91b9101908152600501949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008261352d5761352d613463565b500690565b600060ff821660ff84168060ff0382111561354f5761354f61334c565b019392505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061358a90830184612f23565b9695505050505050565b6000602082840312156135a657600080fd5b815161247981612ec4565b634e487b7160e01b600052603160045260246000fdfe68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f666c616d65732f6d657461646174612fa26469706673582212205e22f36fbc705b16c3708f48ea2a2706e60c87887ee3d972255b887b189d499764736f6c634300080b0033466c616d6573206279204661626c6564204672616374616c73207c204f6666696369616c20436f6c6c656374696f6e

Deployed Bytecode

0x6080604052600436106102725760003560e01c80638da5cb5b1161014f578063be837ea8116100c1578063e985e9c51161007a578063e985e9c514610691578063eced0280146106da578063f2fde38b146106ef578063f80af9841461070f578063f86325ed1461072f578063fadce9e91461074b57600080fd5b8063be837ea81461060a578063c87b56dd1461061f578063c9ed3fdb1461063f578063cbf6fff91461054b578063d47845e414610654578063dbddb26a1461067c57600080fd5b806395d89b411161011357806395d89b4114610576578063a22cb4651461058b578063b527c36d146105ab578063b75421a7146105c0578063b88d4fde146105d5578063bb029ba5146105f557600080fd5b80638da5cb5b146105075780638fc58f231461052557806392642744146105385780639358cdb31461054b578063937a00751461056157600080fd5b806338cc4831116101e85780634d3740a0116101ac5780634d3740a01461046a5780634f6ccce71461047f578063589c024d1461049f5780636352211e146104b257806370a08231146104d2578063715018a6146104f257600080fd5b806338cc4831146103f85780633bda89061461040b5780633ccfd60b1461042057806342842e0e146104355780634c5b7a291461045557600080fd5b8063165def1c1161023a578063165def1c14610348578063173bcf961461035b57806318160ddd1461038357806323b872dd146103a25780632f745c59146103c257806332cb6b0c146103e257600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063095ea7b314610306578063109a988d14610328575b600080fd5b34801561028357600080fd5b50610297610292366004612eda565b610773565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610784565b6040516102a39190612f4f565b3480156102da57600080fd5b506102ee6102e9366004612f62565b610816565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b50610326610321366004612f97565b6108b0565b005b34801561033457600080fd5b5061032661034336600461300d565b6109c6565b61032661035636600461311c565b610d67565b34801561036757600080fd5b506102ee73da17aa88e60cef4007cf10aa94191ecf15ba26f381565b34801561038f57600080fd5b506008545b6040519081526020016102a3565b3480156103ae57600080fd5b506103266103bd366004613163565b61111e565b3480156103ce57600080fd5b506103946103dd366004612f97565b61114f565b3480156103ee57600080fd5b5061039461271081565b34801561040457600080fd5b50336102ee565b34801561041757600080fd5b506103946111e5565b34801561042c57600080fd5b50610326611221565b34801561044157600080fd5b50610326610450366004613163565b6113a0565b34801561046157600080fd5b50610394606481565b34801561047657600080fd5b506103946113bb565b34801561048b57600080fd5b5061039461049a366004612f62565b61143e565b6103266104ad366004612f62565b6114d1565b3480156104be57600080fd5b506102ee6104cd366004612f62565b611830565b3480156104de57600080fd5b506103946104ed36600461319f565b6118a7565b3480156104fe57600080fd5b5061032661192e565b34801561051357600080fd5b50600a546001600160a01b03166102ee565b610326610533366004612f62565b611964565b610326610546366004612f62565b611be5565b34801561055757600080fd5b5061039461138881565b34801561056d57600080fd5b50610394600481565b34801561058257600080fd5b506102c1611d66565b34801561059757600080fd5b506103266105a63660046131ba565b611d75565b3480156105b757600080fd5b50610394611e3a565b3480156105cc57600080fd5b50610326611ebd565b3480156105e157600080fd5b506103266105f03660046131f6565b611f54565b34801561060157600080fd5b50610326611f8c565b34801561061657600080fd5b50610394600a81565b34801561062b57600080fd5b506102c161063a366004612f62565b6121b9565b34801561064b57600080fd5b50610394600681565b34801561066057600080fd5b506102ee736e306a7d34860b0d45346a870f6110483fc5f28081565b34801561068857600080fd5b506102c1612281565b34801561069d57600080fd5b506102976106ac36600461325e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156106e657600080fd5b50600b54610394565b3480156106fb57600080fd5b5061032661070a36600461319f565b61229d565b34801561071b57600080fd5b5061029761072a366004613291565b612335565b34801561073b57600080fd5b5061039467016345785d8a000081565b34801561075757600080fd5b506102ee7303d5a39cd7517bc568aa8b23c4302fa4c67dc20481565b600061077e82612374565b92915050565b606060008054610793906132c6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bf906132c6565b801561080c5780601f106107e15761010080835404028352916020019161080c565b820191906000526020600020905b8154815290600101906020018083116107ef57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166108945760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006108bb82611830565b9050806001600160a01b0316836001600160a01b031614156109295760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161088b565b336001600160a01b0382161480610945575061094581336106ac565b6109b75760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161088b565b6109c18383612399565b505050565b600a546001600160a01b031633146109f05760405162461bcd60e51b815260040161088b90613301565b600b541580610a015750600b546001145b80610a0e5750600b546002145b610a6a5760405162461bcd60e51b815260206004820152602760248201527f4769766561776179732063616e27742062652073657420696e2061697264726f6044820152667020706861736560c81b606482015260840161088b565b828114610ac75760405162461bcd60e51b815260206004820152602560248201527f456e7375726520696e707574206172726179732061726520657175616c20696e6044820152642073697a6560d81b606482015260840161088b565b600e5460005b82811015610b0d57838382818110610ae757610ae7613336565b9050602002013582610af99190613362565b915080610b058161337a565b915050610acd565b506064811115610b745760405162461bcd60e51b815260206004820152602c60248201527f5472616e73616374696f6e206578636565647320636f6e74726163742067697660448201526b6561776179206c696d69747360a01b606482015260840161088b565b60005b84811015610d5d57610c09868683818110610b9457610b94613336565b9050602002016020810190610ba9919061319f565b6010805480602002602001604051908101604052809291908181526020018280548015610bff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610be1575b5050505050612407565b151560011415610c9157838382818110610c2557610c25613336565b9050602002013560116000888885818110610c4257610c42613336565b9050602002016020810190610c57919061319f565b6001600160a01b03166001600160a01b031681526020019081526020016000206000828254610c869190613362565b90915550610d4b9050565b6010868683818110610ca557610ca5613336565b9050602002016020810190610cba919061319f565b81546001810183556000928352602090922090910180546001600160a01b0319166001600160a01b03909216919091179055838382818110610cfe57610cfe613336565b9050602002013560116000888885818110610d1b57610d1b613336565b9050602002016020810190610d30919061319f565b6001600160a01b031681526020810191909152604001600020555b80610d558161337a565b915050610b77565b50600e5550505050565b600b54600114610db95760405162461bcd60e51b815260206004820152601860248201527f43616e206f6e6c79206d696e7420696e2070726573616c650000000000000000604482015260640161088b565b610dc281612335565b1515600114610e1f5760405162461bcd60e51b815260206004820152602360248201527f596f7520617265206e6f742061206d656d626572206f66207468652070726573604482015262616c6560e81b606482015260840161088b565b610e8133600c805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b610ed857600c8054600181019091557fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b031916339081179091556000908152600d60205260409020600490555b336000908152600d6020526040902054821115610f485760405162461bcd60e51b815260206004820152602860248201527f5075726368617365206578636565647320796f75722070726573616c6520616c6044820152673637b1b0ba34b7b760c11b606482015260840161088b565b611388610f5e83610f5860085490565b9061246d565b1115610f7c5760405162461bcd60e51b815260040161088b90613395565b34610f8f67016345785d8a000084612480565b14610fdc5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604482015260640161088b565b60005b8281101561103157610ff933610ff460085490565b61248c565b336000908152600d602052604081208054600192906110199084906133dc565b909155508190506110298161337a565b915050610fdf565b50611094336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114156110c85733600090815260136020526040812080548492906110bd908490613362565b9091555061111a9050565b60128054600181019091557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319163390811790915560009081526013602052604090208290555b5050565b61112833826124a6565b6111445760405162461bcd60e51b815260040161088b906133f3565b6109c183838361259d565b600061115a836118a7565b82106111bc5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161088b565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6040516bffffffffffffffffffffffff193360601b16602082015260009060340160405160208183030381529060405280519060200120905090565b600a546001600160a01b0316331461124b5760405162461bcd60e51b815260040161088b90613301565b47806112995760405162461bcd60e51b815260206004820181905260248201527f42616c616e63652073686f756c64206265206d6f7265207468656e207a65726f604482015260640161088b565b73da17aa88e60cef4007cf10aa94191ecf15ba26f36108fc60056112be846002613444565b6112c89190613479565b6040518115909202916000818181858888f193505050501580156112f0573d6000803e3d6000fd5b50736e306a7d34860b0d45346a870f6110483fc5f2806108fc6005611316846002613444565b6113209190613479565b6040518115909202916000818181858888f19350505050158015611348573d6000803e3d6000fd5b507303d5a39cd7517bc568aa8b23c4302fa4c67dc2046108fc600561136e846001613444565b6113789190613479565b6040518115909202916000818181858888f1935050505015801561111a573d6000803e3d6000fd5b6109c183838360405180602001604052806000815250611f54565b600061141f336010805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1561143857503360009081526011602052604090205490565b50600090565b600061144960085490565b82106114ac5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161088b565b600882815481106114bf576114bf613336565b90600052602060002001549050919050565b600b54600114806114e45750600b546002145b6115445760405162461bcd60e51b815260206004820152602b60248201527f43616e206f6e6c79206d696e742067697665617761797320696e20707265736160448201526a6c6520616e642073616c6560a81b606482015260840161088b565b6115a6336010805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b15156001146116035760405162461bcd60e51b8152602060048201526024808201527f596f7520617265206e6f742061206d656d626572206f662074686520676976656044820152636177617960e01b606482015260840161088b565b336000908152601160205260409020548111156116745760405162461bcd60e51b815260206004820152602960248201527f5075726368617365206578636565647320796f75722067697665617761792061604482015268363637b1b0ba34b7b760b91b606482015260840161088b565b61138861168482610f5860085490565b11156116a25760405162461bcd60e51b815260040161088b90613395565b34156116ea5760405162461bcd60e51b8152602060048201526017602482015276045746865722076616c75652073686f756c64206265203604c1b604482015260640161088b565b60005b8181101561173a5761170233610ff460085490565b3360009081526011602052604081208054600192906117229084906133dc565b909155508190506117328161337a565b9150506116ed565b50600b5460031461182d576117a7336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114156117db5733600090815260136020526040812080548392906117d0908490613362565b9091555061182d9050565b60128054600181019091557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319163390811790915560009081526013602052604090208190555b50565b6000818152600260205260408120546001600160a01b03168061077e5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161088b565b60006001600160a01b0382166119125760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161088b565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b031633146119585760405162461bcd60e51b815260040161088b90613301565b6119626000612748565b565b600b546003146119c05760405162461bcd60e51b815260206004820152602160248201527f43616e206f6e6c79206d696e742061697264726f70732061667465722064726f6044820152600760fc1b606482015260840161088b565b611a22336012805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b1515600114611a7f5760405162461bcd60e51b815260206004820152602360248201527f596f7520617265206e6f742061206d656d626572206f662074686520616972646044820152620726f760ec1b606482015260840161088b565b33600090815260136020526040902054811115611aef5760405162461bcd60e51b815260206004820152602860248201527f5075726368617365206578636565647320796f75722061697264726f7020616c6044820152673637b1b0ba34b7b760c11b606482015260840161088b565b612710611aff82610f5860085490565b1115611b4d5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015260640161088b565b3415611b955760405162461bcd60e51b8152602060048201526017602482015276045746865722076616c75652073686f756c64206265203604c1b604482015260640161088b565b60005b8181101561111a57611bad33610ff460085490565b336000908152601360205260408120805460019290611bcd9084906133dc565b90915550819050611bdd8161337a565b915050611b98565b600b54600214611c375760405162461bcd60e51b815260206004820152601960248201527f43616e206f6e6c79206d696e7420647572696e672073616c6500000000000000604482015260640161088b565b600a811115611cae5760405162461bcd60e51b815260206004820152603760248201527f5265717565737420616d6f756e74206f66204e4654732065786365656473207360448201527f696e676c65207472616e73616374696f6e206c696d6974000000000000000000606482015260840161088b565b611388611cbe82610f5860085490565b1115611cdc5760405162461bcd60e51b815260040161088b90613395565b34611cef67016345785d8a000083612480565b14611d3c5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f727265637400604482015260640161088b565b60005b8181101561173a57611d5433610ff460085490565b80611d5e8161337a565b915050611d3f565b606060018054610793906132c6565b6001600160a01b038216331415611dce5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161088b565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000611e9e33600c805480602002602001604051908101604052809291908181526020018280548015610bff576020028201919060005260206000209081546001600160a01b03168152600190910190602001808311610be1575050505050612407565b15611eb75750336000908152600d602052604090205490565b50600490565b600a546001600160a01b03163314611ee75760405162461bcd60e51b815260040161088b90613301565b6003600b541115611f3a5760405162461bcd60e51b815260206004820152601760248201527f4e6f207068617365206265796f6e642070686173652033000000000000000000604482015260640161088b565b6001600b6000828254611f4d9190613362565b9091555050565b611f5e33836124a6565b611f7a5760405162461bcd60e51b815260040161088b906133f3565b611f868484848461279a565b50505050565b600a546001600160a01b03163314611fb65760405162461bcd60e51b815260040161088b90613301565b600b54156120145760405162461bcd60e51b815260206004820152602560248201527f43616e206f6e6c79206d696e7420646576206672616374616c7320696e2070726044820152646573616c6560d81b606482015260840161088b565b600f5460ff16156120675760405162461bcd60e51b815260206004820152601b60248201527f446576206672616374616c7320616c7265616479206d696e7465640000000000604482015260640161088b565b60005b60068110156120e85761209473da17aa88e60cef4007cf10aa94191ecf15ba26f3610ff460085490565b6120b5736e306a7d34860b0d45346a870f6110483fc5f280610ff460085490565b6120d67303d5a39cd7517bc568aa8b23c4302fa4c67dc204610ff460085490565b806120e08161337a565b91505061206a565b5060128054600181810183557fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec344491820180546001600160a01b031990811673da17aa88e60cef4007cf10aa94191ecf15ba26f317909155336000818152601360205260408120600680825587548087018955870180548616736e306a7d34860b0d45346a870f6110483fc5f28017905580825587548087019098559690950180549093167303d5a39cd7517bc568aa8b23c4302fa4c67dc204179092559052919055600f805460ff19169091179055565b6000818152600260205260409020546060906001600160a01b03166122385760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b606482015260840161088b565b6040518060600160405280602f81526020016135c8602f913961225a836127cd565b60405160200161226b92919061348d565b6040516020818303038152906040529050919050565b6040518060600160405280602f81526020016135c8602f913981565b600a546001600160a01b031633146122c75760405162461bcd60e51b815260040161088b90613301565b6001600160a01b03811661232c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161088b565b61182d81612748565b6000806123406111e5565b9050739eb0f5610d94141c051e19a110fb725cc24937668061236283866128cb565b6001600160a01b031614949350505050565b60006001600160e01b0319821663780e9d6360e01b148061077e575061077e826129a2565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906123ce82611830565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000805b82518110156124635782818151811061242657612426613336565b60200260200101516001600160a01b0316846001600160a01b0316141561245157600191505061077e565b8061245b8161337a565b91505061240b565b5060009392505050565b60006124798284613362565b9392505050565b60006124798284613444565b61111a8282604051806020016040528060008152506129f2565b6000818152600260205260408120546001600160a01b031661251f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161088b565b600061252a83611830565b9050806001600160a01b0316846001600160a01b031614806125655750836001600160a01b031661255a84610816565b6001600160a01b0316145b8061259557506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b03166125b082611830565b6001600160a01b0316146126185760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161088b565b6001600160a01b03821661267a5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161088b565b612685838383612a25565b612690600082612399565b6001600160a01b03831660009081526003602052604081208054600192906126b99084906133dc565b90915550506001600160a01b03821660009081526003602052604081208054600192906126e7908490613362565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6127a584848461259d565b6127b184848484612a30565b611f865760405162461bcd60e51b815260040161088b906134cc565b6060816127f15750506040805180820190915260018152600360fc1b602082015290565b8160005b811561281b57806128058161337a565b91506128149050600a83613479565b91506127f5565b60008167ffffffffffffffff81111561283657612836613079565b6040519080825280601f01601f191660200182016040528015612860576020820181803683370190505b5090505b8415612595576128756001836133dc565b9150612882600a8661351e565b61288d906030613362565b60f81b8183815181106128a2576128a2613336565b60200101906001600160f81b031916908160001a9053506128c4600a86613479565b9450612864565b60008060008084516041146128e6576000935050505061077e565b50505060208201516040830151606084015160001a601b8110156129125761290f601b82613532565b90505b8060ff16601b1415801561292a57508060ff16601c14155b1561293b576000935050505061077e565b60408051600081526020810180835288905260ff831691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561298e573d6000803e3d6000fd5b50505060206040510351935050505061077e565b60006001600160e01b031982166380ac58cd60e01b14806129d357506001600160e01b03198216635b5e139f60e01b145b8061077e57506301ffc9a760e01b6001600160e01b031983161461077e565b6129fc8383612b2e565b612a096000848484612a30565b6109c15760405162461bcd60e51b815260040161088b906134cc565b6109c1838383612c7c565b60006001600160a01b0384163b15612b2357604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612a74903390899088908890600401613557565b6020604051808303816000875af1925050508015612aaf575060408051601f3d908101601f19168201909252612aac91810190613594565b60015b612b09573d808015612add576040519150601f19603f3d011682016040523d82523d6000602084013e612ae2565b606091505b508051612b015760405162461bcd60e51b815260040161088b906134cc565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612595565b506001949350505050565b6001600160a01b038216612b845760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161088b565b6000818152600260205260409020546001600160a01b031615612be95760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161088b565b612bf560008383612a25565b6001600160a01b0382166000908152600360205260408120805460019290612c1e908490613362565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b038316612cd757612cd281600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612cfa565b816001600160a01b0316836001600160a01b031614612cfa57612cfa8382612d34565b6001600160a01b038216612d11576109c181612dd1565b826001600160a01b0316826001600160a01b0316146109c1576109c18282612e80565b60006001612d41846118a7565b612d4b91906133dc565b600083815260076020526040902054909150808214612d9e576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612de3906001906133dc565b60008381526009602052604081205460088054939450909284908110612e0b57612e0b613336565b906000526020600020015490508060088381548110612e2c57612e2c613336565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612e6457612e646135b1565b6001900381819060005260206000200160009055905550505050565b6000612e8b836118a7565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b03198116811461182d57600080fd5b600060208284031215612eec57600080fd5b813561247981612ec4565b60005b83811015612f12578181015183820152602001612efa565b83811115611f865750506000910152565b60008151808452612f3b816020860160208601612ef7565b601f01601f19169290920160200192915050565b6020815260006124796020830184612f23565b600060208284031215612f7457600080fd5b5035919050565b80356001600160a01b0381168114612f9257600080fd5b919050565b60008060408385031215612faa57600080fd5b612fb383612f7b565b946020939093013593505050565b60008083601f840112612fd357600080fd5b50813567ffffffffffffffff811115612feb57600080fd5b6020830191508360208260051b850101111561300657600080fd5b9250929050565b6000806000806040858703121561302357600080fd5b843567ffffffffffffffff8082111561303b57600080fd5b61304788838901612fc1565b9096509450602087013591508082111561306057600080fd5b5061306d87828801612fc1565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126130a057600080fd5b813567ffffffffffffffff808211156130bb576130bb613079565b604051601f8301601f19908116603f011681019082821181831017156130e3576130e3613079565b816040528381528660208588010111156130fc57600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561312f57600080fd5b82359150602083013567ffffffffffffffff81111561314d57600080fd5b6131598582860161308f565b9150509250929050565b60008060006060848603121561317857600080fd5b61318184612f7b565b925061318f60208501612f7b565b9150604084013590509250925092565b6000602082840312156131b157600080fd5b61247982612f7b565b600080604083850312156131cd57600080fd5b6131d683612f7b565b9150602083013580151581146131eb57600080fd5b809150509250929050565b6000806000806080858703121561320c57600080fd5b61321585612f7b565b935061322360208601612f7b565b925060408501359150606085013567ffffffffffffffff81111561324657600080fd5b6132528782880161308f565b91505092959194509250565b6000806040838503121561327157600080fd5b61327a83612f7b565b915061328860208401612f7b565b90509250929050565b6000602082840312156132a357600080fd5b813567ffffffffffffffff8111156132ba57600080fd5b6125958482850161308f565b600181811c908216806132da57607f821691505b602082108114156132fb57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156133755761337561334c565b500190565b600060001982141561338e5761338e61334c565b5060010190565b60208082526027908201527f507572636861736520776f756c6420657863656564206d6178207075626c696360408201526620737570706c7960c81b606082015260800190565b6000828210156133ee576133ee61334c565b500390565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600081600019048311821515161561345e5761345e61334c565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261348857613488613463565b500490565b6000835161349f818460208801612ef7565b8351908301906134b3818360208801612ef7565b64173539b7b760d91b9101908152600501949350505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60008261352d5761352d613463565b500690565b600060ff821660ff84168060ff0382111561354f5761354f61334c565b019392505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061358a90830184612f23565b9695505050505050565b6000602082840312156135a657600080fd5b815161247981612ec4565b634e487b7160e01b600052603160045260246000fdfe68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f666c616d65732f6d657461646174612fa26469706673582212205e22f36fbc705b16c3708f48ea2a2706e60c87887ee3d972255b887b189d499764736f6c634300080b0033

Deployed Bytecode Sourcemap

51621:12482:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63653:219;;;;;;;;;;-1:-1:-1;63653:219:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;63653:219:0;;;;;;;;23231:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;24790:221::-;;;;;;;;;;-1:-1:-1;24790:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:1;;;1674:51;;1662:2;1647:18;24790:221:0;1528:203:1;24313:411:0;;;;;;;;;;-1:-1:-1;24313:411:0;;;;;:::i;:::-;;:::i;:::-;;57220:1004;;;;;;;;;;-1:-1:-1;57220:1004:0;;;;;:::i;:::-;;:::i;59319:1345::-;;;;;;:::i;:::-;;:::i;52302:81::-;;;;;;;;;;;;52341:42;52302:81;;36920:113;;;;;;;;;;-1:-1:-1;37008:10:0;:17;36920:113;;;4717:25:1;;;4705:2;4690:18;36920:113:0;4571:177:1;25680:339:0;;;;;;;;;;-1:-1:-1;25680:339:0;;;;;:::i;:::-;;:::i;36588:256::-;;;;;;;;;;-1:-1:-1;36588:256:0;;;;;:::i;:::-;;:::i;51852:42::-;;;;;;;;;;;;51889:5;51852:42;;54313:88;;;;;;;;;;-1:-1:-1;54383:10:0;54313:88;;54184:121;;;;;;;;;;;;;:::i;56395:359::-;;;;;;;;;;;;;:::i;26090:185::-;;;;;;;;;;-1:-1:-1;26090:185:0;;;;;:::i;:::-;;:::i;51901:42::-;;;;;;;;;;;;51940:3;51901:42;;55664:262;;;;;;;;;;;;;:::i;37110:233::-;;;;;;;;;;-1:-1:-1;37110:233:0;;;;;:::i;:::-;;:::i;60674:1129::-;;;;;;:::i;:::-;;:::i;22925:239::-;;;;;;;;;;-1:-1:-1;22925:239:0;;;;;:::i;:::-;;:::i;22655:208::-;;;;;;;;;;-1:-1:-1;22655:208:0;;;;;:::i;:::-;;:::i;50988:94::-;;;;;;;;;;;;;:::i;50337:87::-;;;;;;;;;;-1:-1:-1;50410:6:0;;-1:-1:-1;;;;;50410:6:0;50337:87;;62859:718;;;;;;:::i;:::-;;:::i;61847:968::-;;;;;;:::i;:::-;;:::i;51950:49::-;;;;;;;;;;;;51995:4;51950:49;;52055:52;;;;;;;;;;;;52106:1;52055:52;;23400:104;;;;;;;;;;;;;:::i;25083:295::-;;;;;;;;;;-1:-1:-1;25083:295:0;;;;;:::i;:::-;;:::i;55934:376::-;;;;;;;;;;;;;:::i;55323:175::-;;;;;;;;;;;;;:::i;26346:328::-;;;;;;;;;;-1:-1:-1;26346:328:0;;;;;:::i;:::-;;:::i;58232:888::-;;;;;;;;;;;;;:::i;52114:48::-;;;;;;;;;;;;52160:2;52114:48;;56814:322;;;;;;;;;;-1:-1:-1;56814:322:0;;;;;:::i;:::-;;:::i;52169:51::-;;;;;;;;;;;;52219:1;52169:51;;52390:81;;;;;;;;;;;;52429:42;52390:81;;52568:83;;;;;;;;;;;;;:::i;25449:164::-;;;;;;;;;;-1:-1:-1;25449:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;25570:25:0;;;25546:4;25570:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;25449:164;55536:120;;;;;;;;;;-1:-1:-1;55639:9:0;;55536:120;;51237:192;;;;;;;;;;-1:-1:-1;51237:192:0;;;;;:::i;:::-;;:::i;53924:252::-;;;;;;;;;;-1:-1:-1;53924:252:0;;;;;:::i;:::-;;:::i;52227:55::-;;;;;;;;;;;;52264:18;52227:55;;52478:81;;;;;;;;;;;;52517:42;52478:81;;63653:219;63797:4;63827:37;63851:12;63827:23;:37::i;:::-;63820:44;63653:219;-1:-1:-1;;63653:219:0:o;23231:100::-;23285:13;23318:5;23311:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23231:100;:::o;24790:221::-;24866:7;28273:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28273:16:0;24886:73;;;;-1:-1:-1;;;24886:73:0;;7530:2:1;24886:73:0;;;7512:21:1;7569:2;7549:18;;;7542:30;7608:34;7588:18;;;7581:62;-1:-1:-1;;;7659:18:1;;;7652:42;7711:19;;24886:73:0;;;;;;;;;-1:-1:-1;24979:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;24979:24:0;;24790:221::o;24313:411::-;24394:13;24410:23;24425:7;24410:14;:23::i;:::-;24394:39;;24458:5;-1:-1:-1;;;;;24452:11:0;:2;-1:-1:-1;;;;;24452:11:0;;;24444:57;;;;-1:-1:-1;;;24444:57:0;;7943:2:1;24444:57:0;;;7925:21:1;7982:2;7962:18;;;7955:30;8021:34;8001:18;;;7994:62;-1:-1:-1;;;8072:18:1;;;8065:31;8113:19;;24444:57:0;7741:397:1;24444:57:0;54383:10;-1:-1:-1;;;;;24536:21:0;;;;:62;;-1:-1:-1;24561:37:0;24578:5;54383:10;25449:164;:::i;24561:37::-;24514:168;;;;-1:-1:-1;;;24514:168:0;;8345:2:1;24514:168:0;;;8327:21:1;8384:2;8364:18;;;8357:30;8423:34;8403:18;;;8396:62;8494:26;8474:18;;;8467:54;8538:19;;24514:168:0;8143:420:1;24514:168:0;24695:21;24704:2;24708:7;24695:8;:21::i;:::-;24383:341;24313:411;;:::o;57220:1004::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;57369:9:::1;::::0;:14;;:32:::1;;;57387:9;;57400:1;57387:14;57369:32;:50;;;;57405:9;;57418:1;57405:14;57369:50;57361:102;;;::::0;-1:-1:-1;;;57361:102:0;;9131:2:1;57361:102:0::1;::::0;::::1;9113:21:1::0;9170:2;9150:18;;;9143:30;9209:34;9189:18;;;9182:62;-1:-1:-1;;;9260:18:1;;;9253:37;9307:19;;57361:102:0::1;8929:403:1::0;57361:102:0::1;57482:33:::0;;::::1;57474:83;;;::::0;-1:-1:-1;;;57474:83:0;;9539:2:1;57474:83:0::1;::::0;::::1;9521:21:1::0;9578:2;9558:18;;;9551:30;9617:34;9597:18;;;9590:62;-1:-1:-1;;;9668:18:1;;;9661:35;9713:19;;57474:83:0::1;9337:401:1::0;57474:83:0::1;57595:14;::::0;57570:22:::1;57622:95;57639:17:::0;;::::1;57622:95;;;57696:6;;57703:1;57696:9;;;;;;;:::i;:::-;;;;;;;57678:27;;;;;:::i;:::-;::::0;-1:-1:-1;57658:3:0;::::1;::::0;::::1;:::i;:::-;;;;57622:95;;;;51940:3;57737:14;:30;;57729:87;;;::::0;-1:-1:-1;;;57729:87:0;;10482:2:1;57729:87:0::1;::::0;::::1;10464:21:1::0;10521:2;10501:18;;;10494:30;10560:34;10540:18;;;10533:62;-1:-1:-1;;;10611:18:1;;;10604:42;10663:19;;57729:87:0::1;10280:408:1::0;57729:87:0::1;57834:6;57829:344;57846:20:::0;;::::1;57829:344;;;57892:45;57904:9;;57914:1;57904:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;57918:18;57892:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;57892:45:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;:11;:45::i;:::-;:53;;57941:4;57892:53;57888:274;;;57999:6;;58006:1;57999:9;;;;;;;:::i;:::-;;;;;;;57966:15;:29;57982:9;;57992:1;57982:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;57966:29:0::1;-1:-1:-1::0;;;;;57966:29:0::1;;;;;;;;;;;;;:42;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;57888:274:0::1;::::0;-1:-1:-1;57888:274:0::1;;58049:18;58073:9;;58083:1;58073:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;58049:37:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;58049:37:0;;;::::1;::::0;;;;;::::1;::::0;;-1:-1:-1;;;;;;58049:37:0::1;-1:-1:-1::0;;;;;58049:37:0;;::::1;::::0;;;::::1;::::0;;58137:6;;58144:1;58137:9;;::::1;;;;;:::i;:::-;;;;;;;58105:15;:29;58121:9;;58131:1;58121:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58105:29:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;58105:29:0;:41;57888:274:::1;57868:3:::0;::::1;::::0;::::1;:::i;:::-;;;;57829:344;;;-1:-1:-1::0;58185:14:0::1;:31:::0;-1:-1:-1;;;;57220:1004:0:o;59319:1345::-;59440:9;;59453:1;59440:14;59432:51;;;;-1:-1:-1;;;59432:51:0;;10895:2:1;59432:51:0;;;10877:21:1;10934:2;10914:18;;;10907:30;10973:26;10953:18;;;10946:54;11017:18;;59432:51:0;10693:348:1;59432:51:0;59502:20;59518:3;59502:15;:20::i;:::-;:28;;59526:4;59502:28;59494:76;;;;-1:-1:-1;;;59494:76:0;;11248:2:1;59494:76:0;;;11230:21:1;11287:2;11267:18;;;11260:30;11326:34;11306:18;;;11299:62;-1:-1:-1;;;11377:18:1;;;11370:33;11420:19;;59494:76:0;11046:399:1;59494:76:0;59671:44;59683:10;59695:19;59671:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59671:44:0;;;;;;;;;;;;;;;;;;;;:11;:44::i;:::-;59667:192;;59741:19;:36;;;;;;;;;;;;-1:-1:-1;;;;;;59741:36:0;59766:10;59741:36;;;;;;-1:-1:-1;59792:28:0;;;:16;59741:36;59792:28;;;;52106:1;59792:55;;59667:192;59896:10;59879:28;;;;:16;:28;;;;;;:44;-1:-1:-1;59879:44:0;59871:97;;;;-1:-1:-1;;;59871:97:0;;11652:2:1;59871:97:0;;;11634:21:1;11691:2;11671:18;;;11664:30;11730:34;11710:18;;;11703:62;-1:-1:-1;;;11781:18:1;;;11774:38;11829:19;;59871:97:0;11450:404:1;59871:97:0;52044:4;59987:31;60005:12;59987:13;37008:10;:17;;36920:113;59987:13;:17;;:31::i;:::-;:46;;59979:98;;;;-1:-1:-1;;;59979:98:0;;;;;;;:::i;:::-;60128:9;60096:28;52264:18;60111:12;60096:14;:28::i;:::-;:41;60088:85;;;;-1:-1:-1;;;60088:85:0;;12469:2:1;60088:85:0;;;12451:21:1;12508:2;12488:18;;;12481:30;12547:33;12527:18;;;12520:61;12598:18;;60088:85:0;12267:355:1;60088:85:0;60212:6;60208:150;60228:12;60224:1;:16;60208:150;;;60262:36;60272:10;60284:13;37008:10;:17;;36920:113;60284:13;60262:9;:36::i;:::-;60330:10;60313:28;;;;:16;:28;;;;;:33;;60345:1;;60313:28;:33;;60345:1;;60313:33;:::i;:::-;;;;-1:-1:-1;60242:3:0;;-1:-1:-1;60242:3:0;;;:::i;:::-;;;;60208:150;;;;60413:42;60425:10;60437:17;60413:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60413:42:0;;;;;;;;;;;;;;;;;;;;:11;:42::i;:::-;:50;;60459:4;60413:50;60409:248;;;60495:10;60480:26;;;;:14;:26;;;;;:42;;60510:12;;60480:26;:42;;60510:12;;60480:42;:::i;:::-;;;;-1:-1:-1;60409:248:0;;-1:-1:-1;60409:248:0;;60555:17;:34;;;;;;;;;;;;-1:-1:-1;;;;;;60555:34:0;60578:10;60555:34;;;;;;-1:-1:-1;60604:26:0;;;:14;60555:34;60604:26;;;;:41;;;60409:248;59319:1345;;:::o;25680:339::-;25875:41;54383:10;25908:7;25875:18;:41::i;:::-;25867:103;;;;-1:-1:-1;;;25867:103:0;;;;;;;:::i;:::-;25983:28;25993:4;25999:2;26003:7;25983:9;:28::i;36588:256::-;36685:7;36721:23;36738:5;36721:16;:23::i;:::-;36713:5;:31;36705:87;;;;-1:-1:-1;;;36705:87:0;;13377:2:1;36705:87:0;;;13359:21:1;13416:2;13396:18;;;13389:30;13455:34;13435:18;;;13428:62;-1:-1:-1;;;13506:18:1;;;13499:41;13557:19;;36705:87:0;13175:407:1;36705:87:0;-1:-1:-1;;;;;;36810:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;36588:256::o;54184:121::-;54268:28;;-1:-1:-1;;54285:10:0;13736:2:1;13732:15;13728:53;54268:28:0;;;13716:66:1;54231:7:0;;13798:12:1;;54268:28:0;;;;;;;;;;;;54258:39;;;;;;54251:46;;54184:121;:::o;56395:359::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;56484:21:::1;56524:11:::0;56516:56:::1;;;::::0;-1:-1:-1;;;56516:56:0;;14023:2:1;56516:56:0::1;::::0;::::1;14005:21:1::0;;;14042:18;;;14035:30;14101:34;14081:18;;;14074:62;14153:18;;56516:56:0::1;13821:356:1::0;56516:56:0::1;52341:42;56583:47;56628:1;56614:11;:7:::0;56624:1:::1;56614:11;:::i;:::-;:15;;;;:::i;:::-;56583:47;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;52429:42:0::1;56641:47;56686:1;56672:11;:7:::0;56682:1:::1;56672:11;:::i;:::-;:15;;;;:::i;:::-;56641:47;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;52517:42:0::1;56699:47;56744:1;56730:11;:7:::0;56740:1:::1;56730:11;:::i;:::-;:15;;;;:::i;:::-;56699:47;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;26090:185:::0;26228:39;26245:4;26251:2;26255:7;26228:39;;;;;;;;;;;;:16;:39::i;55664:262::-;55743:7;55772:43;55784:10;55796:18;55772:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55772:43:0;;;;;;;;;;;;;;;;;;;;:11;:43::i;:::-;55768:151;;;-1:-1:-1;55855:10:0;55839:27;;;;:15;:27;;;;;;;55664:262::o;55768:151::-;-1:-1:-1;55906:1:0;;55664:262::o;37110:233::-;37185:7;37221:30;37008:10;:17;;36920:113;37221:30;37213:5;:38;37205:95;;;;-1:-1:-1;;;37205:95:0;;14814:2:1;37205:95:0;;;14796:21:1;14853:2;14833:18;;;14826:30;14892:34;14872:18;;;14865:62;-1:-1:-1;;;14943:18:1;;;14936:42;14995:19;;37205:95:0;14612:408:1;37205:95:0;37318:10;37329:5;37318:17;;;;;;;;:::i;:::-;;;;;;;;;37311:24;;37110:233;;;:::o;60674:1129::-;60778:9;;60791:1;60778:14;:32;;;;60796:9;;60809:1;60796:14;60778:32;60770:88;;;;-1:-1:-1;;;60770:88:0;;15227:2:1;60770:88:0;;;15209:21:1;15266:2;15246:18;;;15239:30;15305:34;15285:18;;;15278:62;-1:-1:-1;;;15356:18:1;;;15349:41;15407:19;;60770:88:0;15025:407:1;60770:88:0;60877:43;60889:10;60901:18;60877:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60877:43:0;;;;;;;;;;;;;;;;;;;;:11;:43::i;:::-;:51;;60924:4;60877:51;60869:100;;;;-1:-1:-1;;;60869:100:0;;15639:2:1;60869:100:0;;;15621:21:1;15678:2;15658:18;;;15651:30;15717:34;15697:18;;;15690:62;-1:-1:-1;;;15768:18:1;;;15761:34;15812:19;;60869:100:0;15437:400:1;60869:100:0;61004:10;60988:27;;;;:15;:27;;;;;;:43;-1:-1:-1;60988:43:0;60980:97;;;;-1:-1:-1;;;60980:97:0;;16044:2:1;60980:97:0;;;16026:21:1;16083:2;16063:18;;;16056:30;16122:34;16102:18;;;16095:62;-1:-1:-1;;;16173:18:1;;;16166:39;16222:19;;60980:97:0;15842:405:1;60980:97:0;52044:4;61096:31;61114:12;61096:13;37008:10;:17;;36920:113;61096:31;:46;;61088:98;;;;-1:-1:-1;;;61088:98:0;;;;;;;:::i;:::-;61205:9;:14;61197:50;;;;-1:-1:-1;;;61197:50:0;;16454:2:1;61197:50:0;;;16436:21:1;16493:2;16473:18;;;16466:30;-1:-1:-1;;;16512:18:1;;;16505:53;16575:18;;61197:50:0;16252:347:1;61197:50:0;61286:6;61282:149;61302:12;61298:1;:16;61282:149;;;61336:36;61346:10;61358:13;37008:10;:17;;36920:113;61336:36;61403:10;61387:27;;;;:15;:27;;;;;:32;;61418:1;;61387:27;:32;;61418:1;;61387:32;:::i;:::-;;;;-1:-1:-1;61316:3:0;;-1:-1:-1;61316:3:0;;;:::i;:::-;;;;61282:149;;;;61486:9;;61499:1;61486:14;61482:314;;61521:42;61533:10;61545:17;61521:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61521:42:0;;;;;;;;;;;;;;;;;;;;:11;:42::i;:::-;:50;;61567:4;61521:50;61517:268;;;61607:10;61592:26;;;;:14;:26;;;;;:42;;61622:12;;61592:26;:42;;61622:12;;61592:42;:::i;:::-;;;;-1:-1:-1;61517:268:0;;-1:-1:-1;61517:268:0;;61675:17;:34;;;;;;;;;;;;-1:-1:-1;;;;;;61675:34:0;61698:10;61675:34;;;;;;-1:-1:-1;61728:26:0;;;:14;61675:34;61728:26;;;;:41;;;61517:268;60674:1129;:::o;22925:239::-;22997:7;23033:16;;;:7;:16;;;;;;-1:-1:-1;;;;;23033:16:0;23068:19;23060:73;;;;-1:-1:-1;;;23060:73:0;;16806:2:1;23060:73:0;;;16788:21:1;16845:2;16825:18;;;16818:30;16884:34;16864:18;;;16857:62;-1:-1:-1;;;16935:18:1;;;16928:39;16984:19;;23060:73:0;16604:405:1;22655:208:0;22727:7;-1:-1:-1;;;;;22755:19:0;;22747:74;;;;-1:-1:-1;;;22747:74:0;;17216:2:1;22747:74:0;;;17198:21:1;17255:2;17235:18;;;17228:30;17294:34;17274:18;;;17267:62;-1:-1:-1;;;17345:18:1;;;17338:40;17395:19;;22747:74:0;17014:406:1;22747:74:0;-1:-1:-1;;;;;;22839:16:0;;;;;:9;:16;;;;;;;22655:208::o;50988:94::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;51053:21:::1;51071:1;51053:9;:21::i;:::-;50988:94::o:0;62859:718::-;62958:9;;62971:1;62958:14;62950:60;;;;-1:-1:-1;;;62950:60:0;;17627:2:1;62950:60:0;;;17609:21:1;17666:2;17646:18;;;17639:30;17705:34;17685:18;;;17678:62;-1:-1:-1;;;17756:18:1;;;17749:31;17797:19;;62950:60:0;17425:397:1;62950:60:0;63029:42;63041:10;63053:17;63029:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63029:42:0;;;;;;;;;;;;;;;;;;;;:11;:42::i;:::-;:50;;63075:4;63029:50;63021:98;;;;-1:-1:-1;;;63021:98:0;;18029:2:1;63021:98:0;;;18011:21:1;18068:2;18048:18;;;18041:30;18107:34;18087:18;;;18080:62;-1:-1:-1;;;18158:18:1;;;18151:33;18201:19;;63021:98:0;17827:399:1;63021:98:0;63153:10;63138:26;;;;:14;:26;;;;;;:42;-1:-1:-1;63138:42:0;63130:95;;;;-1:-1:-1;;;63130:95:0;;18433:2:1;63130:95:0;;;18415:21:1;18472:2;18452:18;;;18445:30;18511:34;18491:18;;;18484:62;-1:-1:-1;;;18562:18:1;;;18555:38;18610:19;;63130:95:0;18231:404:1;63130:95:0;51889:5;63244:31;63262:12;63244:13;37008:10;:17;;36920:113;63244:31;:45;;63236:90;;;;-1:-1:-1;;;63236:90:0;;18842:2:1;63236:90:0;;;18824:21:1;;;18861:18;;;18854:30;18920:34;18900:18;;;18893:62;18972:18;;63236:90:0;18640:356:1;63236:90:0;63345:9;:14;63337:50;;;;-1:-1:-1;;;63337:50:0;;16454:2:1;63337:50:0;;;16436:21:1;16493:2;16473:18;;;16466:30;-1:-1:-1;;;16512:18:1;;;16505:53;16575:18;;63337:50:0;16252:347:1;63337:50:0;63426:6;63422:148;63442:12;63438:1;:16;63422:148;;;63476:36;63486:10;63498:13;37008:10;:17;;36920:113;63476:36;63542:10;63527:26;;;;:14;:26;;;;;:31;;63557:1;;63527:26;:31;;63557:1;;63527:31;:::i;:::-;;;;-1:-1:-1;63456:3:0;;-1:-1:-1;63456:3:0;;;:::i;:::-;;;;63422:148;;61847:968;61943:9;;61956:1;61943:14;61935:52;;;;-1:-1:-1;;;61935:52:0;;19203:2:1;61935:52:0;;;19185:21:1;19242:2;19222:18;;;19215:30;19281:27;19261:18;;;19254:55;19326:18;;61935:52:0;19001:349:1;61935:52:0;52160:2;62006:12;:35;;61998:103;;;;-1:-1:-1;;;61998:103:0;;19557:2:1;61998:103:0;;;19539:21:1;19596:2;19576:18;;;19569:30;19635:34;19615:18;;;19608:62;19706:25;19686:18;;;19679:53;19749:19;;61998:103:0;19355:419:1;61998:103:0;52044:4;62120:31;62138:12;62120:13;37008:10;:17;;36920:113;62120:31;:46;;62112:98;;;;-1:-1:-1;;;62112:98:0;;;;;;;:::i;:::-;62261:9;62229:28;52264:18;62244:12;62229:14;:28::i;:::-;:41;62221:85;;;;-1:-1:-1;;;62221:85:0;;12469:2:1;62221:85:0;;;12451:21:1;12508:2;12488:18;;;12481:30;12547:33;12527:18;;;12520:61;12598:18;;62221:85:0;12267:355:1;62221:85:0;62345:6;62341:102;62361:12;62357:1;:16;62341:102;;;62395:36;62405:10;62417:13;37008:10;:17;;36920:113;62395:36;62375:3;;;;:::i;:::-;;;;62341:102;;23400:104;23456:13;23489:7;23482:14;;;;;:::i;25083:295::-;-1:-1:-1;;;;;25186:24:0;;54383:10;25186:24;;25178:62;;;;-1:-1:-1;;;25178:62:0;;19981:2:1;25178:62:0;;;19963:21:1;20020:2;20000:18;;;19993:30;20059:27;20039:18;;;20032:55;20104:18;;25178:62:0;19779:349:1;25178:62:0;54383:10;25253:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;25253:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;25253:53:0;;;;;;;;;;25322:48;;540:41:1;;;25253:42:0;;54383:10;25322:48;;513:18:1;25322:48:0;;;;;;;25083:295;;:::o;55934:376::-;56021:7;56131:44;56143:10;56155:19;56131:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56131:44:0;;;;;;;;;;;;;;;;;;;;:11;:44::i;:::-;56127:176;;;-1:-1:-1;56216:10:0;56199:28;;;;:16;:28;;;;;;;55934:376::o;56127:176::-;-1:-1:-1;52106:1:0;;55934:376::o;55323:175::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;55428:1:::1;55415:9;;:14;;55407:50;;;::::0;-1:-1:-1;;;55407:50:0;;20335:2:1;55407:50:0::1;::::0;::::1;20317:21:1::0;20374:2;20354:18;;;20347:30;20413:25;20393:18;;;20386:53;20456:18;;55407:50:0::1;20133:347:1::0;55407:50:0::1;55481:1;55468:9;;:14;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;55323:175:0:o;26346:328::-;26521:41;54383:10;26554:7;26521:18;:41::i;:::-;26513:103;;;;-1:-1:-1;;;26513:103:0;;;;;;;:::i;:::-;26627:39;26641:4;26647:2;26651:7;26660:5;26627:13;:39::i;:::-;26346:328;;;;:::o;58232:888::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;58321:9:::1;::::0;:14;58313:64:::1;;;::::0;-1:-1:-1;;;58313:64:0;;20687:2:1;58313:64:0::1;::::0;::::1;20669:21:1::0;20726:2;20706:18;;;20699:30;20765:34;20745:18;;;20738:62;-1:-1:-1;;;20816:18:1;;;20809:35;20861:19;;58313:64:0::1;20485:401:1::0;58313:64:0::1;58396:19;::::0;::::1;;:28;58388:68;;;::::0;-1:-1:-1;;;58388:68:0;;21093:2:1;58388:68:0::1;::::0;::::1;21075:21:1::0;21132:2;21112:18;;;21105:30;21171:29;21151:18;;;21144:57;21218:18;;58388:68:0::1;20891:351:1::0;58388:68:0::1;58521:6;58516:222;52219:1;58533;:27;58516:222;;;58582:38;52341:42;58606:13;37008:10:::0;:17;;36920:113;58582:38:::1;58635;52429:42;58659:13;37008:10:::0;:17;;36920:113;58635:38:::1;58688;52517:42;58712:13;37008:10:::0;:17;;36920:113;58688:38:::1;58562:3:::0;::::1;::::0;::::1;:::i;:::-;;;;58516:222;;;-1:-1:-1::0;58750:17:0::1;:36:::0;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;;-1:-1:-1;;;;;;58750:36:0;;::::1;52341:42;58750:36;::::0;;;58812:10:::1;-1:-1:-1::0;58797:26:0;;;:14:::1;58750:36;58797:26:::0;;;;52219:1:::1;58797:52:::0;;;58862:36;;;;::::1;::::0;;;::::1;::::0;;;::::1;52429:42;58862:36;::::0;;58909:52;;;58974:36;;;;::::1;::::0;;;;;;::::1;::::0;;;;::::1;52517:42;58974:36;::::0;;;59021:26;;:52;;;59086:19:::1;:26:::0;;-1:-1:-1;;59086:26:0::1;::::0;;::::1;::::0;;58232:888::o;56814:322::-;28249:4;28273:16;;;:7;:16;;;;;;56937:13;;-1:-1:-1;;;;;28273:16:0;56969:77;;;;-1:-1:-1;;;56969:77:0;;21449:2:1;56969:77:0;;;21431:21:1;21488:2;21468:18;;;21461:30;21527:34;21507:18;;;21500:62;-1:-1:-1;;;21578:18:1;;;21571:45;21633:19;;56969:77:0;21247:411:1;56969:77:0;57088:8;;;;;;;;;;;;;;;;;57098:19;:8;:17;:19::i;:::-;57071:56;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57057:71;;56814:322;;;:::o;52568:83::-;;;;;;;;;;;;;;;;;;;:::o;51237:192::-;50410:6;;-1:-1:-1;;;;;50410:6:0;54383:10;50557:23;50549:68;;;;-1:-1:-1;;;50549:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51326:22:0;::::1;51318:73;;;::::0;-1:-1:-1;;;51318:73:0;;22507:2:1;51318:73:0::1;::::0;::::1;22489:21:1::0;22546:2;22526:18;;;22519:30;22585:34;22565:18;;;22558:62;-1:-1:-1;;;22636:18:1;;;22629:36;22682:19;;51318:73:0::1;22305:402:1::0;51318:73:0::1;51402:19;51412:8;51402:9;:19::i;53924:252::-:0;53988:4;54005:15;54023:16;:14;:16::i;:::-;54005:34;-1:-1:-1;54065:42:0;;54139:21;54005:34;54156:3;54139:7;:21::i;:::-;-1:-1:-1;;;;;54139:29:0;;;53924:252;-1:-1:-1;;;;53924:252:0:o;36280:224::-;36382:4;-1:-1:-1;;;;;;36406:50:0;;-1:-1:-1;;;36406:50:0;;:90;;;36460:36;36484:11;36460:23;:36::i;32166:174::-;32241:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;32241:29:0;-1:-1:-1;;;;;32241:29:0;;;;;;;;:24;;32295:23;32241:24;32295:14;:23::i;:::-;-1:-1:-1;;;;;32286:46:0;;;;;;;;;;;32166:174;;:::o;54892:285::-;54998:4;;55020:127;55039:4;:11;55035:1;:15;55020:127;;;55081:4;55086:1;55081:7;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;55076:12:0;:1;-1:-1:-1;;;;;55076:12:0;;55072:64;;;55116:4;55109:11;;;;;55072:64;55052:3;;;;:::i;:::-;;;;55020:127;;;-1:-1:-1;55164:5:0;;54892:285;-1:-1:-1;;;54892:285:0:o;45199:98::-;45257:7;45284:5;45288:1;45284;:5;:::i;:::-;45277:12;45199:98;-1:-1:-1;;;45199:98:0:o;45937:::-;45995:7;46022:5;46026:1;46022;:5;:::i;29168:110::-;29244:26;29254:2;29258:7;29244:26;;;;;;;;;;;;:9;:26::i;28478:348::-;28571:4;28273:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28273:16:0;28588:73;;;;-1:-1:-1;;;28588:73:0;;22914:2:1;28588:73:0;;;22896:21:1;22953:2;22933:18;;;22926:30;22992:34;22972:18;;;22965:62;-1:-1:-1;;;23043:18:1;;;23036:42;23095:19;;28588:73:0;22712:408:1;28588:73:0;28672:13;28688:23;28703:7;28688:14;:23::i;:::-;28672:39;;28741:5;-1:-1:-1;;;;;28730:16:0;:7;-1:-1:-1;;;;;28730:16:0;;:51;;;;28774:7;-1:-1:-1;;;;;28750:31:0;:20;28762:7;28750:11;:20::i;:::-;-1:-1:-1;;;;;28750:31:0;;28730:51;:87;;;-1:-1:-1;;;;;;25570:25:0;;;25546:4;25570:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;28785:32;28722:96;28478:348;-1:-1:-1;;;;28478:348:0:o;31470:578::-;31629:4;-1:-1:-1;;;;;31602:31:0;:23;31617:7;31602:14;:23::i;:::-;-1:-1:-1;;;;;31602:31:0;;31594:85;;;;-1:-1:-1;;;31594:85:0;;23327:2:1;31594:85:0;;;23309:21:1;23366:2;23346:18;;;23339:30;23405:34;23385:18;;;23378:62;-1:-1:-1;;;23456:18:1;;;23449:39;23505:19;;31594:85:0;23125:405:1;31594:85:0;-1:-1:-1;;;;;31698:16:0;;31690:65;;;;-1:-1:-1;;;31690:65:0;;23737:2:1;31690:65:0;;;23719:21:1;23776:2;23756:18;;;23749:30;23815:34;23795:18;;;23788:62;-1:-1:-1;;;23866:18:1;;;23859:34;23910:19;;31690:65:0;23535:400:1;31690:65:0;31768:39;31789:4;31795:2;31799:7;31768:20;:39::i;:::-;31872:29;31889:1;31893:7;31872:8;:29::i;:::-;-1:-1:-1;;;;;31914:15:0;;;;;;:9;:15;;;;;:20;;31933:1;;31914:15;:20;;31933:1;;31914:20;:::i;:::-;;;;-1:-1:-1;;;;;;;31945:13:0;;;;;;:9;:13;;;;;:18;;31962:1;;31945:13;:18;;31962:1;;31945:18;:::i;:::-;;;;-1:-1:-1;;31974:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;31974:21:0;-1:-1:-1;;;;;31974:21:0;;;;;;;;;32013:27;;31974:16;;32013:27;;;;;;;31470:578;;;:::o;51437:173::-;51512:6;;;-1:-1:-1;;;;;51529:17:0;;;-1:-1:-1;;;;;;51529:17:0;;;;;;;51562:40;;51512:6;;;51529:17;51512:6;;51562:40;;51493:16;;51562:40;51482:128;51437:173;:::o;27556:315::-;27713:28;27723:4;27729:2;27733:7;27713:9;:28::i;:::-;27760:48;27783:4;27789:2;27793:7;27802:5;27760:22;:48::i;:::-;27752:111;;;;-1:-1:-1;;;27752:111:0;;;;;;;:::i;18295:723::-;18351:13;18572:10;18568:53;;-1:-1:-1;;18599:10:0;;;;;;;;;;;;-1:-1:-1;;;18599:10:0;;;;;18295:723::o;18568:53::-;18646:5;18631:12;18687:78;18694:9;;18687:78;;18720:8;;;;:::i;:::-;;-1:-1:-1;18743:10:0;;-1:-1:-1;18751:2:0;18743:10;;:::i;:::-;;;18687:78;;;18775:19;18807:6;18797:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18797:17:0;;18775:39;;18825:154;18832:10;;18825:154;;18859:11;18869:1;18859:11;;:::i;:::-;;-1:-1:-1;18928:10:0;18936:2;18928:5;:10;:::i;:::-;18915:24;;:2;:24;:::i;:::-;18902:39;;18885:6;18892;18885:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;18885:56:0;;;;;;;;-1:-1:-1;18956:11:0;18965:2;18956:11;;:::i;:::-;;;18825:154;;52801:1115;52900:7;52925:9;52945;52965:7;53028:3;:10;53042:2;53028:16;53024:68;;53077:1;53061:19;;;;;;;53024:68;-1:-1:-1;;;53395:2:0;53386:12;;53380:19;53433:2;53424:12;;53418:19;53479:2;53470:12;;53464:19;53461:1;53456:28;53607:2;53603:6;;53599:46;;;53626:7;53631:2;53626:7;;:::i;:::-;;;53599:46;53725:1;:7;;53730:2;53725:7;;:18;;;;;53736:1;:7;;53741:2;53736:7;;53725:18;53721:188;;;53776:1;53760:19;;;;;;;53721:188;53873:24;;;;;;;;;;;;24912:25:1;;;24985:4;24973:17;;24953:18;;;24946:45;;;;25007:18;;;25000:34;;;25050:18;;;25043:34;;;53873:24:0;;24884:19:1;;53873:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53866:31;;;;;;;22286:305;22388:4;-1:-1:-1;;;;;;22425:40:0;;-1:-1:-1;;;22425:40:0;;:105;;-1:-1:-1;;;;;;;22482:48:0;;-1:-1:-1;;;22482:48:0;22425:105;:158;;;-1:-1:-1;;;;;;;;;;20936:40:0;;;22547:36;20827:157;29505:321;29635:18;29641:2;29645:7;29635:5;:18::i;:::-;29686:54;29717:1;29721:2;29725:7;29734:5;29686:22;:54::i;:::-;29664:154;;;;-1:-1:-1;;;29664:154:0;;;;;;;:::i;63885:213::-;64042:48;64069:5;64076:3;64081:8;64042:26;:48::i;32905:799::-;33060:4;-1:-1:-1;;;;;33081:13:0;;10183:20;10231:8;33077:620;;33117:72;;-1:-1:-1;;;33117:72:0;;-1:-1:-1;;;;;33117:36:0;;;;;:72;;54383:10;;33168:4;;33174:7;;33183:5;;33117:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33117:72:0;;;;;;;;-1:-1:-1;;33117:72:0;;;;;;;;;;;;:::i;:::-;;;33113:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33359:13:0;;33355:272;;33402:60;;-1:-1:-1;;;33402:60:0;;;;;;;:::i;33355:272::-;33577:6;33571:13;33562:6;33558:2;33554:15;33547:38;33113:529;-1:-1:-1;;;;;;33240:51:0;-1:-1:-1;;;33240:51:0;;-1:-1:-1;33233:58:0;;33077:620;-1:-1:-1;33681:4:0;32905:799;;;;;;:::o;30162:382::-;-1:-1:-1;;;;;30242:16:0;;30234:61;;;;-1:-1:-1;;;30234:61:0;;26038:2:1;30234:61:0;;;26020:21:1;;;26057:18;;;26050:30;26116:34;26096:18;;;26089:62;26168:18;;30234:61:0;25836:356:1;30234:61:0;28249:4;28273:16;;;:7;:16;;;;;;-1:-1:-1;;;;;28273:16:0;:30;30306:58;;;;-1:-1:-1;;;30306:58:0;;26399:2:1;30306:58:0;;;26381:21:1;26438:2;26418:18;;;26411:30;26477;26457:18;;;26450:58;26525:18;;30306:58:0;26197:352:1;30306:58:0;30377:45;30406:1;30410:2;30414:7;30377:20;:45::i;:::-;-1:-1:-1;;;;;30435:13:0;;;;;;:9;:13;;;;;:18;;30452:1;;30435:13;:18;;30452:1;;30435:18;:::i;:::-;;;;-1:-1:-1;;30464:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;30464:21:0;-1:-1:-1;;;;;30464:21:0;;;;;;;;30503:33;;30464:16;;;30503:33;;30464:16;;30503:33;30162:382;;:::o;37956:589::-;-1:-1:-1;;;;;38162:18:0;;38158:187;;38197:40;38229:7;39372:10;:17;;39345:24;;;;:15;:24;;;;;:44;;;39400:24;;;;;;;;;;;;39268:164;38197:40;38158:187;;;38267:2;-1:-1:-1;;;;;38259:10:0;:4;-1:-1:-1;;;;;38259:10:0;;38255:90;;38286:47;38319:4;38325:7;38286:32;:47::i;:::-;-1:-1:-1;;;;;38359:16:0;;38355:183;;38392:45;38429:7;38392:36;:45::i;38355:183::-;38465:4;-1:-1:-1;;;;;38459:10:0;:2;-1:-1:-1;;;;;38459:10:0;;38455:83;;38486:40;38514:2;38518:7;38486:27;:40::i;40059:988::-;40325:22;40375:1;40350:22;40367:4;40350:16;:22::i;:::-;:26;;;;:::i;:::-;40387:18;40408:26;;;:17;:26;;;;;;40325:51;;-1:-1:-1;40541:28:0;;;40537:328;;-1:-1:-1;;;;;40608:18:0;;40586:19;40608:18;;;:12;:18;;;;;;;;:34;;;;;;;;;40659:30;;;;;;:44;;;40776:30;;:17;:30;;;;;:43;;;40537:328;-1:-1:-1;40961:26:0;;;;:17;:26;;;;;;;;40954:33;;;-1:-1:-1;;;;;41005:18:0;;;;;:12;:18;;;;;:34;;;;;;;40998:41;40059:988::o;41342:1079::-;41620:10;:17;41595:22;;41620:21;;41640:1;;41620:21;:::i;:::-;41652:18;41673:24;;;:15;:24;;;;;;42046:10;:26;;41595:46;;-1:-1:-1;41673:24:0;;41595:46;;42046:26;;;;;;:::i;:::-;;;;;;;;;42024:48;;42110:11;42085:10;42096;42085:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;42190:28;;;:15;:28;;;;;;;:41;;;42362:24;;;;;42355:31;42397:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;41413:1008;;;41342:1079;:::o;38846:221::-;38931:14;38948:20;38965:2;38948:16;:20::i;:::-;-1:-1:-1;;;;;38979:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39024:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;38846:221:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:1;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:1:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:1;;1343:180;-1:-1:-1;1343:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2173:367::-;2236:8;2246:6;2300:3;2293:4;2285:6;2281:17;2277:27;2267:55;;2318:1;2315;2308:12;2267:55;-1:-1:-1;2341:20:1;;2384:18;2373:30;;2370:50;;;2416:1;2413;2406:12;2370:50;2453:4;2445:6;2441:17;2429:29;;2513:3;2506:4;2496:6;2493:1;2489:14;2481:6;2477:27;2473:38;2470:47;2467:67;;;2530:1;2527;2520:12;2467:67;2173:367;;;;;:::o;2545:773::-;2667:6;2675;2683;2691;2744:2;2732:9;2723:7;2719:23;2715:32;2712:52;;;2760:1;2757;2750:12;2712:52;2800:9;2787:23;2829:18;2870:2;2862:6;2859:14;2856:34;;;2886:1;2883;2876:12;2856:34;2925:70;2987:7;2978:6;2967:9;2963:22;2925:70;:::i;:::-;3014:8;;-1:-1:-1;2899:96:1;-1:-1:-1;3102:2:1;3087:18;;3074:32;;-1:-1:-1;3118:16:1;;;3115:36;;;3147:1;3144;3137:12;3115:36;;3186:72;3250:7;3239:8;3228:9;3224:24;3186:72;:::i;:::-;2545:773;;;;-1:-1:-1;3277:8:1;-1:-1:-1;;;;2545:773:1:o;3323:127::-;3384:10;3379:3;3375:20;3372:1;3365:31;3415:4;3412:1;3405:15;3439:4;3436:1;3429:15;3455:718;3497:5;3550:3;3543:4;3535:6;3531:17;3527:27;3517:55;;3568:1;3565;3558:12;3517:55;3604:6;3591:20;3630:18;3667:2;3663;3660:10;3657:36;;;3673:18;;:::i;:::-;3748:2;3742:9;3716:2;3802:13;;-1:-1:-1;;3798:22:1;;;3822:2;3794:31;3790:40;3778:53;;;3846:18;;;3866:22;;;3843:46;3840:72;;;3892:18;;:::i;:::-;3932:10;3928:2;3921:22;3967:2;3959:6;3952:18;4013:3;4006:4;4001:2;3993:6;3989:15;3985:26;3982:35;3979:55;;;4030:1;4027;4020:12;3979:55;4094:2;4087:4;4079:6;4075:17;4068:4;4060:6;4056:17;4043:54;4141:1;4134:4;4129:2;4121:6;4117:15;4113:26;4106:37;4161:6;4152:15;;;;;;3455:718;;;;:::o;4178:388::-;4255:6;4263;4316:2;4304:9;4295:7;4291:23;4287:32;4284:52;;;4332:1;4329;4322:12;4284:52;4368:9;4355:23;4345:33;;4429:2;4418:9;4414:18;4401:32;4456:18;4448:6;4445:30;4442:50;;;4488:1;4485;4478:12;4442:50;4511:49;4552:7;4543:6;4532:9;4528:22;4511:49;:::i;:::-;4501:59;;;4178:388;;;;;:::o;4753:328::-;4830:6;4838;4846;4899:2;4887:9;4878:7;4874:23;4870:32;4867:52;;;4915:1;4912;4905:12;4867:52;4938:29;4957:9;4938:29;:::i;:::-;4928:39;;4986:38;5020:2;5009:9;5005:18;4986:38;:::i;:::-;4976:48;;5071:2;5060:9;5056:18;5043:32;5033:42;;4753:328;;;;;:::o;5268:186::-;5327:6;5380:2;5368:9;5359:7;5355:23;5351:32;5348:52;;;5396:1;5393;5386:12;5348:52;5419:29;5438:9;5419:29;:::i;5459:347::-;5524:6;5532;5585:2;5573:9;5564:7;5560:23;5556:32;5553:52;;;5601:1;5598;5591:12;5553:52;5624:29;5643:9;5624:29;:::i;:::-;5614:39;;5703:2;5692:9;5688:18;5675:32;5750:5;5743:13;5736:21;5729:5;5726:32;5716:60;;5772:1;5769;5762:12;5716:60;5795:5;5785:15;;;5459:347;;;;;:::o;5811:537::-;5906:6;5914;5922;5930;5983:3;5971:9;5962:7;5958:23;5954:33;5951:53;;;6000:1;5997;5990:12;5951:53;6023:29;6042:9;6023:29;:::i;:::-;6013:39;;6071:38;6105:2;6094:9;6090:18;6071:38;:::i;:::-;6061:48;;6156:2;6145:9;6141:18;6128:32;6118:42;;6211:2;6200:9;6196:18;6183:32;6238:18;6230:6;6227:30;6224:50;;;6270:1;6267;6260:12;6224:50;6293:49;6334:7;6325:6;6314:9;6310:22;6293:49;:::i;:::-;6283:59;;;5811:537;;;;;;;:::o;6353:260::-;6421:6;6429;6482:2;6470:9;6461:7;6457:23;6453:32;6450:52;;;6498:1;6495;6488:12;6450:52;6521:29;6540:9;6521:29;:::i;:::-;6511:39;;6569:38;6603:2;6592:9;6588:18;6569:38;:::i;:::-;6559:48;;6353:260;;;;;:::o;6618:320::-;6686:6;6739:2;6727:9;6718:7;6714:23;6710:32;6707:52;;;6755:1;6752;6745:12;6707:52;6795:9;6782:23;6828:18;6820:6;6817:30;6814:50;;;6860:1;6857;6850:12;6814:50;6883:49;6924:7;6915:6;6904:9;6900:22;6883:49;:::i;6943:380::-;7022:1;7018:12;;;;7065;;;7086:61;;7140:4;7132:6;7128:17;7118:27;;7086:61;7193:2;7185:6;7182:14;7162:18;7159:38;7156:161;;;7239:10;7234:3;7230:20;7227:1;7220:31;7274:4;7271:1;7264:15;7302:4;7299:1;7292:15;7156:161;;6943:380;;;:::o;8568:356::-;8770:2;8752:21;;;8789:18;;;8782:30;8848:34;8843:2;8828:18;;8821:62;8915:2;8900:18;;8568:356::o;9743:127::-;9804:10;9799:3;9795:20;9792:1;9785:31;9835:4;9832:1;9825:15;9859:4;9856:1;9849:15;9875:127;9936:10;9931:3;9927:20;9924:1;9917:31;9967:4;9964:1;9957:15;9991:4;9988:1;9981:15;10007:128;10047:3;10078:1;10074:6;10071:1;10068:13;10065:39;;;10084:18;;:::i;:::-;-1:-1:-1;10120:9:1;;10007:128::o;10140:135::-;10179:3;-1:-1:-1;;10200:17:1;;10197:43;;;10220:18;;:::i;:::-;-1:-1:-1;10267:1:1;10256:13;;10140:135::o;11859:403::-;12061:2;12043:21;;;12100:2;12080:18;;;12073:30;12139:34;12134:2;12119:18;;12112:62;-1:-1:-1;;;12205:2:1;12190:18;;12183:37;12252:3;12237:19;;11859:403::o;12627:125::-;12667:4;12695:1;12692;12689:8;12686:34;;;12700:18;;:::i;:::-;-1:-1:-1;12737:9:1;;12627:125::o;12757:413::-;12959:2;12941:21;;;12998:2;12978:18;;;12971:30;13037:34;13032:2;13017:18;;13010:62;-1:-1:-1;;;13103:2:1;13088:18;;13081:47;13160:3;13145:19;;12757:413::o;14182:168::-;14222:7;14288:1;14284;14280:6;14276:14;14273:1;14270:21;14265:1;14258:9;14251:17;14247:45;14244:71;;;14295:18;;:::i;:::-;-1:-1:-1;14335:9:1;;14182:168::o;14355:127::-;14416:10;14411:3;14407:20;14404:1;14397:31;14447:4;14444:1;14437:15;14471:4;14468:1;14461:15;14487:120;14527:1;14553;14543:35;;14558:18;;:::i;:::-;-1:-1:-1;14592:9:1;;14487:120::o;21663:637::-;21943:3;21981:6;21975:13;21997:53;22043:6;22038:3;22031:4;22023:6;22019:17;21997:53;:::i;:::-;22113:13;;22072:16;;;;22135:57;22113:13;22072:16;22169:4;22157:17;;22135:57;:::i;:::-;-1:-1:-1;;;22214:20:1;;22243:22;;;22292:1;22281:13;;21663:637;-1:-1:-1;;;;21663:637:1:o;23940:414::-;24142:2;24124:21;;;24181:2;24161:18;;;24154:30;24220:34;24215:2;24200:18;;24193:62;-1:-1:-1;;;24286:2:1;24271:18;;24264:48;24344:3;24329:19;;23940:414::o;24359:112::-;24391:1;24417;24407:35;;24422:18;;:::i;:::-;-1:-1:-1;24456:9:1;;24359:112::o;24476:204::-;24514:3;24550:4;24547:1;24543:12;24582:4;24579:1;24575:12;24617:3;24611:4;24607:14;24602:3;24599:23;24596:49;;;24625:18;;:::i;:::-;24661:13;;24476:204;-1:-1:-1;;;24476:204:1:o;25088:489::-;-1:-1:-1;;;;;25357:15:1;;;25339:34;;25409:15;;25404:2;25389:18;;25382:43;25456:2;25441:18;;25434:34;;;25504:3;25499:2;25484:18;;25477:31;;;25282:4;;25525:46;;25551:19;;25543:6;25525:46;:::i;:::-;25517:54;25088:489;-1:-1:-1;;;;;;25088:489:1:o;25582:249::-;25651:6;25704:2;25692:9;25683:7;25679:23;25675:32;25672:52;;;25720:1;25717;25710:12;25672:52;25752:9;25746:16;25771:30;25795:5;25771:30;:::i;26554:127::-;26615:10;26610:3;26606:20;26603:1;26596:31;26646:4;26643:1;26636:15;26670:4;26667:1;26660:15

Swarm Source

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