Contract 0xc56F1FedE723F74F8C9508763c64De52685ffB59 1

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0xc3515634ca08b3f73b59b625e915a6da893ac99daecabcf1d8e0932af0b5d4fc0x60806040127297932022-08-06 0:52:2454 days 14 hrs ago0xa319bf12a9b89699379411043a3099e74cf0000c IN  Contract Creation0 Ether0.0054571 1.20999998
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x57e2a44caf859643767b47f666c2ec50c61258ec

Contract Name:
Chloe

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, BSD-3-Clause license

Contract Source Code (Solidity Multiple files format)

File 2 of 19: chloe.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "./ERC721MetadataEnumerable.sol";
import "./Freezable.sol";
import "./Describable.sol";

contract Chloe is
  ERC721MetadataEnumerable,
  Freezable,
  Describable
{

  constructor(string memory name, string memory symbol, string memory description, address to, string memory uri) public {
    nftName = name;
    nftSymbol = symbol;
    _setupDescription(description);
    _freeze(msg.sender, false);
    if (to != address(0)) {
      _freeze(to, false);
      mint(to, 1, uri);
    }
  }

  function mint(address to, uint256 tokenId, string memory uri) public onlyOwner {
    super._mint(to, tokenId);
    super._setTokenUri(tokenId, uri);
  }

  function burn(uint256 tokenId) external onlyOwner {
    super._burn(tokenId);
  }

  function _beforeTokenTransfer(address from, address to, uint256) internal override whenTransfer(from, to) {
  }

  function unfreezeAndMint(address recipient, uint256 tokenId, string calldata uri) public onlyOwner {
      unfreeze(recipient);
      mint(recipient, tokenId, uri);
  }

  function unfreezeAndTransfer(address recipient) public onlyOwner {
      unfreeze(recipient);
      super._transfer(recipient, 1);
  }
}

File 1 of 19: Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.2;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

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

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

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

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

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

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

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

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

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

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

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

File 3 of 19: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

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

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

File 4 of 19: Describable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

contract Describable {
    string private _description;

    function _setupDescription(string memory description) internal {
        _description = description;
    }

    function description() public view returns (string memory) {
        return _description;
    }
}

File 5 of 19: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

import "./Context.sol";
import "./IERC20.sol";
import "./SafeMath.sol";
import "./Address.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;
    using Address for address;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount) internal virtual { }
}

File 6 of 19: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Souce: https://github.com/0xcert/ethereum-erc721/

import "./IERC721.sol";
import "./SafeMath.sol";
import "./IERC721TokenReceiver.sol";
import "./SupportsInterface.sol";
import "./Address.sol";

/**
 * @dev Implementation of ERC-721 non-fungible token standard.
 */
contract ERC721 is
  IERC721,
  SupportsInterface
{
  using SafeMath for uint256;
  using Address for address;

  /**
   * @dev List of revert message codes. Implementing dApp should handle showing the correct message.
   * Based on 0xcert framework error codes.
   */
  string constant ZERO_ADDRESS = "003001";
  string constant NOT_VALID_NFT = "003002";
  string constant NOT_OWNER_OR_OPERATOR = "003003";
  string constant NOT_OWNER_APPROWED_OR_OPERATOR = "003004";
  string constant NOT_ABLE_TO_RECEIVE_NFT = "003005";
  string constant NFT_ALREADY_EXISTS = "003006";
  string constant NOT_OWNER = "003007";
  string constant IS_OWNER = "003008";

  /**
   * @dev Magic value of a smart contract that can recieve NFT.
   * Equal to: bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")).
   */
  bytes4 internal constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02;

  /**
   * @dev A mapping from NFT ID to the address that owns it.
   */
  mapping (uint256 => address) internal idToOwner;

  /**
   * @dev Mapping from NFT ID to approved address.
   */
  mapping (uint256 => address) internal idToApproval;

   /**
   * @dev Mapping from owner address to count of his tokens.
   */
  mapping (address => uint256) private ownerToNFTokenCount;

  /**
   * @dev Mapping from owner address to mapping of operator addresses.
   */
  mapping (address => mapping (address => bool)) internal ownerToOperators;

  /**
   * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are
   * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any
   * number of NFTs may be created and assigned without emitting Transfer. At the time of any
   * transfer, the approved address for that NFT (if any) is reset to none.
   * @param _from Sender of NFT (if address is zero address it indicates token creation).
   * @param _to Receiver of NFT (if address is zero address it indicates token destruction).
   * @param _tokenId The NFT that got transfered.
   */
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 indexed _tokenId
  );

  /**
   * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero
   * address indicates there is no approved address. When a Transfer event emits, this also
   * indicates that the approved address for that NFT (if any) is reset to none.
   * @param _owner Owner of NFT.
   * @param _approved Address that we are approving.
   * @param _tokenId NFT which we are approving.
   */
  event Approval(
    address indexed _owner,
    address indexed _approved,
    uint256 indexed _tokenId
  );

  /**
   * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage
   * all NFTs of the owner.
   * @param _owner Owner of NFT.
   * @param _operator Address to which we are setting operator rights.
   * @param _approved Status of operator rights(true if operator rights are given and false if
   * revoked).
   */
  event ApprovalForAll(
    address indexed _owner,
    address indexed _operator,
    bool _approved
  );

  /**
   * @dev Guarantees that the msg.sender is an owner or operator of the given NFT.
   * @param _tokenId ID of the NFT to validate.
   */
  modifier canOperate(
    uint256 _tokenId
  )
  {
    address tokenOwner = idToOwner[_tokenId];
    require(tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender], NOT_OWNER_OR_OPERATOR);
    _;
  }

  /**
   * @dev Guarantees that the msg.sender is allowed to transfer NFT.
   * @param _tokenId ID of the NFT to transfer.
   */
  modifier canTransfer(
    uint256 _tokenId
  )
  {
    address tokenOwner = idToOwner[_tokenId];
    require(
      tokenOwner == msg.sender
      || idToApproval[_tokenId] == msg.sender
      || ownerToOperators[tokenOwner][msg.sender],
      NOT_OWNER_APPROWED_OR_OPERATOR
    );
    _;
  }

  /**
   * @dev Guarantees that _tokenId is a valid Token.
   * @param _tokenId ID of the NFT to validate.
   */
  modifier validNFToken(
    uint256 _tokenId
  )
  {
    require(idToOwner[_tokenId] != address(0), NOT_VALID_NFT);
    _;
  }

  /**
   * @dev Contract constructor.
   */
  constructor()
    public
  {
    supportedInterfaces[0x80ac58cd] = true; // ERC721
  }

  /**
   * @dev Transfers the ownership of an NFT from one address to another address. This function can
   * be changed to payable.
   * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the
   * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is
   * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this
   * function checks if `_to` is a smart contract (code size > 0). If so, it calls
   * `onERC721Received` on `_to` and throws if the return value is not
   * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   * @param _data Additional data with no specified format, sent in call to `_to`.
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes calldata _data
  )
    external
    override
  {
    _safeTransferFrom(_from, _to, _tokenId, _data);
  }

  /**
   * @dev Transfers the ownership of an NFT from one address to another address. This function can
   * be changed to payable.
   * @notice This works identically to the other function with an extra data parameter, except this
   * function just sets data to ""
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external
    override
  {
    _safeTransferFrom(_from, _to, _tokenId, "");
  }

  /**
   * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved
   * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero
   * address. Throws if `_tokenId` is not a valid NFT. This function can be changed to payable.
   * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else
   * they maybe be permanently lost.
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external
    override
    canTransfer(_tokenId)
    validNFToken(_tokenId)
  {
    address tokenOwner = idToOwner[_tokenId];
    require(tokenOwner == _from, NOT_OWNER);

    _transfer(_to, _tokenId);
  }

  /**
   * @dev Set or reaffirm the approved address for an NFT. This function can be changed to payable.
   * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is
   * the current NFT owner, or an authorized operator of the current owner.
   * @param _approved Address to be approved for the given NFT ID.
   * @param _tokenId ID of the token to be approved.
   */
  function approve(
    address _approved,
    uint256 _tokenId
  )
    external
    override
    canOperate(_tokenId)
    validNFToken(_tokenId)
  {
    address tokenOwner = idToOwner[_tokenId];
    require(_approved != tokenOwner, IS_OWNER);

    idToApproval[_tokenId] = _approved;
    emit Approval(tokenOwner, _approved, _tokenId);
  }

  /**
   * @dev Enables or disables approval for a third party ("operator") to manage all of
   * `msg.sender`'s assets. It also emits the ApprovalForAll event.
   * @notice This works even if sender doesn't own any tokens at the time.
   * @param _operator Address to add to the set of authorized operators.
   * @param _approved True if the operators is approved, false to revoke approval.
   */
  function setApprovalForAll(
    address _operator,
    bool _approved
  )
    external
    override
  {
    ownerToOperators[msg.sender][_operator] = _approved;
    emit ApprovalForAll(msg.sender, _operator, _approved);
  }

  /**
   * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are
   * considered invalid, and this function throws for queries about the zero address.
   * @param _owner Address for whom to query the balance.
   * @return Balance of _owner.
   */
  function balanceOf(
    address _owner
  )
    external
    override
    view
    returns (uint256)
  {
    require(_owner != address(0), ZERO_ADDRESS);
    return _getOwnerNFTCount(_owner);
  }

  /**
   * @dev Returns the address of the owner of the NFT. NFTs assigned to zero address are considered
   * invalid, and queries about them do throw.
   * @param _tokenId The identifier for an NFT.
   * @return _owner Address of _tokenId owner.
   */
  function ownerOf(
    uint256 _tokenId
  )
    external
    override
    view
    returns (address _owner)
  {
    _owner = idToOwner[_tokenId];
    require(_owner != address(0), NOT_VALID_NFT);
  }

  /**
   * @dev Get the approved address for a single NFT.
   * @notice Throws if `_tokenId` is not a valid NFT.
   * @param _tokenId ID of the NFT to query the approval of.
   * @return Address that _tokenId is approved for.
   */
  function getApproved(
    uint256 _tokenId
  )
    external
    override
    view
    validNFToken(_tokenId)
    returns (address)
  {
    return idToApproval[_tokenId];
  }

  /**
   * @dev Checks if `_operator` is an approved operator for `_owner`.
   * @param _owner The address that owns the NFTs.
   * @param _operator The address that acts on behalf of the owner.
   * @return True if approved for all, false otherwise.
   */
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    external
    override
    view
    returns (bool)
  {
    return ownerToOperators[_owner][_operator];
  }

  /**
   * @dev Actually preforms the transfer.
   * @notice Does NO checks.
   * @param _to Address of a new owner.
   * @param _tokenId The NFT that is being transferred.
   */
  function _transfer(
    address _to,
    uint256 _tokenId
  )
    internal
  {
    address from = idToOwner[_tokenId];
    _clearApproval(_tokenId);

    _beforeTokenTransfer(from, _to, _tokenId);

    _removeNFToken(from, _tokenId);
    _addNFToken(_to, _tokenId);

    emit Transfer(from, _to, _tokenId);
  }

  /**
   * @dev Mints a new NFT.
   * @notice This is an internal function which should be called from user-implemented external
   * mint function. Its purpose is to show and properly initialize data structures when using this
   * implementation.
   * @param _to The address that will own the minted NFT.
   * @param _tokenId of the NFT to be minted by the msg.sender.
   */
  function _mint(
    address _to,
    uint256 _tokenId
  )
    internal
    virtual
  {
    require(_to != address(0), ZERO_ADDRESS);
    require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS);

    _addNFToken(_to, _tokenId);
    _beforeTokenTransfer(msg.sender, _to, _tokenId);

    emit Transfer(address(0), _to, _tokenId);
  }

  /**
   * @dev Burns a NFT.
   * @notice This is an internal function which should be called from user-implemented external burn
   * function. Its purpose is to show and properly initialize data structures when using this
   * implementation. Also, note that this burn implementation allows the minter to re-mint a burned
   * NFT.
   * @param _tokenId ID of the NFT to be burned.
   */
  function _burn(
    uint256 _tokenId
  )
    internal
    virtual
    validNFToken(_tokenId)
  {
    address tokenOwner = idToOwner[_tokenId];
    _clearApproval(_tokenId);
    _removeNFToken(tokenOwner, _tokenId);
    emit Transfer(tokenOwner, address(0), _tokenId);
  }

  /**
   * @dev Removes a NFT from owner.
   * @notice Use and override this function with caution. Wrong usage can have serious consequences.
   * @param _from Address from wich we want to remove the NFT.
   * @param _tokenId Which NFT we want to remove.
   */
  function _removeNFToken(
    address _from,
    uint256 _tokenId
  )
    internal
    virtual
  {
    require(idToOwner[_tokenId] == _from, NOT_OWNER);
    ownerToNFTokenCount[_from] = ownerToNFTokenCount[_from] - 1;
    delete idToOwner[_tokenId];
  }

  /**
   * @dev Assignes a new NFT to owner.
   * @notice Use and override this function with caution. Wrong usage can have serious consequences.
   * @param _to Address to wich we want to add the NFT.
   * @param _tokenId Which NFT we want to add.
   */
  function _addNFToken(
    address _to,
    uint256 _tokenId
  )
    internal
    virtual
  {
    require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS);

    idToOwner[_tokenId] = _to;
    ownerToNFTokenCount[_to] = ownerToNFTokenCount[_to].add(1);
  }

  /**
   * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable
   * extension to remove double storage (gas optimization) of owner nft count.
   * @param _owner Address for whom to query the count.
   * @return Number of _owner NFTs.
   */
  function _getOwnerNFTCount(
    address _owner
  )
    internal
    virtual
    view
    returns (uint256)
  {
    return ownerToNFTokenCount[_owner];
  }

  /**
   * @dev Actually perform the safeTransferFrom.
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   * @param _data Additional data with no specified format, sent in call to `_to`.
   */
  function _safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes memory _data
  )
    private
    canTransfer(_tokenId)
    validNFToken(_tokenId)
  {
    address tokenOwner = idToOwner[_tokenId];
    require(tokenOwner == _from, NOT_OWNER);
    require(_to != address(0), ZERO_ADDRESS);

    _transfer(_to, _tokenId);

    if (_to.isContract())
    {
      bytes4 retval = IERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
      require(retval == MAGIC_ON_ERC721_RECEIVED, NOT_ABLE_TO_RECEIVE_NFT);
    }
  }

  /**
   * @dev Clears the current approval of a given NFT ID.
   * @param _tokenId ID of the NFT to be transferred.
   */
  function _clearApproval(
    uint256 _tokenId
  )
    private
  {
    if (idToApproval[_tokenId] != address(0))
    {
      delete idToApproval[_tokenId];
    }
  }

  /**
   * @dev Hook that is called before any transfer of tokens. This includes
   * minting and burning.
   *
   * Calling conditions:
   *
   * - when `from` and `to` are both non-zero, `tokenId` of ``from``'s tokens
   * will be to transferred to `to`.
   * - when `from` is zero, `amount` tokens will be minted for `to`.
   * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
   * - `from` and `to` are never both zero.
   *
   */
  function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
}

File 7 of 19: ERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Souce: https://github.com/0xcert/ethereum-erc721/

import "./ERC721.sol";
import "./IERC721Metadata.sol";

/**
 * @dev Optional metadata implementation for ERC-721 non-fungible token standard.
 */
contract ERC721Metadata is
  ERC721,
  IERC721Metadata
{

  /**
   * @dev A descriptive name for a collection of NFTs.
   */
  string internal nftName;

  /**
   * @dev An abbreviated name for NFTokens.
   */
  string internal nftSymbol;

  /**
   * @dev Mapping from NFT ID to metadata uri.
   */
  mapping (uint256 => string) internal idToUri;

  /**
   * @dev Contract constructor.
   * @notice When implementing this contract don't forget to set nftName and nftSymbol.
   */
  constructor()
    public
  {
    supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata
  }

  /**
   * @dev Returns a descriptive name for a collection of NFTokens.
   * @return _name Representing name.
   */
  function name()
    external
    override
    view
    returns (string memory _name)
  {
    _name = nftName;
  }

  /**
   * @dev Returns an abbreviated name for NFTokens.
   * @return _symbol Representing symbol.
   */
  function symbol()
    external
    override
    view
    returns (string memory _symbol)
  {
    _symbol = nftSymbol;
  }

  /**
   * @dev A distinct URI (RFC 3986) for a given NFT.
   * @param _tokenId Id for which we want uri.
   * @return URI of _tokenId.
   */
  function tokenURI(
    uint256 _tokenId
  )
    external
    override
    view
    validNFToken(_tokenId)
    returns (string memory)
  {
    return idToUri[_tokenId];
  }

  /**
   * @dev Burns a NFT.
   * @notice This is an internal function which should be called from user-implemented external
   * burn function. Its purpose is to show and properly initialize data structures when using this
   * implementation. Also, note that this burn implementation allows the minter to re-mint a burned
   * NFT.
   * @param _tokenId ID of the NFT to be burned.
   */
  function _burn(
    uint256 _tokenId
  )
    internal
    override
    virtual
  {
    super._burn(_tokenId);

    if (bytes(idToUri[_tokenId]).length != 0)
    {
      delete idToUri[_tokenId];
    }
  }

  /**
   * @dev Set a distinct URI (RFC 3986) for a given NFT ID.
   * @notice This is an internal function which should be called from user-implemented external
   * function. Its purpose is to show and properly initialize data structures when using this
   * implementation.
   * @param _tokenId Id for which we want URI.
   * @param _uri String representing RFC 3986 URI.
   */
  function _setTokenUri(
    uint256 _tokenId,
    string memory _uri
  )
    internal
    validNFToken(_tokenId)
  {
    idToUri[_tokenId] = _uri;
  }

}

File 8 of 19: ERC721MetadataEnumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Souce: https://github.com/0xcert/ethereum-erc721/

import "./ERC721Metadata.sol";
import "./IERC721Enumerable.sol";

/**
 * @dev Optional enumeration implementation for ERC-721 non-fungible token standard.
 */
contract ERC721MetadataEnumerable is
  ERC721Metadata,
  IERC721Enumerable
{

  /**
   * @dev List of revert message codes. Implementing dApp should handle showing
   * the correct message. Based on 0xcert framework error codes.
   */
  string constant INVALID_INDEX = "005007";

  /**
   * @dev Array of all NFT IDs.
   */
  uint256[] internal tokens;

  /**
   * @dev Mapping from token ID to its index in global tokens array.
   */
  mapping(uint256 => uint256) internal idToIndex;

  /**
   * @dev Mapping from owner to list of owned NFT IDs.
   */
  mapping(address => uint256[]) internal ownerToIds;

  /**
   * @dev Mapping from NFT ID to its index in the owner tokens list.
   */
  mapping(uint256 => uint256) internal idToOwnerIndex;

  /**
   * @dev Contract constructor.
   */
  constructor()
    public
  {
    supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable
  }

  /**
   * @dev Returns the count of all existing NFTokens.
   * @return Total supply of NFTs.
   */
  function totalSupply()
    external
    override
    view
    returns (uint256)
  {
    return tokens.length;
  }

  /**
   * @dev Returns NFT ID by its index.
   * @param _index A counter less than `totalSupply()`.
   * @return Token id.
   */
  function tokenByIndex(
    uint256 _index
  )
    external
    override
    view
    returns (uint256)
  {
    require(_index < tokens.length, INVALID_INDEX);
    return tokens[_index];
  }

  /**
   * @dev returns the n-th NFT ID from a list of owner's tokens.
   * @param _owner Token owner's address.
   * @param _index Index number representing n-th token in owner's list of tokens.
   * @return Token id.
   */
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    external
    override
    view
    returns (uint256)
  {
    require(_index < ownerToIds[_owner].length, INVALID_INDEX);
    return ownerToIds[_owner][_index];
  }

  /**
   * @dev Mints a new NFT.
   * @notice This is an internal function which should be called from user-implemented external
   * mint function. Its purpose is to show and properly initialize data structures when using this
   * implementation.
   * @param _to The address that will own the minted NFT.
   * @param _tokenId of the NFT to be minted by the msg.sender.
   */
  function _mint(
    address _to,
    uint256 _tokenId
  )
    internal
    override
    virtual
  {
    super._mint(_to, _tokenId);
    tokens.push(_tokenId);
    idToIndex[_tokenId] = tokens.length - 1;
  }

  /**
   * @dev Burns a NFT.
   * @notice This is an internal function which should be called from user-implemented external
   * burn function. Its purpose is to show and properly initialize data structures when using this
   * implementation. Also, note that this burn implementation allows the minter to re-mint a burned
   * NFT.
   * @param _tokenId ID of the NFT to be burned.
   */
  function _burn(
    uint256 _tokenId
  )
    internal
    override
    virtual
  {
    super._burn(_tokenId);

    uint256 tokenIndex = idToIndex[_tokenId];
    uint256 lastTokenIndex = tokens.length - 1;
    uint256 lastToken = tokens[lastTokenIndex];

    tokens[tokenIndex] = lastToken;

    tokens.pop();
    // This wastes gas if you are burning the last token but saves a little gas if you are not.
    idToIndex[lastToken] = tokenIndex;
    idToIndex[_tokenId] = 0;
  }

  /**
   * @dev Removes a NFT from an address.
   * @notice Use and override this function with caution. Wrong usage can have serious consequences.
   * @param _from Address from wich we want to remove the NFT.
   * @param _tokenId Which NFT we want to remove.
   */
  function _removeNFToken(
    address _from,
    uint256 _tokenId
  )
    internal
    override
    virtual
  {
    require(idToOwner[_tokenId] == _from, NOT_OWNER);
    delete idToOwner[_tokenId];

    uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
    uint256 lastTokenIndex = ownerToIds[_from].length - 1;

    if (lastTokenIndex != tokenToRemoveIndex)
    {
      uint256 lastToken = ownerToIds[_from][lastTokenIndex];
      ownerToIds[_from][tokenToRemoveIndex] = lastToken;
      idToOwnerIndex[lastToken] = tokenToRemoveIndex;
    }

    ownerToIds[_from].pop();
  }

  /**
   * @dev Assignes a new NFT to an address.
   * @notice Use and override this function with caution. Wrong usage can have serious consequences.
   * @param _to Address to wich we want to add the NFT.
   * @param _tokenId Which NFT we want to add.
   */
  function _addNFToken(
    address _to,
    uint256 _tokenId
  )
    internal
    override
    virtual
  {
    require(idToOwner[_tokenId] == address(0), NFT_ALREADY_EXISTS);
    idToOwner[_tokenId] = _to;

    ownerToIds[_to].push(_tokenId);
    idToOwnerIndex[_tokenId] = ownerToIds[_to].length - 1;
  }

  /**
   * @dev Helper function that gets NFT count of owner. This is needed for overriding in enumerable
   * extension to remove double storage(gas optimization) of owner nft count.
   * @param _owner Address for whom to query the count.
   * @return Number of _owner NFTs.
   */
  function _getOwnerNFTCount(
    address _owner
  )
    internal
    override
    virtual
    view
    returns (uint256)
  {
    return ownerToIds[_owner].length;
  }
}

File 9 of 19: Freezable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

import "./Pausable.sol";

contract Freezable is Pausable {
    mapping (address => bool) unfrozenAccounts;

    event Freeze(address indexed account);
    event Unfreeze(address indexed account);
    event NotFreezable();

    bool public canFreeze = true;

    function _frozen(address account) internal view returns (bool) {
        return canFreeze && !unfrozenAccounts[account];
    }

    function _freeze(address account, bool frozen) internal {
        unfrozenAccounts[account] = !frozen;
    }

    modifier whenUnfrozen(address account) {
        require(!_frozen(account), "account is frozen");
        _;
    }

    function frozen(address account) public view returns (bool) {
        return _frozen(account);
    }

    function freeze(address account) public onlyOwner {
        _freeze(account, true);
        emit Freeze(account);
    }

    function unfreeze(address account) public onlyOwner {
        _freeze(account, false);
        emit Unfreeze(account);
    }

    function _beforeTransfer(address from, address to) internal whenNotPaused whenUnfrozen(from) whenUnfrozen(to) {
    }

    modifier whenTransfer(address from, address to) {
        _beforeTransfer(from, to);
	_;
    }

    function notFreezable() onlyOwner public {
        canFreeze = false;
        emit NotFreezable();
    }
}

File 10 of 19: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/0xcert/ethereum-erc721/

/**
 * @dev A standard for detecting smart contract interfaces.
 * See: https://eips.ethereum.org/EIPS/eip-165.
 */
interface IERC165
{

  /**
   * @dev Checks if the smart contract includes a specific interface.
   * @notice This function uses less than 30,000 gas.
   * @param _interfaceID The interface identifier, as specified in ERC-165.
   * @return True if _interfaceID is supported, false otherwise.
   */
  function supportsInterface(
    bytes4 _interfaceID
  )
    external
    view
    returns (bool);

}

File 11 of 19: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

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

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

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

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

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

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

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

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

File 12 of 19: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/0xcert/ethereum-erc721/

/**
 * @dev IERC-721 non-fungible token standard.
 * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md.
 */
interface IERC721
{

  /**
   * @dev Emits when ownership of any NFT changes by any mechanism. This event emits when NFTs are
   * created (`from` == 0) and destroyed (`to` == 0). Exception: during contract creation, any
   * number of NFTs may be created and assigned without emitting Transfer. At the time of any
   * transfer, the approved address for that NFT (if any) is reset to none.
   */
  event Transfer(
    address indexed _from,
    address indexed _to,
    uint256 indexed _tokenId
  );

  /**
   * @dev This emits when the approved address for an NFT is changed or reaffirmed. The zero
   * address indicates there is no approved address. When a Transfer event emits, this also
   * indicates that the approved address for that NFT (if any) is reset to none.
   */
  event Approval(
    address indexed _owner,
    address indexed _approved,
    uint256 indexed _tokenId
  );

  /**
   * @dev This emits when an operator is enabled or disabled for an owner. The operator can manage
   * all NFTs of the owner.
   */
  event ApprovalForAll(
    address indexed _owner,
    address indexed _operator,
    bool _approved
  );

  /**
   * @dev Transfers the ownership of an NFT from one address to another address.
   * @notice Throws unless `msg.sender` is the current owner, an authorized operator, or the
   * approved address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is
   * the zero address. Throws if `_tokenId` is not a valid NFT. When transfer is complete, this
   * function checks if `_to` is a smart contract (code size > 0). If so, it calls
   * `onERC721Received` on `_to` and throws if the return value is not
   * `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   * @param _data Additional data with no specified format, sent in call to `_to`.
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId,
    bytes calldata _data
  )
    external;

  /**
   * @dev Transfers the ownership of an NFT from one address to another address.
   * @notice This works identically to the other function with an extra data parameter, except this
   * function just sets data to ""
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   */
  function safeTransferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external;

  /**
   * @dev Throws unless `msg.sender` is the current owner, an authorized operator, or the approved
   * address for this NFT. Throws if `_from` is not the current owner. Throws if `_to` is the zero
   * address. Throws if `_tokenId` is not a valid NFT.
   * @notice The caller is responsible to confirm that `_to` is capable of receiving NFTs or else
   * they mayb be permanently lost.
   * @param _from The current owner of the NFT.
   * @param _to The new owner.
   * @param _tokenId The NFT to transfer.
   */
  function transferFrom(
    address _from,
    address _to,
    uint256 _tokenId
  )
    external;

  /**
   * @dev Set or reaffirm the approved address for an NFT.
   * @notice The zero address indicates there is no approved address. Throws unless `msg.sender` is
   * the current NFT owner, or an authorized operator of the current owner.
   * @param _approved The new approved NFT controller.
   * @param _tokenId The NFT to approve.
   */
  function approve(
    address _approved,
    uint256 _tokenId
  )
    external;

  /**
   * @dev Enables or disables approval for a third party ("operator") to manage all of
   * `msg.sender`'s assets. It also emits the ApprovalForAll event.
   * @notice The contract MUST allow multiple operators per owner.
   * @param _operator Address to add to the set of authorized operators.
   * @param _approved True if the operators is approved, false to revoke approval.
   */
  function setApprovalForAll(
    address _operator,
    bool _approved
  )
    external;

  /**
   * @dev Returns the number of NFTs owned by `_owner`. NFTs assigned to the zero address are
   * considered invalid, and this function throws for queries about the zero address.
   * @param _owner Address for whom to query the balance.
   * @return Balance of _owner.
   */
  function balanceOf(
    address _owner
  )
    external
    view
    returns (uint256);

  /**
   * @dev Returns the address of the owner of the NFT. NFTs assigned to zero address are considered
   * invalid, and queries about them do throw.
   * @param _tokenId The identifier for an NFT.
   * @return Address of _tokenId owner.
   */
  function ownerOf(
    uint256 _tokenId
  )
    external
    view
    returns (address);

  /**
   * @dev Get the approved address for a single NFT.
   * @notice Throws if `_tokenId` is not a valid NFT.
   * @param _tokenId The NFT to find the approved address for.
   * @return Address that _tokenId is approved for.
   */
  function getApproved(
    uint256 _tokenId
  )
    external
    view
    returns (address);

  /**
   * @dev Returns true if `_operator` is an approved operator for `_owner`, false otherwise.
   * @param _owner The address that owns the NFTs.
   * @param _operator The address that acts on behalf of the owner.
   * @return True if approved for all, false otherwise.
   */
  function isApprovedForAll(
    address _owner,
    address _operator
  )
    external
    view
    returns (bool);

}

File 13 of 19: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/0xcert/ethereum-erc721/

/**
 * @dev Optional enumeration extension for ERC-721 non-fungible token standard.
 * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md.
 */
interface IERC721Enumerable
{

  /**
   * @dev Returns a count of valid NFTs tracked by this contract, where each one of them has an
   * assigned and queryable owner not equal to the zero address.
   * @return Total supply of NFTs.
   */
  function totalSupply()
    external
    view
    returns (uint256);

  /**
   * @dev Returns the token identifier for the `_index`th NFT. Sort order is not specified.
   * @param _index A counter less than `totalSupply()`.
   * @return Token id.
   */
  function tokenByIndex(
    uint256 _index
  )
    external
    view
    returns (uint256);

  /**
   * @dev Returns the token identifier for the `_index`th NFT assigned to `_owner`. Sort order is
   * not specified. It throws if `_index` >= `balanceOf(_owner)` or if `_owner` is the zero address,
   * representing invalid NFTs.
   * @param _owner An address where we are interested in NFTs owned by them.
   * @param _index A counter less than `balanceOf(_owner)`.
   * @return Token id.
   */
  function tokenOfOwnerByIndex(
    address _owner,
    uint256 _index
  )
    external
    view
    returns (uint256);

}

File 14 of 19: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Souce: https://github.com/0xcert/ethereum-erc721/

/**
 * @dev Optional metadata extension for ERC-721 non-fungible token standard.
 * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md.
 */
interface IERC721Metadata
{

  /**
   * @dev Returns a descriptive name for a collection of NFTs in this contract.
   * @return _name Representing name.
   */
  function name()
    external
    view
    returns (string memory _name);

  /**
   * @dev Returns a abbreviated name for a collection of NFTs in this contract.
   * @return _symbol Representing symbol.
   */
  function symbol()
    external
    view
    returns (string memory _symbol);

  /**
   * @dev Returns a distinct Uniform Resource Identifier (URI) for a given asset. It Throws if
   * `_tokenId` is not a valid NFT. URIs are defined in RFC3986. The URI may point to a JSON file
   * that conforms to the "ERC721 Metadata JSON Schema".
   * @return URI of _tokenId.
   */
  function tokenURI(uint256 _tokenId)
    external
    view
    returns (string memory);

}

File 15 of 19: IERC721TokenReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/0xcert/ethereum-erc721/

/**
 * @dev ERC-721 interface for accepting safe transfers.
 * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md.
 */
interface IERC721TokenReceiver
{

  /**
   * @dev Handle the receipt of a NFT. The ERC721 smart contract calls this function on the
   * recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return
   * of other than the magic value MUST result in the transaction being reverted.
   * Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` unless throwing.
   * @notice The contract address is always the message sender. A wallet/broker/auction application
   * MUST implement the wallet interface if it will accept safe transfers.
   * @param _operator The address which called `safeTransferFrom` function.
   * @param _from The address which previously owned the token.
   * @param _tokenId The NFT identifier which is being transferred.
   * @param _data Additional data with no specified format.
   * @return Returns `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
   */
  function onERC721Received(
    address _operator,
    address _from,
    uint256 _tokenId,
    bytes calldata _data
  )
    external
    returns(bytes4);

}

File 16 of 19: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;

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

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
      owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
      require(msg.sender == owner);
      _;
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
      require(newOwner != address(0));
      emit OwnershipTransferred(owner, newOwner);
      owner = newOwner;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   */
  function renounceOwnership() public onlyOwner {
      emit OwnershipRenounced(owner);
      owner = address(0);
  }
}

File 17 of 19: Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

import "./Ownable.sol";

/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();
  event NotPausable();

  bool public paused = false;
  bool public canPause = true;

  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
      require(!paused || msg.sender == owner);
      _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
      require(paused);
      _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   **/
  function pause() onlyOwner whenNotPaused public {
      require(canPause == true);
      paused = true;
      emit Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
      require(paused == true);
      paused = false;
      emit Unpause();
  }

  /**
   * @dev Prevent the token from ever being paused again
   **/
  function notPausable() onlyOwner public {
      paused = false;
      canPause = false;
      emit NotPausable();
  }
}

File 18 of 19: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/OpenZeppelin/openzeppelin-contracts

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

File 19 of 19: SupportsInterface.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

// Source: https://github.com/0xcert/ethereum-erc721/

import "./IERC165.sol";

/**
 * @dev Implementation of standard for detect smart contract interfaces.
 */
contract SupportsInterface is
  IERC165
{

  /**
   * @dev Mapping of supported intefraces.
   * You must not set element 0xffffffff to true.
   */
  mapping(bytes4 => bool) internal supportedInterfaces;

  /**
   * @dev Contract constructor.
   */
  constructor()
    public
  {
    supportedInterfaces[0x01ffc9a7] = true; // ERC165
  }

  /**
   * @dev Function to check which interfaces are suported by this contract.
   * @param _interfaceID Id of the interface.
   * @return True if _interfaceID is supported, false otherwise.
   */
  function supportsInterface(
    bytes4 _interfaceID
  )
    external
    override
    view
    returns (bool)
  {
    return supportedInterfaces[_interfaceID];
  }

}

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"address","name":"to","type":"address"},{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Freeze","type":"event"},{"anonymous":false,"inputs":[],"name":"NotFreezable","type":"event"},{"anonymous":false,"inputs":[],"name":"NotPausable","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","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":[],"name":"Pause","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"inputs":[{"internalType":"address","name":"_approved","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canFreeze","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canPause","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"frozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notFreezable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"notPausable","outputs":[],"stateMutability":"nonpayable","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":"_owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_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":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"_symbol","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":"address","name":"account","type":"address"}],"name":"unfreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"unfreezeAndMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"unfreezeAndTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600c60146101000a81548160ff0219169083151502179055506001600c60156101000a81548160ff0219169083151502179055506001600e60006101000a81548160ff0219169083151502179055503480156200006257600080fd5b506040516200588838038062005888833981810160405260a08110156200008857600080fd5b8101908080516040519392919084640100000000821115620000a957600080fd5b83820191506020820185811115620000c057600080fd5b8251866001820283011164010000000082111715620000de57600080fd5b8083526020830192505050908051906020019080838360005b8381101562000114578082015181840152602081019050620000f7565b50505050905090810190601f168015620001425780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200016657600080fd5b838201915060208201858111156200017d57600080fd5b82518660018202830111640100000000821117156200019b57600080fd5b8083526020830192505050908051906020019080838360005b83811015620001d1578082015181840152602081019050620001b4565b50505050905090810190601f168015620001ff5780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200022357600080fd5b838201915060208201858111156200023a57600080fd5b82518660018202830111640100000000821117156200025857600080fd5b8083526020830192505050908051906020019080838360005b838110156200028e57808201518184015260208101905062000271565b50505050905090810190601f168015620002bc5780820380516001836020036101000a031916815260200191505b506040526020018051906020019092919080516040519392919084640100000000821115620002ea57600080fd5b838201915060208201858111156200030157600080fd5b82518660018202830111640100000000821117156200031f57600080fd5b8083526020830192505050908051906020019080838360005b838110156200035557808201518184015260208101905062000338565b50505050905090810190601f168015620003835780820380516001836020036101000a031916815260200191505b5060405250505060016000806301ffc9a760e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555060016000806380ac58cd60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff0219169083151502179055506001600080635b5e139f60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff021916908315150217905550600160008063780e9d6360e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555033600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600590805190602001906200052792919062000ff5565b5083600690805190602001906200054092919062000ff5565b506200055283620005cd60201b60201c565b62000565336000620005e960201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620005c257620005ad826000620005e960201b60201c565b620005c1826001836200064560201b60201c565b5b50505050506200109b565b80600f9080519060200190620005e592919062000ff5565b5050565b8015600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614620006a057600080fd5b620006b78383620006d360201b62002d4e1760201c565b620006ce82826200073760201b62002da51760201c565b505050565b620006ea8282620008ac60201b62002f141760201c565b600881908060018154018082558091505060019003906000526020600020016000909190919091505560016008805490500360096000838152602001908152602001600020819055505050565b81600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f3030333030320000000000000000000000000000000000000000000000000000815250906200087c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200084057808201518184015260208101905062000823565b50505050905090810190601f1680156200086e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5081600760008581526020019081526020016000209080519060200190620008a692919062000ff5565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090620009bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200098157808201518184015260208101905062000964565b50505050905090810190601f168015620009af5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30303330303600000000000000000000000000000000000000000000000000008152509062000b01576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101562000ac557808201518184015260208101905062000aa8565b50505050905090810190601f16801562000af35780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5062000b14828262000b8760201b60201c565b62000b2733838362000de460201b60201c565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30303330303600000000000000000000000000000000000000000000000000008152509062000cca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101562000c8e57808201518184015260208101905062000c71565b50505050905090810190601f16801562000cbc5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150556001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003600b6000838152602001908152602001600020819055505050565b828262000df8828262000dff60201b60201c565b5050505050565b600c60149054906101000a900460ff16158062000e695750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b62000e7357600080fd5b8162000e858162000f8560201b60201c565b1562000ef9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6163636f756e742069732066726f7a656e00000000000000000000000000000081525060200191505060405180910390fd5b8162000f0b8162000f8560201b60201c565b1562000f7f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6163636f756e742069732066726f7a656e00000000000000000000000000000081525060200191505060405180910390fd5b50505050565b6000600e60009054906101000a900460ff16801562000fee5750600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b9050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200103857805160ff191683800117855562001069565b8280016001018555821562001069579182015b82811115620010685782518255916020019190600101906200104b565b5b5090506200107891906200107c565b5090565b5b80821115620010975760008160009055506001016200107d565b5090565b6147dd80620010ab6000396000f3fe608060405234801561001057600080fd5b50600436106102065760003560e01c80636352211e1161011a57806395d89b41116100ad578063d05166501161007c578063d051665014610ae8578063d3fc986414610b42578063e985e9c514610c27578063f2fde38b14610ca1578063fbc6e84e14610ce557610206565b806395d89b41146108ab578063a22cb4651461092e578063b88d4fde1461097e578063c87b56dd14610a4157610206565b80638456cb59116100e95780638456cb59146107865780638d1fdf2f146107905780638da5cb5b146107d45780638e6406ef1461080857610206565b80636352211e1461064957806370a08231146106a1578063715018a6146106f95780637284e4161461070357610206565b80632f745c591161019d57806342966c681161016c57806342966c681461056b57806345c8b1a6146105995780634be8b05e146105dd5780634f6ccce7146105e75780635c975abb1461062957610206565b80632f745c5914610471578063323be1c5146104d35780633f4ba83a146104f357806342842e0e146104fd57610206565b8063095ea7b3116101d9578063095ea7b31461038d5780631104bc77146103db57806318160ddd146103e557806323b872dd1461040357610206565b806301ffc9a71461020b57806306fdde031461026e578063081812fc146102f157806308998b4e14610349575b600080fd5b6102566004803603602081101561022157600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610d05565b60405180821515815260200191505060405180910390f35b610276610d6c565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102b657808201518184015260208101905061029b565b50505050905090810190601f1680156102e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61031d6004803603602081101561030757600080fd5b8101908080359060200190929190505050610e0e565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61038b6004803603602081101561035f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f8e565b005b6103d9600480360360408110156103a357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610fff565b005b6103e3611511565b005b6103ed6115b4565b6040518082815260200191505060405180910390f35b61046f6004803603606081101561041957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115c1565b005b6104bd6004803603604081101561048757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a99565b6040518082815260200191505060405180910390f35b6104db611c1a565b60405180821515815260200191505060405180910390f35b6104fb611c2d565b005b6105696004803603606081101561051357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611d09565b005b6105976004803603602081101561058157600080fd5b8101908080359060200190929190505050611d29565b005b6105db600480360360208110156105af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d8f565b005b6105e5611e3a565b005b610613600480360360208110156105fd57600080fd5b8101908080359060200190929190505050611ef8565b6040518082815260200191505060405180910390f35b610631611ffe565b60405180821515815260200191505060405180910390f35b6106756004803603602081101561065f57600080fd5b8101908080359060200190929190505050612011565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106e3600480360360208110156106b757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061215c565b6040518082815260200191505060405180910390f35b61070161227b565b005b61070b61237e565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561074b578082015181840152602081019050610730565b50505050905090810190601f1680156107785780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61078e612420565b005b6107d2600480360360208110156107a657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612555565b005b6107dc612600565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6108a96004803603606081101561081e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019064010000000081111561086557600080fd5b82018360208201111561087757600080fd5b8035906020019184600183028401116401000000008311171561089957600080fd5b9091929391929390505050612626565b005b6108b36126de565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108f35780820151818401526020810190506108d8565b50505050905090810190601f1680156109205780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61097c6004803603604081101561094457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612780565b005b610a3f6004803603608081101561099457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156109fb57600080fd5b820183602082011115610a0d57600080fd5b80359060200191846001830284011164010000000083111715610a2f57600080fd5b909192939192939050505061287f565b005b610a6d60048036036020811015610a5757600080fd5b81019080803590602001909291905050506128d6565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610aad578082015181840152602081019050610a92565b50505050905090810190601f168015610ada5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610b2a60048036036020811015610afe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ace565b60405180821515815260200191505060405180910390f35b610c2560048036036060811015610b5857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610b9f57600080fd5b820183602082011115610bb157600080fd5b80359060200191846001830284011164010000000083111715610bd357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612ae0565b005b610c8960048036036040811015610c3d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b53565b60405180821515815260200191505060405180910390f35b610ce360048036036020811015610cb757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612be7565b005b610ced612d3b565b60405180821515815260200191505060405180910390f35b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060058054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e045780601f10610dd957610100808354040283529160200191610e04565b820191906000526020600020905b815481529060010190602001808311610de757829003601f168201915b5050505050905090565b600081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090610f51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610f16578082015181840152602081019050610efb565b50505050905090810190601f168015610f435780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610fe857600080fd5b610ff181611d8f565b610ffc8160016131d7565b50565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614806110f85750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f3030333030330000000000000000000000000000000000000000000000000000815250906111d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561119957808201518184015260208101905061117e565b50505050905090810190601f1680156111c65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090611316576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156112db5780820151818401526020810190506112c0565b50505050905090810190601f1680156113085780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303800000000000000000000000000000000000000000000000000008152509061145b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611420578082015181840152602081019050611405565b50505050905090810190601f16801561144d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50856002600087815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550848673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461156b57600080fd5b6000600e60006101000a81548160ff0219169083151502179055507fa41ce0eb55e300a1ce656ef6b0c94d7f1f13fab1042ff519cf6bfbf0ed280b1d60405160405180910390a1565b6000600880549050905090565b8060006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061169257503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806117235750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f3030333030340000000000000000000000000000000000000000000000000000815250906117ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156117c45780820151818401526020810190506117a9565b50505050905090810190601f1680156117f15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5082600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090611941576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156119065780820151818401526020810190506118eb565b50505050905090810190601f1680156119335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060006001600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090611a85576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611a4a578082015181840152602081019050611a2f565b50505050905090810190601f168015611a775780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50611a9086866131d7565b50505050505050565b6000600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905082106040518060400160405280600681526020017f303035303037000000000000000000000000000000000000000000000000000081525090611bbc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b81578082015181840152602081019050611b66565b50505050905090810190601f168015611bae5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208281548110611c0757fe5b9060005260206000200154905092915050565b600c60159054906101000a900460ff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c8757600080fd5b600c60149054906101000a900460ff16611ca057600080fd5b60011515600c60149054906101000a900460ff16151514611cc057600080fd5b6000600c60146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b611d2483838360405180602001604052806000815250613297565b505050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d8357600080fd5b611d8c81613b04565b50565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611de957600080fd5b611df4816000613bc2565b8073ffffffffffffffffffffffffffffffffffffffff167fca5069937e68fd197927055037f59d7c90bf75ac104e6e375539ef480c3ad6ee60405160405180910390a250565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e9457600080fd5b6000600c60146101000a81548160ff0219169083151502179055506000600c60156101000a81548160ff0219169083151502179055507faff39f66825d4448497d384dee3f4a3adf00a622960add00806503ae4ccee01c60405160405180910390a1565b600060088054905082106040518060400160405280600681526020017f303035303037000000000000000000000000000000000000000000000000000081525090611fde576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611fa3578082015181840152602081019050611f88565b50505050905090810190601f168015611fd05780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060088281548110611fec57fe5b90600052602060002001549050919050565b600c60149054906101000a900460ff1681565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561211b578082015181840152602081019050612100565b50505050905090810190601f1680156121485780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f30303330303100000000000000000000000000000000000000000000000000008152509061226a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561222f578082015181840152602081019050612214565b50505050905090810190601f16801561225c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5061227482613c1e565b9050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146122d557600080fd5b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a26000600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6060600f8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124165780601f106123eb57610100808354040283529160200191612416565b820191906000526020600020905b8154815290600101906020018083116123f957829003601f168201915b5050505050905090565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461247a57600080fd5b600c60149054906101000a900460ff1615806124e35750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6124ec57600080fd5b60011515600c60159054906101000a900460ff1615151461250c57600080fd5b6001600c60146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146125af57600080fd5b6125ba816001613bc2565b8073ffffffffffffffffffffffffffffffffffffffff167faf85b60d26151edd11443b704d424da6c43d0468f2235ebae3d1904dbc32304960405160405180910390a250565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461268057600080fd5b61268984611d8f565b6126d8848484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050612ae0565b50505050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156127765780601f1061274b57610100808354040283529160200191612776565b820191906000526020600020905b81548152906001019060200180831161275957829003601f168201915b5050505050905090565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b6128cf85858585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050613297565b5050505050565b606081600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612a19576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129de5780820151818401526020810190506129c3565b50505050905090810190601f168015612a0b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600760008481526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015612ac15780601f10612a9657610100808354040283529160200191612ac1565b820191906000526020600020905b815481529060010190602001808311612aa457829003601f168201915b5050505050915050919050565b6000612ad982613c6a565b9050919050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b3a57600080fd5b612b448383612d4e565b612b4e8282612da5565b505050565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c4157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612c7b57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600e60009054906101000a900460ff1681565b612d588282612f14565b600881908060018154018082558091505060019003906000526020600020016000909190919091505560016008805490500360096000838152602001908152602001600020819055505050565b81600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090612ee6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612eab578082015181840152602081019050612e90565b50505050905090810190601f168015612ed85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5081600760008581526020019081526020016000209080519060200190612f0e9291906146c2565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090613021576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612fe6578082015181840152602081019050612fcb565b50505050905090810190601f1680156130135780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303036000000000000000000000000000000000000000000000000000081525090613161576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561312657808201518184015260208101905061310b565b50505050905090810190601f1680156131535780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5061316c8282613cd9565b613177338383613f32565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b60006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061321882613f45565b613223818484613f32565b61322d8183613fe6565b6132378383613cd9565b818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b8160006001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061336857503373ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b806133f95750600460008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6040518060400160405280600681526020017f3030333030340000000000000000000000000000000000000000000000000000815250906134d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561349a57808201518184015260208101905061347f565b50505050905090810190601f1680156134c75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5083600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090613617576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156135dc5780820151818401526020810190506135c1565b50505050905090810190601f1680156136095780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060006001600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30303330303700000000000000000000000000000000000000000000000000008152509061375b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613720578082015181840152602081019050613705565b50505050905090810190601f16801561374d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303031000000000000000000000000000000000000000000000000000081525090613869576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561382e578082015181840152602081019050613813565b50505050905090810190601f16801561385b5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5061387487876131d7565b6138938773ffffffffffffffffffffffffffffffffffffffff166142f4565b15613afa5760008773ffffffffffffffffffffffffffffffffffffffff1663150b7a02338b8a8a6040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561394757808201518184015260208101905061392c565b50505050905090810190601f1680156139745780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561399657600080fd5b505af11580156139aa573d6000803e3d6000fd5b505050506040513d60208110156139c057600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146040518060400160405280600681526020017f303033303035000000000000000000000000000000000000000000000000000081525090613af7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613abc578082015181840152602081019050613aa1565b50505050905090810190601f168015613ae95780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50505b5050505050505050565b613b0d81614307565b60006009600083815260200190815260200160002054905060006001600880549050039050600060088281548110613b4157fe5b906000526020600020015490508060088481548110613b5c57fe5b90600052602060002001819055506008805480613b7557fe5b600190038181906000526020600020016000905590558260096000838152602001908152602001600020819055506000600960008681526020019081526020016000208190555050505050565b8015600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490509050919050565b6000600e60009054906101000a900460ff168015613cd25750600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303036000000000000000000000000000000000000000000000000000081525090613e18576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ddd578082015181840152602081019050613dc2565b50505050905090810190601f168015613e0a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190806001815401808255809150506001900390600052602060002001600090919091909150556001600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905003600b6000838152602001908152602001600020819055505050565b8282613f3e8282614362565b5050505050565b600073ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613fe3576002600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b50565b8173ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303033303037000000000000000000000000000000000000000000000000000081525090614124576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156140e95780820151818401526020810190506140ce565b50505050905090810190601f1680156141165780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506001600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600b600083815260200190815260200160002054905060006001600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050039050818114614290576000600a60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020828154811061421057fe5b9060005260206000200154905080600a60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020848154811061426857fe5b906000526020600020018190555082600b600083815260200190815260200160002081905550505b600a60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806142d857fe5b6001900381819060005260206000200160009055905550505050565b600080823b905060008111915050919050565b614310816144d4565b6000600760008381526020019081526020016000208054600181600116156101000203166002900490501461435f5760076000828152602001908152602001600020600061435e9190614742565b5b50565b600c60149054906101000a900460ff1615806143cb5750600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6143d457600080fd5b816143de81613c6a565b15614451576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6163636f756e742069732066726f7a656e00000000000000000000000000000081525060200191505060405180910390fd5b8161445b81613c6a565b156144ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f6163636f756e742069732066726f7a656e00000000000000000000000000000081525060200191505060405180910390fd5b50505050565b80600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303033303032000000000000000000000000000000000000000000000000000081525090614615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156145da5780820151818401526020810190506145bf565b50505050905090810190601f1680156146075780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060006001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061465783613f45565b6146618184613fe6565b82600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061470357805160ff1916838001178555614731565b82800160010185558215614731579182015b82811115614730578251825591602001919060010190614715565b5b50905061473e919061478a565b5090565b50805460018160011615610100020316600290046000825580601f106147685750614787565b601f016020900490600052602060002090810190614786919061478a565b5b50565b5b808211156147a357600081600090555060010161478b565b509056fea2646970667358221220768d7639f361daaa0ab3d7e52133dfb978e53f0d0346d089e18db07a5b1dfd6064736f6c634300060c003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000a319bf12a9b89699379411043a3099e74cf0000c0000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000c43686c6f6520546f6b656e730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543484c4f450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010746f6b656e7320666f722063686c6f65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054687474703a2f2f6c6f63616c686f73743a333030302f76312f6a756e6f2f646f776e6c6f61645f646f63756d656e743f646f635f69643d7075626c69632d5769523437564e4e6571586758425935487039375552000000000000000000000000

Deployed ByteCode Sourcemap

154:1066:18:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;759:163:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;954:113:5;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9635:173:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;1084:134:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7500:338:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1270:104:7;;;:::i;:::-;;1262:113:6;;;:::i;:::-;;;;;;;;;;;;;;;;;;;6796:292:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1927:240:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;386:27:15;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;1046:127;;;:::i;:::-;;6060:170:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;712:81:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;917:124:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1247:117:15;;;:::i;:::-;;1509:189:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;356:26:15;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;9201:198:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;8749:194;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;1258:115:14;;;:::i;:::-;;231:95:2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;837:127:15;;;:::i;:::-;;792:119:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;336:20:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;912:168:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1177:121:5;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8240:223:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;5462:199;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;1444:171:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;686:100:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;556:152:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;10069:182:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;988:180:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;285:28:7;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;759:163:17;863:4;884:19;:33;904:12;884:33;;;;;;;;;;;;;;;;;;;;;;;;;;;877:40;;759:163;;;:::o;954:113:5:-;1018:19;1055:7;1047:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;954:113;:::o;9635:173:4:-;9757:7;9734:8;4440:1;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;;4401:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9781:12:::1;:22;9794:8;9781:22;;;;;;;;;;;;;;;;;;;;;9774:29;;9635:173:::0;;;;:::o;1084:134:18:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1157:19:18::1;1166:9;1157:8;:19::i;:::-;1184:29;1200:9;1211:1;1184:15;:29::i;:::-;1084:134:::0;:::o;7500:338:4:-;7607:8;3645:18;3666:9;:19;3676:8;3666:19;;;;;;;;;;;;;;;;;;;;;3645:40;;3713:10;3699:24;;:10;:24;;;:68;;;;3727:16;:28;3744:10;3727:28;;;;;;;;;;;;;;;:40;3756:10;3727:40;;;;;;;;;;;;;;;;;;;;;;;;;3699:68;3769:21;;;;;;;;;;;;;;;;;3691:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7634:8:::1;4440:1;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;::::0;4401:57:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7652:18:::2;7673:9;:19;7683:8;7673:19;;;;;;;;;;;;;;;;;;;;;7652:40;;7719:10;7706:23;;:9;:23;;;;7731:8;;;;;;;;;;;;;;;;::::0;7698:42:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7772:9;7747:12;:22;7760:8;7747:22;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;7824:8;7813:9;7792:41;;7801:10;7792:41;;;;;;;;;;;;4464:1;3797::::1;7500:338:::0;;;;:::o;1270:104:7:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1333:5:7::1;1321:9;;:17;;;;;;;;;;;;;;;;;;1353:14;;;;;;;;;;1270:104::o:0;1262:113:6:-;1333:7;1357:6;:13;;;;1350:20;;1262:113;:::o;6796:292:4:-;6922:8;3991:18;4012:9;:19;4022:8;4012:19;;;;;;;;;;;;;;;;;;;;;3991:40;;4066:10;4052:24;;:10;:24;;;:70;;;;4112:10;4086:36;;:12;:22;4099:8;4086:22;;;;;;;;;;;;;;;;;;;;;:36;;;4052:70;:120;;;;4132:16;:28;4149:10;4132:28;;;;;;;;;;;;;;;:40;4161:10;4132:40;;;;;;;;;;;;;;;;;;;;;;;;;4052:120;4180:30;;;;;;;;;;;;;;;;;4037:179;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6949:8:::1;4440:1;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;::::0;4401:57:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6967:18:::2;6988:9;:19;6998:8;6988:19;;;;;;;;;;;;;;;;;;;;;6967:40;;7035:5;7021:19;;:10;:19;;;7042:9;;;;;;;;;;;;;;;;::::0;7013:39:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7059:24;7069:3;7074:8;7059:9;:24::i;:::-;4464:1;4222::::1;6796:292:::0;;;;;:::o;1927:240:6:-;2048:7;2082:10;:18;2093:6;2082:18;;;;;;;;;;;;;;;:25;;;;2073:6;:34;2109:13;;;;;;;;;;;;;;;;;2065:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2136:10;:18;2147:6;2136:18;;;;;;;;;;;;;;;2155:6;2136:26;;;;;;;;;;;;;;;;2129:33;;1927:240;;;;:::o;386:27:15:-;;;;;;;;;;;;;:::o;1046:127::-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;736:6:15::1;;;;;;;;;;;728:15;;;::::0;::::1;;1119:4:::2;1109:14;;:6;;;;;;;;;;;:14;;;1101:23;;;::::0;::::2;;1141:5;1132:6;;:14;;;;;;;;;;;;;;;;;;1159:9;;;;;;;;;;1046:127::o:0;6060:170:4:-;6182:43;6200:5;6207:3;6212:8;6182:43;;;;;;;;;;;;:17;:43::i;:::-;6060:170;;;:::o;712:81:18:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;768:20:18::1;780:7;768:11;:20::i;:::-;712:81:::0;:::o;917:124:7:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;979:23:7::1;987:7;996:5;979:7;:23::i;:::-;1026:7;1017:17;;;;;;;;;;;;917:124:::0;:::o;1247:117:15:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1304:5:15::1;1295:6;;:14;;;;;;;;;;;;;;;;;;1328:5;1317:8;;:16;;;;;;;;;;;;;;;;;;1346:13;;;;;;;;;;1247:117::o:0;1509:189:6:-;1603:7;1637:6;:13;;;;1628:6;:22;1652:13;;;;;;;;;;;;;;;;;1620:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1679:6;1686;1679:14;;;;;;;;;;;;;;;;1672:21;;1509:189;;;:::o;356:26:15:-;;;;;;;;;;;;;:::o;9201:198:4:-;9292:14;9325:9;:19;9335:8;9325:19;;;;;;;;;;;;;;;;;;;;;9316:28;;9376:1;9358:20;;:6;:20;;;;9380:13;;;;;;;;;;;;;;;;;9350:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9201:198;;;:::o;8749:194::-;8840:7;8883:1;8865:20;;:6;:20;;;;8887:12;;;;;;;;;;;;;;;;;8857:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8913:25;8931:6;8913:17;:25::i;:::-;8906:32;;8749:194;;;:::o;1258:115:14:-;807:5;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1336:5:::1;;;;;;;;;;;1317:25;;;;;;;;;;;;1366:1;1350:5;;:18;;;;;;;;;;;;;;;;;;1258:115::o:0;231:95:2:-;275:13;307:12;300:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;231:95;:::o;837:127:15:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;557:6:15::1;;;;;;;;;;;556:7;:30;;;;581:5;;;;;;;;;;;567:19;;:10;:19;;;556:30;548:39;;;::::0;::::1;;913:4:::2;901:16;;:8;;;;;;;;;;;:16;;;893:25;;;::::0;::::2;;935:4;926:6;;:13;;;;;;;;;;;;;;;;;;952:7;;;;;;;;;;837:127::o:0;792:119:7:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;852:22:7::1;860:7;869:4;852:7;:22::i;:::-;896:7;889:15;;;;;;;;;;;;792:119:::0;:::o;336:20:14:-;;;;;;;;;;;;;:::o;912:168:18:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1019:19:18::1;1028:9;1019:8;:19::i;:::-;1046:29;1051:9;1062:7;1071:3;;1046:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:4;:29::i;:::-;912:168:::0;;;;:::o;1177:121:5:-;1243:21;1284:9;1274:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1177:121;:::o;8240:223:4:-;8390:9;8348:16;:28;8365:10;8348:28;;;;;;;;;;;;;;;:39;8377:9;8348:39;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;8437:9;8410:48;;8425:10;8410:48;;;8448:9;8410:48;;;;;;;;;;;;;;;;;;;;8240:223;;:::o;5462:199::-;5610:46;5628:5;5635:3;5640:8;5650:5;;5610:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:17;:46::i;:::-;5462:199;;;;;:::o;1444:171:5:-;1563:13;1540:8;4440:1:4;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;;4401:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1593:7:5::1;:17;1601:8;1593:17;;;;;;;;;;;1586:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1444:171:::0;;;;:::o;686:100:7:-;740:4;763:16;771:7;763;:16::i;:::-;756:23;;686:100;;;:::o;556:152:18:-;807:5:14;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;641:24:18::1;653:2;657:7;641:11;:24::i;:::-;671:32;690:7;699:3;671:18;:32::i;:::-;556:152:::0;;;:::o;10069:182:4:-;10190:4;10211:16;:24;10228:6;10211:24;;;;;;;;;;;;;;;:35;10236:9;10211:35;;;;;;;;;;;;;;;;;;;;;;;;;10204:42;;10069:182;;;;:::o;988:180:14:-;807:5;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1086:1:::1;1066:22;;:8;:22;;;;1058:31;;;::::0;::::1;;1130:8;1102:37;;1123:5;;;;;;;;;;;1102:37;;;;;;;;;;;;1155:8;1147:5;;:16;;;;;;;;;;;;;;;;;;988:180:::0;:::o;285:28:7:-;;;;;;;;;;;;;:::o;2548:207:6:-;2652:26;2664:3;2669:8;2652:11;:26::i;:::-;2684:6;2696:8;2684:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2749:1;2733:6;:13;;;;:17;2711:9;:19;2721:8;2711:19;;;;;;;;;;;:39;;;;2548:207;;:::o;2597:149:5:-;2699:8;4440:1:4;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;;4401:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2737:4:5::1;2717:7;:17;2725:8;2717:17;;;;;;;;;;;:24;;;;;;;;;;;;:::i;:::-;;2597:149:::0;;;:::o;11125:337:4:-;11239:1;11224:17;;:3;:17;;;;11243:12;;;;;;;;;;;;;;;;;11216:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11301:1;11270:33;;:9;:19;11280:8;11270:19;;;;;;;;;;;;;;;;;;;;;:33;;;11305:18;;;;;;;;;;;;;;;;;11262:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11331:26;11343:3;11348:8;11331:11;:26::i;:::-;11363:47;11384:10;11396:3;11401:8;11363:20;:47::i;:::-;11448:8;11443:3;11422:35;;11439:1;11422:35;;;;;;;;;;;;11125:337;;:::o;10434:310::-;10517:12;10532:9;:19;10542:8;10532:19;;;;;;;;;;;;;;;;;;;;;10517:34;;10557:24;10572:8;10557:14;:24::i;:::-;10588:41;10609:4;10615:3;10620:8;10588:20;:41::i;:::-;10636:30;10651:4;10657:8;10636:14;:30::i;:::-;10672:26;10684:3;10689:8;10672:11;:26::i;:::-;10730:8;10725:3;10710:29;;10719:4;10710:29;;;;;;;;;;;;10434:310;;;:::o;13874:570::-;14015:8;3991:18;4012:9;:19;4022:8;4012:19;;;;;;;;;;;;;;;;;;;;;3991:40;;4066:10;4052:24;;:10;:24;;;:70;;;;4112:10;4086:36;;:12;:22;4099:8;4086:22;;;;;;;;;;;;;;;;;;;;;:36;;;4052:70;:120;;;;4132:16;:28;4149:10;4132:28;;;;;;;;;;;;;;;:40;4161:10;4132:40;;;;;;;;;;;;;;;;;;;;;;;;;4052:120;4180:30;;;;;;;;;;;;;;;;;4037:179;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14042:8:::1;4440:1;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;::::0;4401:57:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14060:18:::2;14081:9;:19;14091:8;14081:19;;;;;;;;;;;;;;;;;;;;;14060:40;;14128:5;14114:19;;:10;:19;;;14135:9;;;;;;;;;;;;;;;;::::0;14106:39:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14174:1;14159:17;;:3;:17;;;;14178:12;;;;;;;;;;;;;;;;::::0;14151:40:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14198:24;14208:3;14213:8;14198:9;:24::i;:::-;14233:16;:3;:14;;;:16::i;:::-;14229:211;;;14263:13;14300:3;14279:42;;;14322:10;14334:5;14341:8;14351:5;14279:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;14263:94;;1195:10;14383:24;;14373:34;;;:6;:34;;;;14409:23;;;;;;;;;;;;;;;;::::0;14365:68:::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14229:211;;4464:1;4222::::1;13874:570:::0;;;;;;:::o;3148:476:6:-;3235:21;3247:8;3235:11;:21::i;:::-;3263:18;3284:9;:19;3294:8;3284:19;;;;;;;;;;;;3263:40;;3309:22;3350:1;3334:6;:13;;;;:17;3309:42;;3357:17;3377:6;3384:14;3377:22;;;;;;;;;;;;;;;;3357:42;;3427:9;3406:6;3413:10;3406:18;;;;;;;;;;;;;;;:30;;;;3443:6;:12;;;;;;;;;;;;;;;;;;;;;;;;3580:10;3557:9;:20;3567:9;3557:20;;;;;;;;;;;:33;;;;3618:1;3596:9;:19;3606:8;3596:19;;;;;;;;;;;:23;;;;3148:476;;;;:::o;452:108:7:-;547:6;546:7;518:16;:25;535:7;518:25;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;452:108;;:::o;5330:165:6:-;5441:7;5465:10;:18;5476:6;5465:18;;;;;;;;;;;;;;;:25;;;;5458:32;;5330:165;;;:::o;320:126:7:-;377:4;400:9;;;;;;;;;;;:39;;;;;414:16;:25;431:7;414:25;;;;;;;;;;;;;;;;;;;;;;;;;413:26;400:39;393:46;;320:126;;;:::o;4739:304:6:-;4888:1;4857:33;;:9;:19;4867:8;4857:19;;;;;;;;;;;;;;;;;;;;;:33;;;4892:18;;;;;;;;;;;;;;;;;4849:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4939:3;4917:9;:19;4927:8;4917:19;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;4949:10;:15;4960:3;4949:15;;;;;;;;;;;;;;;4970:8;4949:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5037:1;5012:10;:15;5023:3;5012:15;;;;;;;;;;;;;;;:22;;;;:26;4985:14;:24;5000:8;4985:24;;;;;;;;;;;:53;;;;4739:304;;:::o;797:111:18:-;893:4;899:2;1228:25:7;1244:4;1250:2;1228:15;:25::i;:::-;797:111:18;;;;;:::o;14571:164:4:-;14679:1;14645:36;;:12;:22;14658:8;14645:22;;;;;;;;;;;;;;;;;;;;;:36;;;14641:90;;14702:12;:22;14715:8;14702:22;;;;;;;;;;;;14695:29;;;;;;;;;;;14641:90;14571:164;:::o;3895:580:6:-;4041:5;4018:28;;:9;:19;4028:8;4018:19;;;;;;;;;;;;;;;;;;;;;:28;;;4048:9;;;;;;;;;;;;;;;;;4010:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4071:9;:19;4081:8;4071:19;;;;;;;;;;;;4064:26;;;;;;;;;;;4097;4126:14;:24;4141:8;4126:24;;;;;;;;;;;;4097:53;;4156:22;4208:1;4181:10;:17;4192:5;4181:17;;;;;;;;;;;;;;;:24;;;;:28;4156:53;;4238:18;4220:14;:36;4216:225;;4270:17;4290:10;:17;4301:5;4290:17;;;;;;;;;;;;;;;4308:14;4290:33;;;;;;;;;;;;;;;;4270:53;;4371:9;4331:10;:17;4342:5;4331:17;;;;;;;;;;;;;;;4349:18;4331:37;;;;;;;;;;;;;;;:49;;;;4416:18;4388:14;:25;4403:9;4388:25;;;;;;;;;;;:46;;;;4216:225;;4447:10;:17;4458:5;4447:17;;;;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;;;;;;;3895:580;;;;:::o;785:413:0:-;845:4;1048:12;1157:7;1145:20;1137:28;;1190:1;1183:4;:8;1176:15;;;785:413;;;:::o;2008:204:5:-;2095:21;2107:8;2095:11;:21::i;:::-;2162:1;2133:7;:17;2141:8;2133:17;;;;;;;;;;;2127:31;;;;;;;;;;;;;;;;:36;2123:85;;2184:7;:17;2192:8;2184:17;;;;;;;;;;;;2177:24;;;;:::i;:::-;2123:85;2008:204;:::o;1047:117:7:-;557:6:15;;;;;;;;;;;556:7;:30;;;;581:5;;;;;;;;;;;567:19;;:10;:19;;;556:30;548:39;;;;;;1134:4:7::1;624:16;632:7;624;:16::i;:::-;623:17;615:47;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;1153:2:::2;624:16;632:7;624;:16::i;:::-;623:17;615:47;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;672:1;595::15::1;1047:117:7::0;;:::o;11855:271:4:-;11938:8;4440:1;4409:33;;:9;:19;4419:8;4409:19;;;;;;;;;;;;;;;;;;;;;:33;;;;4444:13;;;;;;;;;;;;;;;;;4401:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11956:18:::1;11977:9;:19;11987:8;11977:19;;;;;;;;;;;;;;;;;;;;;11956:40;;12002:24;12017:8;12002:14;:24::i;:::-;12032:36;12047:10;12059:8;12032:14;:36::i;:::-;12112:8;12108:1;12079:42;;12088:10;12079:42;;;;;;;;;;;;4464:1;11855:271:::0;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://768d7639f361daaa0ab3d7e52133dfb978e53f0d0346d089e18db07a5b1dfd60
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.