Token ERC1155 Tokens

Overview ERC-1155

Total Supply:
0 TOKOT

Holders:
1 addresses

Transfers:
-

Profile Summary

 
Contract:
0x469620a25087a539de8e9e828a90964ae7fd5dcb0x469620A25087A539DE8E9E828A90964aE7Fd5Dcb

Loading
[ Download CSV Export  ] 
Loading
Loading

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

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

Contract Name:
Juloe

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

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

Contract Source Code (Solidity Multiple files format)

File 20 of 25: juloe.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./ERC1155.sol";
import "./Freezable.sol";
import "./Describable.sol";
import "./Strings.sol";

contract Juloe is
  ERC1155,
  Freezable,
  Describable
{

  /**
   * @dev A descriptive name for a collection of tokens.
   */
  string internal name_;

  /**
   * @dev An abbreviated name for a collection of tokens.
   */
  string internal symbol_;

  constructor(string memory name, string memory symbol, string memory description, string memory uri_) ERC1155(uri_) public {
    name_ = name;
    symbol_ = symbol;
    _setupDescription(description);
  }

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

  /**
   * @dev Returns an abbreviated name for a collection tokens.
   * @return _symbol Representing symbol.
   */
  function symbol()
    external
    view
    returns (string memory _symbol)
  {
    _symbol = symbol_;
  }


  function mint(address to, uint256 id, uint256 amount, bytes memory data) public onlyOwner {
    super._mint(to, id, amount, data);
  }

  function mintBatch(
    address _to,
    uint256[] memory _ids,
    uint256[] memory _quantities,
    bytes memory _data
  ) public onlyOwner {
    super._mintBatch(_to, _ids, _quantities, _data);
  }

  function _beforeTokenTransfer(
      address operator,
      address from,
      address to,
      uint256[] memory ids,
      uint256[] memory amounts,
      bytes memory data
  ) internal override whenTransfer(from, to) {}

  function uri(uint256 _tokenId) public view override returns (string memory) {
    return Strings.strConcat(
      super.uri(_tokenId),
      "&token_id=",
      Strings.uint2str(_tokenId)
    );
  }

  function contractURI() public view returns (string memory) {
    return super.uri(0);
  }
}

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

pragma solidity 0.8.17;

// 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 2 of 25: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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) {
        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 3 of 25: Describable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

contract Describable {
    string private _description;

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

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

File 4 of 25: ERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./IERC1155MetadataURI.sol";
import "./Address.sol";
import "./Context.sol";
import "./ERC165.sol";

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

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

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

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

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

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

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

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

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

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

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

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

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

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

        address operator = _msgSender();

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

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        _balances[id][from] = fromBalance - amount;
        _balances[id][to] += amount;

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

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

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

        address operator = _msgSender();

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

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

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            _balances[id][from] = fromBalance - amount;
            _balances[id][to] += amount;
        }

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

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

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

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

        address operator = _msgSender();

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

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

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

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

        address operator = _msgSender();

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

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

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

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

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

        address operator = _msgSender();

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

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        _balances[id][from] = fromBalance - amount;

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

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

        address operator = _msgSender();

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

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

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            _balances[id][from] = fromBalance - amount;
        }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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

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

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

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

        return array;
    }
}

File 5 of 25: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IERC165.sol";

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

File 6 of 25: ERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 7 of 25: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 8 of 25: ERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 9 of 25: ERC721MetadataEnumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 10 of 25: Freezable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

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 11 of 25: IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

File 12 of 25: IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IERC1155.sol";

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

File 13 of 25: IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IERC165.sol";

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

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

File 14 of 25: IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 15 of 25: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 16 of 25: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 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 17 of 25: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 18 of 25: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 19 of 25: IERC721TokenReceiver.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 21 of 25: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 22 of 25: Pausable.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 23 of 25: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// 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 24 of 25: Strings.sol
// SPDX-License-Identifier: MIT
// Inspired by https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol

pragma solidity 0.8.17;

library Strings {
    function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory) {
        return string(abi.encodePacked(_a, _b, _c, _d, _e));
    }

    function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory) {
        return strConcat(_a, _b, _c, _d, "");
    }

    function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) {
        return strConcat(_a, _b, _c, "", "");
    }

    function strConcat(string memory _a, string memory _b) internal pure returns (string memory) {
        return strConcat(_a, _b, "", "", "");
    }

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

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

pragma solidity 0.8.17;

// 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":"string","name":"uri_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"Unfreeze","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"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":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_quantities","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mintBatch","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":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"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":"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040526000600360146101000a81548160ff0219169083151502179055506001600360156101000a81548160ff0219169083151502179055506001600560006101000a81548160ff0219169083151502179055503480156200006257600080fd5b5060405162004553380380620045538339818101604052810190620000889190620002d8565b806200009a816200011b60201b60201c565b5033600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508360079081620000ed919062000611565b508260089081620000ff919062000611565b5062000111826200013060201b60201c565b50505050620006f8565b80600290816200012c919062000611565b5050565b806006908162000141919062000611565b5050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620001ae8262000163565b810181811067ffffffffffffffff82111715620001d057620001cf62000174565b5b80604052505050565b6000620001e562000145565b9050620001f38282620001a3565b919050565b600067ffffffffffffffff82111562000216576200021562000174565b5b620002218262000163565b9050602081019050919050565b60005b838110156200024e57808201518184015260208101905062000231565b60008484015250505050565b6000620002716200026b84620001f8565b620001d9565b90508281526020810184848401111562000290576200028f6200015e565b5b6200029d8482856200022e565b509392505050565b600082601f830112620002bd57620002bc62000159565b5b8151620002cf8482602086016200025a565b91505092915050565b60008060008060808587031215620002f557620002f46200014f565b5b600085015167ffffffffffffffff81111562000316576200031562000154565b5b6200032487828801620002a5565b945050602085015167ffffffffffffffff81111562000348576200034762000154565b5b6200035687828801620002a5565b935050604085015167ffffffffffffffff8111156200037a576200037962000154565b5b6200038887828801620002a5565b925050606085015167ffffffffffffffff811115620003ac57620003ab62000154565b5b620003ba87828801620002a5565b91505092959194509250565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200041957607f821691505b6020821081036200042f576200042e620003d1565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004997fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200045a565b620004a586836200045a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620004f2620004ec620004e684620004bd565b620004c7565b620004bd565b9050919050565b6000819050919050565b6200050e83620004d1565b620005266200051d82620004f9565b84845462000467565b825550505050565b600090565b6200053d6200052e565b6200054a81848462000503565b505050565b5b8181101562000572576200056660008262000533565b60018101905062000550565b5050565b601f821115620005c1576200058b8162000435565b62000596846200044a565b81016020851015620005a6578190505b620005be620005b5856200044a565b8301826200054f565b50505b505050565b600082821c905092915050565b6000620005e660001984600802620005c6565b1980831691505092915050565b6000620006018383620005d3565b9150826002028217905092915050565b6200061c82620003c6565b67ffffffffffffffff81111562000638576200063762000174565b5b62000644825462000400565b6200065182828562000576565b600060209050601f83116001811462000689576000841562000674578287015190505b620006808582620005f3565b865550620006f0565b601f198416620006998662000435565b60005b82811015620006c3578489015182556001820191506020850194506020810190506200069c565b86831015620006e35784890151620006df601f891682620005d3565b8355505b6001600288020188555050505b505050505050565b613e4b80620007086000396000f3fe608060405234801561001057600080fd5b50600436106101a85760003560e01c8063715018a6116100f9578063a22cb46511610097578063e985e9c511610071578063e985e9c514610449578063f242432a14610479578063f2fde38b14610495578063fbc6e84e146104b1576101a8565b8063a22cb465146103df578063d0516650146103fb578063e8a3d4851461042b576101a8565b80638456cb59116100d35780638456cb591461037d5780638d1fdf2f146103875780638da5cb5b146103a357806395d89b41146103c1576101a8565b8063715018a6146103395780637284e41614610343578063731133e914610361576101a8565b80632eb2c2d61161016657806345c8b1a61161014057806345c8b1a6146102c55780634be8b05e146102e15780634e1273f4146102eb5780635c975abb1461031b576101a8565b80632eb2c2d614610281578063323be1c51461029d5780633f4ba83a146102bb576101a8565b8062fdd58e146101ad57806301ffc9a7146101dd57806306fdde031461020d5780630e89341c1461022b5780631104bc771461025b5780631f7fdffa14610265575b600080fd5b6101c760048036038101906101c29190612879565b6104cf565b6040516101d491906128c8565b60405180910390f35b6101f760048036038101906101f2919061293b565b610597565b6040516102049190612983565b60405180910390f35b610215610679565b6040516102229190612a2e565b60405180910390f35b61024560048036038101906102409190612a50565b61070b565b6040516102529190612a2e565b60405180910390f35b610263610764565b005b61027f600480360381019061027a9190612c7a565b610807565b005b61029b60048036038101906102969190612d35565b610873565b005b6102a5610914565b6040516102b29190612983565b60405180910390f35b6102c3610927565b005b6102df60048036038101906102da9190612e04565b610a03565b005b6102e9610aae565b005b61030560048036038101906103009190612ef4565b610b6c565b604051610312919061302a565b60405180910390f35b610323610c85565b6040516103309190612983565b60405180910390f35b610341610c98565b005b61034b610d9b565b6040516103589190612a2e565b60405180910390f35b61037b6004803603810190610376919061304c565b610e2d565b005b610385610e99565b005b6103a1600480360381019061039c9190612e04565b610fce565b005b6103ab611079565b6040516103b891906130de565b60405180910390f35b6103c961109f565b6040516103d69190612a2e565b60405180910390f35b6103f960048036038101906103f49190613125565b611131565b005b61041560048036038101906104109190612e04565b611147565b6040516104229190612983565b60405180910390f35b610433611159565b6040516104409190612a2e565b60405180910390f35b610463600480360381019061045e9190613165565b61116a565b6040516104709190612983565b60405180910390f35b610493600480360381019061048e91906131a5565b6111fe565b005b6104af60048036038101906104aa9190612e04565b61129f565b005b6104b96113f2565b6040516104c69190612983565b60405180910390f35b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361053f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610536906132ae565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061066257507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610672575061067182611405565b5b9050919050565b606060078054610688906132fd565b80601f01602080910402602001604051908101604052809291908181526020018280546106b4906132fd565b80156107015780601f106106d657610100808354040283529160200191610701565b820191906000526020600020905b8154815290600101906020018083116106e457829003601f168201915b5050505050905090565b606061075d6107198361146f565b6040518060400160405280600a81526020017f26746f6b656e5f69643d0000000000000000000000000000000000000000000081525061075885611503565b611672565b9050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107be57600080fd5b6000600560006101000a81548160ff0219169083151502179055507fa41ce0eb55e300a1ce656ef6b0c94d7f1f13fab1042ff519cf6bfbf0ed280b1d60405160405180910390a1565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461086157600080fd5b61086d848484846116a8565b50505050565b61087b6118c5565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614806108c157506108c0856108bb6118c5565b61116a565b5b610900576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f7906133a0565b60405180910390fd5b61090d85858585856118cd565b5050505050565b600360159054906101000a900460ff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461098157600080fd5b600360149054906101000a900460ff1661099a57600080fd5b60011515600360149054906101000a900460ff161515146109ba57600080fd5b6000600360146101000a81548160ff0219169083151502179055507f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3360405160405180910390a1565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a5d57600080fd5b610a68816000611be9565b8073ffffffffffffffffffffffffffffffffffffffff167fca5069937e68fd197927055037f59d7c90bf75ac104e6e375539ef480c3ad6ee60405160405180910390a250565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b0857600080fd5b6000600360146101000a81548160ff0219169083151502179055506000600360156101000a81548160ff0219169083151502179055507faff39f66825d4448497d384dee3f4a3adf00a622960add00806503ae4ccee01c60405160405180910390a1565b60608151835114610bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba990613432565b60405180910390fd5b6000835167ffffffffffffffff811115610bcf57610bce612a82565b5b604051908082528060200260200182016040528015610bfd5781602001602082028036833780820191505090505b50905060005b8451811015610c7a57610c4a858281518110610c2257610c21613452565b5b6020026020010151858381518110610c3d57610c3c613452565b5b60200260200101516104cf565b828281518110610c5d57610c5c613452565b5b60200260200101818152505080610c73906134b0565b9050610c03565b508091505092915050565b600360149054906101000a900460ff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cf257600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a26000600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060068054610daa906132fd565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd6906132fd565b8015610e235780601f10610df857610100808354040283529160200191610e23565b820191906000526020600020905b815481529060010190602001808311610e0657829003601f168201915b5050505050905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e8757600080fd5b610e9384848484611c45565b50505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ef357600080fd5b600360149054906101000a900460ff161580610f5c5750600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610f6557600080fd5b60011515600360159054906101000a900460ff16151514610f8557600080fd5b6001600360146101000a81548160ff0219169083151502179055507f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62560405160405180910390a1565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461102857600080fd5b611033816001611be9565b8073ffffffffffffffffffffffffffffffffffffffff167faf85b60d26151edd11443b704d424da6c43d0468f2235ebae3d1904dbc32304960405160405180910390a250565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600880546110ae906132fd565b80601f01602080910402602001604051908101604052809291908181526020018280546110da906132fd565b80156111275780601f106110fc57610100808354040283529160200191611127565b820191906000526020600020905b81548152906001019060200180831161110a57829003601f168201915b5050505050905090565b61114361113c6118c5565b8383611dda565b5050565b600061115282611f46565b9050919050565b6060611165600061146f565b905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6112066118c5565b73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16148061124c575061124b856112466118c5565b61116a565b5b61128b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112829061356a565b60405180910390fd5b6112988585858585611fb5565b5050505050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112f957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361133257600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600560009054906101000a900460ff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60606002805461147e906132fd565b80601f01602080910402602001604051908101604052809291908181526020018280546114aa906132fd565b80156114f75780601f106114cc576101008083540402835291602001916114f7565b820191906000526020600020905b8154815290600101906020018083116114da57829003601f168201915b50505050509050919050565b60606000820361154a576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061166d565b600082905060005b6000821461157c578080611565906134b0565b915050600a8261157591906135b9565b9150611552565b60008167ffffffffffffffff81111561159857611597612a82565b5b6040519080825280601f01601f1916602001820160405280156115ca5781602001600182028036833780820191505090505b50905060006001836115dc91906135ea565b90505b6000861461166557600a866115f4919061361e565b6030611600919061364f565b60f81b82828061160f90613683565b93508151811061162257611621613452565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8661165e91906135b9565b95506115df565b819450505050505b919050565b606061169f848484604051806020016040528060008152506040518060200160405280600081525061223f565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170e9061371e565b60405180910390fd5b815183511461175b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611752906137b0565b60405180910390fd5b60006117656118c5565b905061177681600087878787612274565b60005b845181101561182f5783818151811061179557611794613452565b5b60200260200101516000808784815181106117b3576117b2613452565b5b6020026020010151815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611815919061364f565b925050819055508080611827906134b0565b915050611779565b508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516118a79291906137d0565b60405180910390a46118be8160008787878761228a565b5050505050565b600033905090565b8151835114611911576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611908906137b0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611980576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197790613879565b60405180910390fd5b600061198a6118c5565b905061199a818787878787612274565b60005b8451811015611b545760008582815181106119bb576119ba613452565b5b6020026020010151905060008583815181106119da576119d9613452565b5b60200260200101519050600080600084815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611a7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a729061390b565b60405180910390fd5b8181611a8791906135ea565b60008085815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160008085815260200190815260200160002060008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611b39919061364f565b9250508190555050505080611b4d906134b0565b905061199d565b508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611bcb9291906137d0565b60405180910390a4611be181878787878761228a565b505050505050565b8015600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611cb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cab9061371e565b60405180910390fd5b6000611cbe6118c5565b9050611cdf81600087611cd088612461565b611cd988612461565b87612274565b8260008086815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611d3e919061364f565b925050819055508473ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051611dbc92919061392b565b60405180910390a4611dd3816000878787876124db565b5050505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611e48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3f906139c6565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611f399190612983565b60405180910390a3505050565b6000600560009054906101000a900460ff168015611fae5750600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16155b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603612024576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161201b90613879565b60405180910390fd5b600061202e6118c5565b905061204e81878761203f88612461565b61204888612461565b87612274565b600080600086815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050838110156120e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120dc9061390b565b60405180910390fd5b83816120f191906135ea565b60008087815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508360008087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546121a3919061364f565b925050819055508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62888860405161222092919061392b565b60405180910390a46122368288888888886124db565b50505050505050565b6060858585858560405160200161225a959493929190613a22565b604051602081830303815290604052905095945050505050565b848461228082826126b2565b5050505050505050565b6122a98473ffffffffffffffffffffffffffffffffffffffff166127be565b15612459578373ffffffffffffffffffffffffffffffffffffffff1663bc197c8187878686866040518663ffffffff1660e01b81526004016122ef959493929190613ac2565b6020604051808303816000875af192505050801561232b57506040513d601f19601f820116820180604052508101906123289190613b3f565b60015b6123d057612337613b79565b806308c379a003612393575061234b613b9b565b806123565750612395565b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161238a9190612a2e565b60405180910390fd5b505b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123c790613c9d565b60405180910390fd5b63bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244e90613d2f565b60405180910390fd5b505b505050505050565b60606000600167ffffffffffffffff8111156124805761247f612a82565b5b6040519080825280602002602001820160405280156124ae5781602001602082028036833780820191505090505b50905082816000815181106124c6576124c5613452565b5b60200260200101818152505080915050919050565b6124fa8473ffffffffffffffffffffffffffffffffffffffff166127be565b156126aa578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401612540959493929190613d4f565b6020604051808303816000875af192505050801561257c57506040513d601f19601f820116820180604052508101906125799190613b3f565b60015b61262157612588613b79565b806308c379a0036125e4575061259c613b9b565b806125a757506125e6565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125db9190612a2e565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261890613c9d565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146126a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161269f90613d2f565b60405180910390fd5b505b505050505050565b600360149054906101000a900460ff16158061271b5750600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61272457600080fd5b8161272e81611f46565b1561276e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276590613df5565b60405180910390fd5b8161277881611f46565b156127b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127af90613df5565b60405180910390fd5b50505050565b600080823b905060008111915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612810826127e5565b9050919050565b61282081612805565b811461282b57600080fd5b50565b60008135905061283d81612817565b92915050565b6000819050919050565b61285681612843565b811461286157600080fd5b50565b6000813590506128738161284d565b92915050565b600080604083850312156128905761288f6127db565b5b600061289e8582860161282e565b92505060206128af85828601612864565b9150509250929050565b6128c281612843565b82525050565b60006020820190506128dd60008301846128b9565b92915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612918816128e3565b811461292357600080fd5b50565b6000813590506129358161290f565b92915050565b600060208284031215612951576129506127db565b5b600061295f84828501612926565b91505092915050565b60008115159050919050565b61297d81612968565b82525050565b60006020820190506129986000830184612974565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156129d85780820151818401526020810190506129bd565b60008484015250505050565b6000601f19601f8301169050919050565b6000612a008261299e565b612a0a81856129a9565b9350612a1a8185602086016129ba565b612a23816129e4565b840191505092915050565b60006020820190508181036000830152612a4881846129f5565b905092915050565b600060208284031215612a6657612a656127db565b5b6000612a7484828501612864565b91505092915050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612aba826129e4565b810181811067ffffffffffffffff82111715612ad957612ad8612a82565b5b80604052505050565b6000612aec6127d1565b9050612af88282612ab1565b919050565b600067ffffffffffffffff821115612b1857612b17612a82565b5b602082029050602081019050919050565b600080fd5b6000612b41612b3c84612afd565b612ae2565b90508083825260208201905060208402830185811115612b6457612b63612b29565b5b835b81811015612b8d5780612b798882612864565b845260208401935050602081019050612b66565b5050509392505050565b600082601f830112612bac57612bab612a7d565b5b8135612bbc848260208601612b2e565b91505092915050565b600080fd5b600067ffffffffffffffff821115612be557612be4612a82565b5b612bee826129e4565b9050602081019050919050565b82818337600083830152505050565b6000612c1d612c1884612bca565b612ae2565b905082815260208101848484011115612c3957612c38612bc5565b5b612c44848285612bfb565b509392505050565b600082601f830112612c6157612c60612a7d565b5b8135612c71848260208601612c0a565b91505092915050565b60008060008060808587031215612c9457612c936127db565b5b6000612ca28782880161282e565b945050602085013567ffffffffffffffff811115612cc357612cc26127e0565b5b612ccf87828801612b97565b935050604085013567ffffffffffffffff811115612cf057612cef6127e0565b5b612cfc87828801612b97565b925050606085013567ffffffffffffffff811115612d1d57612d1c6127e0565b5b612d2987828801612c4c565b91505092959194509250565b600080600080600060a08688031215612d5157612d506127db565b5b6000612d5f8882890161282e565b9550506020612d708882890161282e565b945050604086013567ffffffffffffffff811115612d9157612d906127e0565b5b612d9d88828901612b97565b935050606086013567ffffffffffffffff811115612dbe57612dbd6127e0565b5b612dca88828901612b97565b925050608086013567ffffffffffffffff811115612deb57612dea6127e0565b5b612df788828901612c4c565b9150509295509295909350565b600060208284031215612e1a57612e196127db565b5b6000612e288482850161282e565b91505092915050565b600067ffffffffffffffff821115612e4c57612e4b612a82565b5b602082029050602081019050919050565b6000612e70612e6b84612e31565b612ae2565b90508083825260208201905060208402830185811115612e9357612e92612b29565b5b835b81811015612ebc5780612ea8888261282e565b845260208401935050602081019050612e95565b5050509392505050565b600082601f830112612edb57612eda612a7d565b5b8135612eeb848260208601612e5d565b91505092915050565b60008060408385031215612f0b57612f0a6127db565b5b600083013567ffffffffffffffff811115612f2957612f286127e0565b5b612f3585828601612ec6565b925050602083013567ffffffffffffffff811115612f5657612f556127e0565b5b612f6285828601612b97565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612fa181612843565b82525050565b6000612fb38383612f98565b60208301905092915050565b6000602082019050919050565b6000612fd782612f6c565b612fe18185612f77565b9350612fec83612f88565b8060005b8381101561301d5781516130048882612fa7565b975061300f83612fbf565b925050600181019050612ff0565b5085935050505092915050565b600060208201905081810360008301526130448184612fcc565b905092915050565b60008060008060808587031215613066576130656127db565b5b60006130748782880161282e565b945050602061308587828801612864565b935050604061309687828801612864565b925050606085013567ffffffffffffffff8111156130b7576130b66127e0565b5b6130c387828801612c4c565b91505092959194509250565b6130d881612805565b82525050565b60006020820190506130f360008301846130cf565b92915050565b61310281612968565b811461310d57600080fd5b50565b60008135905061311f816130f9565b92915050565b6000806040838503121561313c5761313b6127db565b5b600061314a8582860161282e565b925050602061315b85828601613110565b9150509250929050565b6000806040838503121561317c5761317b6127db565b5b600061318a8582860161282e565b925050602061319b8582860161282e565b9150509250929050565b600080600080600060a086880312156131c1576131c06127db565b5b60006131cf8882890161282e565b95505060206131e08882890161282e565b94505060406131f188828901612864565b935050606061320288828901612864565b925050608086013567ffffffffffffffff811115613223576132226127e0565b5b61322f88828901612c4c565b9150509295509295909350565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a60008201527f65726f2061646472657373000000000000000000000000000000000000000000602082015250565b6000613298602b836129a9565b91506132a38261323c565b604082019050919050565b600060208201905081810360008301526132c78161328b565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061331557607f821691505b602082108103613328576133276132ce565b5b50919050565b7f455243313135353a207472616e736665722063616c6c6572206973206e6f742060008201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000602082015250565b600061338a6032836129a9565b91506133958261332e565b604082019050919050565b600060208201905081810360008301526133b98161337d565b9050919050565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b600061341c6029836129a9565b9150613427826133c0565b604082019050919050565b6000602082019050818103600083015261344b8161340f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006134bb82612843565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036134ed576134ec613481565b5b600182019050919050565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260008201527f20617070726f7665640000000000000000000000000000000000000000000000602082015250565b60006135546029836129a9565b915061355f826134f8565b604082019050919050565b6000602082019050818103600083015261358381613547565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006135c482612843565b91506135cf83612843565b9250826135df576135de61358a565b5b828204905092915050565b60006135f582612843565b915061360083612843565b925082820390508181111561361857613617613481565b5b92915050565b600061362982612843565b915061363483612843565b9250826136445761364361358a565b5b828206905092915050565b600061365a82612843565b915061366583612843565b925082820190508082111561367d5761367c613481565b5b92915050565b600061368e82612843565b9150600082036136a1576136a0613481565b5b600182039050919050565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b60006137086021836129a9565b9150613713826136ac565b604082019050919050565b60006020820190508181036000830152613737816136fb565b9050919050565b7f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060008201527f6d69736d61746368000000000000000000000000000000000000000000000000602082015250565b600061379a6028836129a9565b91506137a58261373e565b604082019050919050565b600060208201905081810360008301526137c98161378d565b9050919050565b600060408201905081810360008301526137ea8185612fcc565b905081810360208301526137fe8184612fcc565b90509392505050565b7f455243313135353a207472616e7366657220746f20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b60006138636025836129a9565b915061386e82613807565b604082019050919050565b6000602082019050818103600083015261389281613856565b9050919050565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f60008201527f72207472616e7366657200000000000000000000000000000000000000000000602082015250565b60006138f5602a836129a9565b915061390082613899565b604082019050919050565b60006020820190508181036000830152613924816138e8565b9050919050565b600060408201905061394060008301856128b9565b61394d60208301846128b9565b9392505050565b7f455243313135353a2073657474696e6720617070726f76616c2073746174757360008201527f20666f722073656c660000000000000000000000000000000000000000000000602082015250565b60006139b06029836129a9565b91506139bb82613954565b604082019050919050565b600060208201905081810360008301526139df816139a3565b9050919050565b600081905092915050565b60006139fc8261299e565b613a0681856139e6565b9350613a168185602086016129ba565b80840191505092915050565b6000613a2e82886139f1565b9150613a3a82876139f1565b9150613a4682866139f1565b9150613a5282856139f1565b9150613a5e82846139f1565b91508190509695505050505050565b600081519050919050565b600082825260208201905092915050565b6000613a9482613a6d565b613a9e8185613a78565b9350613aae8185602086016129ba565b613ab7816129e4565b840191505092915050565b600060a082019050613ad760008301886130cf565b613ae460208301876130cf565b8181036040830152613af68186612fcc565b90508181036060830152613b0a8185612fcc565b90508181036080830152613b1e8184613a89565b90509695505050505050565b600081519050613b398161290f565b92915050565b600060208284031215613b5557613b546127db565b5b6000613b6384828501613b2a565b91505092915050565b60008160e01c9050919050565b600060033d1115613b985760046000803e613b95600051613b6c565b90505b90565b600060443d10613c2857613bad6127d1565b60043d036004823e80513d602482011167ffffffffffffffff82111715613bd5575050613c28565b808201805167ffffffffffffffff811115613bf35750505050613c28565b80602083010160043d038501811115613c10575050505050613c28565b613c1f82602001850186612ab1565b82955050505050505b90565b7f455243313135353a207472616e7366657220746f206e6f6e204552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b6000613c876034836129a9565b9150613c9282613c2b565b604082019050919050565b60006020820190508181036000830152613cb681613c7a565b9050919050565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b6000613d196028836129a9565b9150613d2482613cbd565b604082019050919050565b60006020820190508181036000830152613d4881613d0c565b9050919050565b600060a082019050613d6460008301886130cf565b613d7160208301876130cf565b613d7e60408301866128b9565b613d8b60608301856128b9565b8181036080830152613d9d8184613a89565b90509695505050505050565b7f6163636f756e742069732066726f7a656e000000000000000000000000000000600082015250565b6000613ddf6011836129a9565b9150613dea82613da9565b602082019050919050565b60006020820190508181036000830152613e0e81613dd2565b905091905056fea26469706673582212202dc173cf5742d7a3354fdb4c3ec6d05c7896196940c07a2dd66d2d7c3959b7f964736f6c63430008110033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000d746f6b6f2d6572632d31313535000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005544f4b4f540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009544f4b4f20544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b68747470733a2f2f706f7274616c2d73746167652e746f6b6f2e6e6574776f726b2f76312f6a756e6f2f646f776e6c6f61645f646f63756d656e743f646f635f69643d7075626c69632d7a784561354d704e394e35377554366b76366f72336826746f6b656e5f69643d31000000000000000000000000000000000000000000

Deployed ByteCode Sourcemap

161:1769:24:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2061:228:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1112:305;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;737:98:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1637:198;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1270:104:9;;;:::i;:::-;;1205:200:24;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3936:430:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;386:27:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1046:127;;;:::i;:::-;;917:124:9;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1247:117:20;;;:::i;:::-;;2446:508:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;356:26:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1258:115:19;;;:::i;:::-;;231:95:2;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1067:134:24;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;837:127:20;;;:::i;:::-;;792:119:9;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;336:20:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;956:106:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3022:153:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;686:100:9;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1839:89:24;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3242:166:3;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3475:389;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;988:180:19;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;285:28:9;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2061:228:3;2147:7;2193:1;2174:21;;:7;:21;;;2166:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;2260:9;:13;2270:2;2260:13;;;;;;;;;;;:22;2274:7;2260:22;;;;;;;;;;;;;;;;2253:29;;2061:228;;;;:::o;1112:305::-;1214:4;1264:26;1249:41;;;:11;:41;;;;:109;;;;1321:37;1306:52;;;:11;:52;;;;1249:109;:161;;;;1374:36;1398:11;1374:23;:36::i;:::-;1249:161;1230:180;;1112:305;;;:::o;737:98:24:-;788:19;825:5;817:13;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;737:98;:::o;1637:198::-;1698:13;1726:104;1751:19;1761:8;1751:9;:19::i;:::-;1726:104;;;;;;;;;;;;;;;;;1798:26;1815:8;1798:16;:26::i;:::-;1726:17;:104::i;:::-;1719:111;;1637:198;;;:::o;1270:104:9:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1333:5:9::1;1321:9;;:17;;;;;;;;;;;;;;;;;;1353:14;;;;;;;;;;1270:104::o:0;1205:200:24:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1353:47:24::1;1370:3;1375:4;1381:11;1394:5;1353:16;:47::i;:::-;1205:200:::0;;;;:::o;3936:430:3:-;4169:12;:10;:12::i;:::-;4161:20;;:4;:20;;;:60;;;;4185:36;4202:4;4208:12;:10;:12::i;:::-;4185:16;:36::i;:::-;4161:60;4140:157;;;;;;;;;;;;:::i;:::-;;;;;;;;;4307:52;4330:4;4336:2;4340:3;4345:7;4354:4;4307:22;:52::i;:::-;3936:430;;;;;:::o;386:27:20:-;;;;;;;;;;;;;:::o;1046:127::-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;736:6:20::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;917:124:9:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;979:23:9::1;987:7;996:5;979:7;:23::i;:::-;1026:7;1017:17;;;;;;;;;;;;917:124:::0;:::o;1247:117:20:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1304:5:20::1;1295:6;;:14;;;;;;;;;;;;;;;;;;1328:5;1317:8;;:16;;;;;;;;;;;;;;;;;;1346:13;;;;;;;;;;1247:117::o:0;2446:508:3:-;2597:16;2656:3;:10;2637:8;:15;:29;2629:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;2723:30;2770:8;:15;2756:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2723:63;;2802:9;2797:120;2821:8;:15;2817:1;:19;2797:120;;;2876:30;2886:8;2895:1;2886:11;;;;;;;;:::i;:::-;;;;;;;;2899:3;2903:1;2899:6;;;;;;;;:::i;:::-;;;;;;;;2876:9;:30::i;:::-;2857:13;2871:1;2857:16;;;;;;;;:::i;:::-;;;;;;;:49;;;;;2838:3;;;;:::i;:::-;;;2797:120;;;;2934:13;2927:20;;;2446:508;;;;:::o;356:26:20:-;;;;;;;;;;;;;:::o;1258:115:19:-;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;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;231:95;:::o;1067:134:24:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1163:33:24::1;1175:2;1179;1183:6;1191:4;1163:11;:33::i;:::-;1067:134:::0;;;;:::o;837:127:20:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;557:6:20::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:9:-;807:5:19;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;852:22:9::1;860:7;869:4;852:7;:22::i;:::-;896:7;889:15;;;;;;;;;;;;792:119:::0;:::o;336:20:19:-;;;;;;;;;;;;;:::o;956:106:24:-;1009:21;1050:7;1040:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;956:106;:::o;3022:153:3:-;3116:52;3135:12;:10;:12::i;:::-;3149:8;3159;3116:18;:52::i;:::-;3022:153;;:::o;686:100:9:-;740:4;763:16;771:7;763;:16::i;:::-;756:23;;686:100;;;:::o;1839:89:24:-;1883:13;1911:12;1921:1;1911:9;:12::i;:::-;1904:19;;1839:89;:::o;3242:166:3:-;3341:4;3364:18;:27;3383:7;3364:27;;;;;;;;;;;;;;;:37;3392:8;3364:37;;;;;;;;;;;;;;;;;;;;;;;;;3357:44;;3242:166;;;;:::o;3475:389::-;3683:12;:10;:12::i;:::-;3675:20;;:4;:20;;;:60;;;;3699:36;3716:4;3722:12;:10;:12::i;:::-;3699:16;:36::i;:::-;3675:60;3654:148;;;;;;;;;;;;:::i;:::-;;;;;;;;;3812:45;3830:4;3836:2;3840;3844:6;3852:4;3812:17;:45::i;:::-;3475:389;;;;;:::o;988:180:19:-;807:5;;;;;;;;;;;793:19;;:10;:19;;;785:28;;;;;;1086:1:::1;1066:22;;:8;:22;;::::0;1058:31:::1;;;::::0;::::1;;1130:8;1102:37;;1123:5;;;;;;;;;;;1102:37;;;;;;;;;;;;1155:8;1147:5;;:16;;;;;;;;;;;;;;;;;;988:180:::0;:::o;285:28:9:-;;;;;;;;;;;;;:::o;763:155:4:-;848:4;886:25;871:40;;;:11;:40;;;;864:47;;763:155;;;:::o;1816:103:3:-;1876:13;1908:4;1901:11;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1816:103;;;:::o;899:467:22:-;949:27;998:1;992:2;:7;988:48;;1015:10;;;;;;;;;;;;;;;;;;;;;988:48;1045:6;1054:2;1045:11;;1066:8;1084:66;1096:1;1091;:6;1084:66;;1113:5;;;;;:::i;:::-;;;;1137:2;1132:7;;;;;:::i;:::-;;;1084:66;;;1159:17;1189:3;1179:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1159:34;;1203:6;1218:1;1212:3;:7;;;;:::i;:::-;1203:16;;1229:102;1242:1;1236:2;:7;1229:102;;1294:2;1289;:7;;;;:::i;:::-;1284:2;:12;;;;:::i;:::-;1271:27;;1259:4;1264:3;;;;;:::i;:::-;;;1259:9;;;;;;;;:::i;:::-;;;;;:39;;;;;;;;;;;1318:2;1312:8;;;;;:::i;:::-;;;1229:102;;;1354:4;1340:19;;;;;;899:467;;;;:::o;577:164::-;673:13;705:29;715:2;719;723;705:29;;;;;;;;;;;;;;;;;;;;;;;;:9;:29::i;:::-;698:36;;577:164;;;;;:::o;9108:715:3:-;9294:1;9280:16;;:2;:16;;;9272:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;9366:7;:14;9352:3;:10;:28;9344:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;9436:16;9455:12;:10;:12::i;:::-;9436:31;;9478:66;9499:8;9517:1;9521:2;9525:3;9530:7;9539:4;9478:20;:66::i;:::-;9560:9;9555:101;9579:3;:10;9575:1;:14;9555:101;;;9635:7;9643:1;9635:10;;;;;;;;:::i;:::-;;;;;;;;9610:9;:17;9620:3;9624:1;9620:6;;;;;;;;:::i;:::-;;;;;;;;9610:17;;;;;;;;;;;:21;9628:2;9610:21;;;;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;;;;;9591:3;;;;;:::i;:::-;;;;9555:101;;;;9707:2;9671:53;;9703:1;9671:53;;9685:8;9671:53;;;9711:3;9716:7;9671:53;;;;;;;:::i;:::-;;;;;;;;9735:81;9771:8;9789:1;9793:2;9797:3;9802:7;9811:4;9735:35;:81::i;:::-;9262:561;9108:715;;;;:::o;657:96:1:-;710:7;736:10;729:17;;657:96;:::o;5925:1003:3:-;6145:7;:14;6131:3;:10;:28;6123:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;6236:1;6222:16;;:2;:16;;;6214:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;6291:16;6310:12;:10;:12::i;:::-;6291:31;;6333:60;6354:8;6364:4;6370:2;6374:3;6379:7;6388:4;6333:20;:60::i;:::-;6409:9;6404:369;6428:3;:10;6424:1;:14;6404:369;;;6459:10;6472:3;6476:1;6472:6;;;;;;;;:::i;:::-;;;;;;;;6459:19;;6492:14;6509:7;6517:1;6509:10;;;;;;;;:::i;:::-;;;;;;;;6492:27;;6534:19;6556:9;:13;6566:2;6556:13;;;;;;;;;;;:19;6570:4;6556:19;;;;;;;;;;;;;;;;6534:41;;6612:6;6597:11;:21;;6589:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;6715:6;6701:11;:20;;;;:::i;:::-;6679:9;:13;6689:2;6679:13;;;;;;;;;;;:19;6693:4;6679:19;;;;;;;;;;;;;;;:42;;;;6756:6;6735:9;:13;6745:2;6735:13;;;;;;;;;;;:17;6749:2;6735:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;6445:328;;;6440:3;;;;:::i;:::-;;;6404:369;;;;6818:2;6788:47;;6812:4;6788:47;;6802:8;6788:47;;;6822:3;6827:7;6788:47;;;;;;;:::i;:::-;;;;;;;;6846:75;6882:8;6892:4;6898:2;6902:3;6907:7;6916:4;6846:35;:75::i;:::-;6113:815;5925:1003;;;;;:::o;452:108:9:-;547:6;546:7;518:16;:25;535:7;518:25;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;452:108;;:::o;8210:553:3:-;8371:1;8357:16;;:2;:16;;;8349:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;8422:16;8441:12;:10;:12::i;:::-;8422:31;;8464:102;8485:8;8503:1;8507:2;8511:21;8529:2;8511:17;:21::i;:::-;8534:25;8552:6;8534:17;:25::i;:::-;8561:4;8464:20;:102::i;:::-;8598:6;8577:9;:13;8587:2;8577:13;;;;;;;;;;;:17;8591:2;8577:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;8656:2;8619:52;;8652:1;8619:52;;8634:8;8619:52;;;8660:2;8664:6;8619:52;;;;;;;:::i;:::-;;;;;;;;8682:74;8713:8;8731:1;8735:2;8739;8743:6;8751:4;8682:30;:74::i;:::-;8339:424;8210:553;;;;:::o;11813:323::-;11963:8;11954:17;;:5;:17;;;11946:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;12065:8;12027:18;:25;12046:5;12027:25;;;;;;;;;;;;;;;:35;12053:8;12027:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;12110:8;12088:41;;12103:5;12088:41;;;12120:8;12088:41;;;;;;:::i;:::-;;;;;;;;11813:323;;;:::o;320:126:9:-;377:4;400:9;;;;;;;;;;;:39;;;;;414:16;:25;431:7;414:25;;;;;;;;;;;;;;;;;;;;;;;;;413:26;400:39;393:46;;320:126;;;:::o;4816:763:3:-;5011:1;4997:16;;:2;:16;;;4989:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;5066:16;5085:12;:10;:12::i;:::-;5066:31;;5108:96;5129:8;5139:4;5145:2;5149:21;5167:2;5149:17;:21::i;:::-;5172:25;5190:6;5172:17;:25::i;:::-;5199:4;5108:20;:96::i;:::-;5215:19;5237:9;:13;5247:2;5237:13;;;;;;;;;;;:19;5251:4;5237:19;;;;;;;;;;;;;;;;5215:41;;5289:6;5274:11;:21;;5266:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;5388:6;5374:11;:20;;;;:::i;:::-;5352:9;:13;5362:2;5352:13;;;;;;;;;;;:19;5366:4;5352:19;;;;;;;;;;;;;;;:42;;;;5425:6;5404:9;:13;5414:2;5404:13;;;;;;;;;;;:17;5418:2;5404:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;5478:2;5447:46;;5472:4;5447:46;;5462:8;5447:46;;;5482:2;5486:6;5447:46;;;;;;;:::i;:::-;;;;;;;;5504:68;5535:8;5545:4;5551:2;5555;5559:6;5567:4;5504:30;:68::i;:::-;4979:600;;4816:763;;;;;:::o;168:215:22:-;300:13;356:2;360;364;368;372;339:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;325:51;;168:215;;;;;;;:::o;1409:224:24:-;1621:4;1627:2;1228:25:9;1244:4;1250:2;1228:15;:25::i;:::-;1409:224:24;;;;;;;;:::o;14021:792:3:-;14253:15;:2;:13;;;:15::i;:::-;14249:558;;;14305:2;14288:43;;;14332:8;14342:4;14348:3;14353:7;14362:4;14288:79;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;14284:513;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;14673:6;14666:14;;;;;;;;;;;:::i;:::-;;;;;;;;14284:513;;;14720:62;;;;;;;;;;:::i;:::-;;;;;;;;14284:513;14458:48;;;14446:60;;;:8;:60;;;;14442:157;;14530:50;;;;;;;;;;:::i;:::-;;;;;;;;14442:157;14368:245;14249:558;14021:792;;;;;;:::o;14819:193::-;14885:16;14913:22;14952:1;14938:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14913:41;;14975:7;14964:5;14970:1;14964:8;;;;;;;;:::i;:::-;;;;;;;:18;;;;;15000:5;14993:12;;;14819:193;;;:::o;13290:725::-;13497:15;:2;:13;;;:15::i;:::-;13493:516;;;13549:2;13532:38;;;13571:8;13581:4;13587:2;13591:6;13599:4;13532:72;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;13528:471;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;13875:6;13868:14;;;;;;;;;;;:::i;:::-;;;;;;;;13528:471;;;13922:62;;;;;;;;;;:::i;:::-;;;;;;;;13528:471;13665:43;;;13653:55;;;:8;:55;;;;13649:152;;13732:50;;;;;;;;;;:::i;:::-;;;;;;;;13649:152;13605:210;13493:516;13290:725;;;;;;:::o;1047:117:9:-;557:6:20;;;;;;;;;;;556:7;:30;;;;581:5;;;;;;;;;;;567:19;;:10;:19;;;556:30;548:39;;;;;;1134:4:9::1;624:16;632:7;624;:16::i;:::-;623:17;615:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;1153:2:::2;624:16;632:7;624;:16::i;:::-;623:17;615:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;672:1;595::20::1;1047:117:9::0;;:::o;785:413:0:-;845:4;1048:12;1157:7;1145:20;1137:28;;1190:1;1183:4;:8;1176:15;;;785:413;;;:::o;7:75:25:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:126;371:7;411:42;404:5;400:54;389:65;;334:126;;;:::o;466:96::-;503:7;532:24;550:5;532:24;:::i;:::-;521:35;;466:96;;;:::o;568:122::-;641:24;659:5;641:24;:::i;:::-;634:5;631:35;621:63;;680:1;677;670:12;621:63;568:122;:::o;696:139::-;742:5;780:6;767:20;758:29;;796:33;823:5;796:33;:::i;:::-;696:139;;;;:::o;841:77::-;878:7;907:5;896:16;;841:77;;;:::o;924:122::-;997:24;1015:5;997:24;:::i;:::-;990:5;987:35;977:63;;1036:1;1033;1026:12;977:63;924:122;:::o;1052:139::-;1098:5;1136:6;1123:20;1114:29;;1152:33;1179:5;1152:33;:::i;:::-;1052:139;;;;:::o;1197:474::-;1265:6;1273;1322:2;1310:9;1301:7;1297:23;1293:32;1290:119;;;1328:79;;:::i;:::-;1290:119;1448:1;1473:53;1518:7;1509:6;1498:9;1494:22;1473:53;:::i;:::-;1463:63;;1419:117;1575:2;1601:53;1646:7;1637:6;1626:9;1622:22;1601:53;:::i;:::-;1591:63;;1546:118;1197:474;;;;;:::o;1677:118::-;1764:24;1782:5;1764:24;:::i;:::-;1759:3;1752:37;1677:118;;:::o;1801:222::-;1894:4;1932:2;1921:9;1917:18;1909:26;;1945:71;2013:1;2002:9;1998:17;1989:6;1945:71;:::i;:::-;1801:222;;;;:::o;2029:149::-;2065:7;2105:66;2098:5;2094:78;2083:89;;2029:149;;;:::o;2184:120::-;2256:23;2273:5;2256:23;:::i;:::-;2249:5;2246:34;2236:62;;2294:1;2291;2284:12;2236:62;2184:120;:::o;2310:137::-;2355:5;2393:6;2380:20;2371:29;;2409:32;2435:5;2409:32;:::i;:::-;2310:137;;;;:::o;2453:327::-;2511:6;2560:2;2548:9;2539:7;2535:23;2531:32;2528:119;;;2566:79;;:::i;:::-;2528:119;2686:1;2711:52;2755:7;2746:6;2735:9;2731:22;2711:52;:::i;:::-;2701:62;;2657:116;2453:327;;;;:::o;2786:90::-;2820:7;2863:5;2856:13;2849:21;2838:32;;2786:90;;;:::o;2882:109::-;2963:21;2978:5;2963:21;:::i;:::-;2958:3;2951:34;2882:109;;:::o;2997:210::-;3084:4;3122:2;3111:9;3107:18;3099:26;;3135:65;3197:1;3186:9;3182:17;3173:6;3135:65;:::i;:::-;2997:210;;;;:::o;3213:99::-;3265:6;3299:5;3293:12;3283:22;;3213:99;;;:::o;3318:169::-;3402:11;3436:6;3431:3;3424:19;3476:4;3471:3;3467:14;3452:29;;3318:169;;;;:::o;3493:246::-;3574:1;3584:113;3598:6;3595:1;3592:13;3584:113;;;3683:1;3678:3;3674:11;3668:18;3664:1;3659:3;3655:11;3648:39;3620:2;3617:1;3613:10;3608:15;;3584:113;;;3731:1;3722:6;3717:3;3713:16;3706:27;3555:184;3493:246;;;:::o;3745:102::-;3786:6;3837:2;3833:7;3828:2;3821:5;3817:14;3813:28;3803:38;;3745:102;;;:::o;3853:377::-;3941:3;3969:39;4002:5;3969:39;:::i;:::-;4024:71;4088:6;4083:3;4024:71;:::i;:::-;4017:78;;4104:65;4162:6;4157:3;4150:4;4143:5;4139:16;4104:65;:::i;:::-;4194:29;4216:6;4194:29;:::i;:::-;4189:3;4185:39;4178:46;;3945:285;3853:377;;;;:::o;4236:313::-;4349:4;4387:2;4376:9;4372:18;4364:26;;4436:9;4430:4;4426:20;4422:1;4411:9;4407:17;4400:47;4464:78;4537:4;4528:6;4464:78;:::i;:::-;4456:86;;4236:313;;;;:::o;4555:329::-;4614:6;4663:2;4651:9;4642:7;4638:23;4634:32;4631:119;;;4669:79;;:::i;:::-;4631:119;4789:1;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4760:117;4555:329;;;;:::o;4890:117::-;4999:1;4996;4989:12;5013:180;5061:77;5058:1;5051:88;5158:4;5155:1;5148:15;5182:4;5179:1;5172:15;5199:281;5282:27;5304:4;5282:27;:::i;:::-;5274:6;5270:40;5412:6;5400:10;5397:22;5376:18;5364:10;5361:34;5358:62;5355:88;;;5423:18;;:::i;:::-;5355:88;5463:10;5459:2;5452:22;5242:238;5199:281;;:::o;5486:129::-;5520:6;5547:20;;:::i;:::-;5537:30;;5576:33;5604:4;5596:6;5576:33;:::i;:::-;5486:129;;;:::o;5621:311::-;5698:4;5788:18;5780:6;5777:30;5774:56;;;5810:18;;:::i;:::-;5774:56;5860:4;5852:6;5848:17;5840:25;;5920:4;5914;5910:15;5902:23;;5621:311;;;:::o;5938:117::-;6047:1;6044;6037:12;6078:710;6174:5;6199:81;6215:64;6272:6;6215:64;:::i;:::-;6199:81;:::i;:::-;6190:90;;6300:5;6329:6;6322:5;6315:21;6363:4;6356:5;6352:16;6345:23;;6416:4;6408:6;6404:17;6396:6;6392:30;6445:3;6437:6;6434:15;6431:122;;;6464:79;;:::i;:::-;6431:122;6579:6;6562:220;6596:6;6591:3;6588:15;6562:220;;;6671:3;6700:37;6733:3;6721:10;6700:37;:::i;:::-;6695:3;6688:50;6767:4;6762:3;6758:14;6751:21;;6638:144;6622:4;6617:3;6613:14;6606:21;;6562:220;;;6566:21;6180:608;;6078:710;;;;;:::o;6811:370::-;6882:5;6931:3;6924:4;6916:6;6912:17;6908:27;6898:122;;6939:79;;:::i;:::-;6898:122;7056:6;7043:20;7081:94;7171:3;7163:6;7156:4;7148:6;7144:17;7081:94;:::i;:::-;7072:103;;6888:293;6811:370;;;;:::o;7187:117::-;7296:1;7293;7286:12;7310:307;7371:4;7461:18;7453:6;7450:30;7447:56;;;7483:18;;:::i;:::-;7447:56;7521:29;7543:6;7521:29;:::i;:::-;7513:37;;7605:4;7599;7595:15;7587:23;;7310:307;;;:::o;7623:146::-;7720:6;7715:3;7710;7697:30;7761:1;7752:6;7747:3;7743:16;7736:27;7623:146;;;:::o;7775:423::-;7852:5;7877:65;7893:48;7934:6;7893:48;:::i;:::-;7877:65;:::i;:::-;7868:74;;7965:6;7958:5;7951:21;8003:4;7996:5;7992:16;8041:3;8032:6;8027:3;8023:16;8020:25;8017:112;;;8048:79;;:::i;:::-;8017:112;8138:54;8185:6;8180:3;8175;8138:54;:::i;:::-;7858:340;7775:423;;;;;:::o;8217:338::-;8272:5;8321:3;8314:4;8306:6;8302:17;8298:27;8288:122;;8329:79;;:::i;:::-;8288:122;8446:6;8433:20;8471:78;8545:3;8537:6;8530:4;8522:6;8518:17;8471:78;:::i;:::-;8462:87;;8278:277;8217:338;;;;:::o;8561:1363::-;8706:6;8714;8722;8730;8779:3;8767:9;8758:7;8754:23;8750:33;8747:120;;;8786:79;;:::i;:::-;8747:120;8906:1;8931:53;8976:7;8967:6;8956:9;8952:22;8931:53;:::i;:::-;8921:63;;8877:117;9061:2;9050:9;9046:18;9033:32;9092:18;9084:6;9081:30;9078:117;;;9114:79;;:::i;:::-;9078:117;9219:78;9289:7;9280:6;9269:9;9265:22;9219:78;:::i;:::-;9209:88;;9004:303;9374:2;9363:9;9359:18;9346:32;9405:18;9397:6;9394:30;9391:117;;;9427:79;;:::i;:::-;9391:117;9532:78;9602:7;9593:6;9582:9;9578:22;9532:78;:::i;:::-;9522:88;;9317:303;9687:2;9676:9;9672:18;9659:32;9718:18;9710:6;9707:30;9704:117;;;9740:79;;:::i;:::-;9704:117;9845:62;9899:7;9890:6;9879:9;9875:22;9845:62;:::i;:::-;9835:72;;9630:287;8561:1363;;;;;;;:::o;9930:1509::-;10084:6;10092;10100;10108;10116;10165:3;10153:9;10144:7;10140:23;10136:33;10133:120;;;10172:79;;:::i;:::-;10133:120;10292:1;10317:53;10362:7;10353:6;10342:9;10338:22;10317:53;:::i;:::-;10307:63;;10263:117;10419:2;10445:53;10490:7;10481:6;10470:9;10466:22;10445:53;:::i;:::-;10435:63;;10390:118;10575:2;10564:9;10560:18;10547:32;10606:18;10598:6;10595:30;10592:117;;;10628:79;;:::i;:::-;10592:117;10733:78;10803:7;10794:6;10783:9;10779:22;10733:78;:::i;:::-;10723:88;;10518:303;10888:2;10877:9;10873:18;10860:32;10919:18;10911:6;10908:30;10905:117;;;10941:79;;:::i;:::-;10905:117;11046:78;11116:7;11107:6;11096:9;11092:22;11046:78;:::i;:::-;11036:88;;10831:303;11201:3;11190:9;11186:19;11173:33;11233:18;11225:6;11222:30;11219:117;;;11255:79;;:::i;:::-;11219:117;11360:62;11414:7;11405:6;11394:9;11390:22;11360:62;:::i;:::-;11350:72;;11144:288;9930:1509;;;;;;;;:::o;11445:329::-;11504:6;11553:2;11541:9;11532:7;11528:23;11524:32;11521:119;;;11559:79;;:::i;:::-;11521:119;11679:1;11704:53;11749:7;11740:6;11729:9;11725:22;11704:53;:::i;:::-;11694:63;;11650:117;11445:329;;;;:::o;11780:311::-;11857:4;11947:18;11939:6;11936:30;11933:56;;;11969:18;;:::i;:::-;11933:56;12019:4;12011:6;12007:17;11999:25;;12079:4;12073;12069:15;12061:23;;11780:311;;;:::o;12114:710::-;12210:5;12235:81;12251:64;12308:6;12251:64;:::i;:::-;12235:81;:::i;:::-;12226:90;;12336:5;12365:6;12358:5;12351:21;12399:4;12392:5;12388:16;12381:23;;12452:4;12444:6;12440:17;12432:6;12428:30;12481:3;12473:6;12470:15;12467:122;;;12500:79;;:::i;:::-;12467:122;12615:6;12598:220;12632:6;12627:3;12624:15;12598:220;;;12707:3;12736:37;12769:3;12757:10;12736:37;:::i;:::-;12731:3;12724:50;12803:4;12798:3;12794:14;12787:21;;12674:144;12658:4;12653:3;12649:14;12642:21;;12598:220;;;12602:21;12216:608;;12114:710;;;;;:::o;12847:370::-;12918:5;12967:3;12960:4;12952:6;12948:17;12944:27;12934:122;;12975:79;;:::i;:::-;12934:122;13092:6;13079:20;13117:94;13207:3;13199:6;13192:4;13184:6;13180:17;13117:94;:::i;:::-;13108:103;;12924:293;12847:370;;;;:::o;13223:894::-;13341:6;13349;13398:2;13386:9;13377:7;13373:23;13369:32;13366:119;;;13404:79;;:::i;:::-;13366:119;13552:1;13541:9;13537:17;13524:31;13582:18;13574:6;13571:30;13568:117;;;13604:79;;:::i;:::-;13568:117;13709:78;13779:7;13770:6;13759:9;13755:22;13709:78;:::i;:::-;13699:88;;13495:302;13864:2;13853:9;13849:18;13836:32;13895:18;13887:6;13884:30;13881:117;;;13917:79;;:::i;:::-;13881:117;14022:78;14092:7;14083:6;14072:9;14068:22;14022:78;:::i;:::-;14012:88;;13807:303;13223:894;;;;;:::o;14123:114::-;14190:6;14224:5;14218:12;14208:22;;14123:114;;;:::o;14243:184::-;14342:11;14376:6;14371:3;14364:19;14416:4;14411:3;14407:14;14392:29;;14243:184;;;;:::o;14433:132::-;14500:4;14523:3;14515:11;;14553:4;14548:3;14544:14;14536:22;;14433:132;;;:::o;14571:108::-;14648:24;14666:5;14648:24;:::i;:::-;14643:3;14636:37;14571:108;;:::o;14685:179::-;14754:10;14775:46;14817:3;14809:6;14775:46;:::i;:::-;14853:4;14848:3;14844:14;14830:28;;14685:179;;;;:::o;14870:113::-;14940:4;14972;14967:3;14963:14;14955:22;;14870:113;;;:::o;15019:732::-;15138:3;15167:54;15215:5;15167:54;:::i;:::-;15237:86;15316:6;15311:3;15237:86;:::i;:::-;15230:93;;15347:56;15397:5;15347:56;:::i;:::-;15426:7;15457:1;15442:284;15467:6;15464:1;15461:13;15442:284;;;15543:6;15537:13;15570:63;15629:3;15614:13;15570:63;:::i;:::-;15563:70;;15656:60;15709:6;15656:60;:::i;:::-;15646:70;;15502:224;15489:1;15486;15482:9;15477:14;;15442:284;;;15446:14;15742:3;15735:10;;15143:608;;;15019:732;;;;:::o;15757:373::-;15900:4;15938:2;15927:9;15923:18;15915:26;;15987:9;15981:4;15977:20;15973:1;15962:9;15958:17;15951:47;16015:108;16118:4;16109:6;16015:108;:::i;:::-;16007:116;;15757:373;;;;:::o;16136:943::-;16231:6;16239;16247;16255;16304:3;16292:9;16283:7;16279:23;16275:33;16272:120;;;16311:79;;:::i;:::-;16272:120;16431:1;16456:53;16501:7;16492:6;16481:9;16477:22;16456:53;:::i;:::-;16446:63;;16402:117;16558:2;16584:53;16629:7;16620:6;16609:9;16605:22;16584:53;:::i;:::-;16574:63;;16529:118;16686:2;16712:53;16757:7;16748:6;16737:9;16733:22;16712:53;:::i;:::-;16702:63;;16657:118;16842:2;16831:9;16827:18;16814:32;16873:18;16865:6;16862:30;16859:117;;;16895:79;;:::i;:::-;16859:117;17000:62;17054:7;17045:6;17034:9;17030:22;17000:62;:::i;:::-;16990:72;;16785:287;16136:943;;;;;;;:::o;17085:118::-;17172:24;17190:5;17172:24;:::i;:::-;17167:3;17160:37;17085:118;;:::o;17209:222::-;17302:4;17340:2;17329:9;17325:18;17317:26;;17353:71;17421:1;17410:9;17406:17;17397:6;17353:71;:::i;:::-;17209:222;;;;:::o;17437:116::-;17507:21;17522:5;17507:21;:::i;:::-;17500:5;17497:32;17487:60;;17543:1;17540;17533:12;17487:60;17437:116;:::o;17559:133::-;17602:5;17640:6;17627:20;17618:29;;17656:30;17680:5;17656:30;:::i;:::-;17559:133;;;;:::o;17698:468::-;17763:6;17771;17820:2;17808:9;17799:7;17795:23;17791:32;17788:119;;;17826:79;;:::i;:::-;17788:119;17946:1;17971:53;18016:7;18007:6;17996:9;17992:22;17971:53;:::i;:::-;17961:63;;17917:117;18073:2;18099:50;18141:7;18132:6;18121:9;18117:22;18099:50;:::i;:::-;18089:60;;18044:115;17698:468;;;;;:::o;18172:474::-;18240:6;18248;18297:2;18285:9;18276:7;18272:23;18268:32;18265:119;;;18303:79;;:::i;:::-;18265:119;18423:1;18448:53;18493:7;18484:6;18473:9;18469:22;18448:53;:::i;:::-;18438:63;;18394:117;18550:2;18576:53;18621:7;18612:6;18601:9;18597:22;18576:53;:::i;:::-;18566:63;;18521:118;18172:474;;;;;:::o;18652:1089::-;18756:6;18764;18772;18780;18788;18837:3;18825:9;18816:7;18812:23;18808:33;18805:120;;;18844:79;;:::i;:::-;18805:120;18964:1;18989:53;19034:7;19025:6;19014:9;19010:22;18989:53;:::i;:::-;18979:63;;18935:117;19091:2;19117:53;19162:7;19153:6;19142:9;19138:22;19117:53;:::i;:::-;19107:63;;19062:118;19219:2;19245:53;19290:7;19281:6;19270:9;19266:22;19245:53;:::i;:::-;19235:63;;19190:118;19347:2;19373:53;19418:7;19409:6;19398:9;19394:22;19373:53;:::i;:::-;19363:63;;19318:118;19503:3;19492:9;19488:19;19475:33;19535:18;19527:6;19524:30;19521:117;;;19557:79;;:::i;:::-;19521:117;19662:62;19716:7;19707:6;19696:9;19692:22;19662:62;:::i;:::-;19652:72;;19446:288;18652:1089;;;;;;;;:::o;19747:230::-;19887:34;19883:1;19875:6;19871:14;19864:58;19956:13;19951:2;19943:6;19939:15;19932:38;19747:230;:::o;19983:366::-;20125:3;20146:67;20210:2;20205:3;20146:67;:::i;:::-;20139:74;;20222:93;20311:3;20222:93;:::i;:::-;20340:2;20335:3;20331:12;20324:19;;19983:366;;;:::o;20355:419::-;20521:4;20559:2;20548:9;20544:18;20536:26;;20608:9;20602:4;20598:20;20594:1;20583:9;20579:17;20572:47;20636:131;20762:4;20636:131;:::i;:::-;20628:139;;20355:419;;;:::o;20780:180::-;20828:77;20825:1;20818:88;20925:4;20922:1;20915:15;20949:4;20946:1;20939:15;20966:320;21010:6;21047:1;21041:4;21037:12;21027:22;;21094:1;21088:4;21084:12;21115:18;21105:81;;21171:4;21163:6;21159:17;21149:27;;21105:81;21233:2;21225:6;21222:14;21202:18;21199:38;21196:84;;21252:18;;:::i;:::-;21196:84;21017:269;20966:320;;;:::o;21292:237::-;21432:34;21428:1;21420:6;21416:14;21409:58;21501:20;21496:2;21488:6;21484:15;21477:45;21292:237;:::o;21535:366::-;21677:3;21698:67;21762:2;21757:3;21698:67;:::i;:::-;21691:74;;21774:93;21863:3;21774:93;:::i;:::-;21892:2;21887:3;21883:12;21876:19;;21535:366;;;:::o;21907:419::-;22073:4;22111:2;22100:9;22096:18;22088:26;;22160:9;22154:4;22150:20;22146:1;22135:9;22131:17;22124:47;22188:131;22314:4;22188:131;:::i;:::-;22180:139;;21907:419;;;:::o;22332:228::-;22472:34;22468:1;22460:6;22456:14;22449:58;22541:11;22536:2;22528:6;22524:15;22517:36;22332:228;:::o;22566:366::-;22708:3;22729:67;22793:2;22788:3;22729:67;:::i;:::-;22722:74;;22805:93;22894:3;22805:93;:::i;:::-;22923:2;22918:3;22914:12;22907:19;;22566:366;;;:::o;22938:419::-;23104:4;23142:2;23131:9;23127:18;23119:26;;23191:9;23185:4;23181:20;23177:1;23166:9;23162:17;23155:47;23219:131;23345:4;23219:131;:::i;:::-;23211:139;;22938:419;;;:::o;23363:180::-;23411:77;23408:1;23401:88;23508:4;23505:1;23498:15;23532:4;23529:1;23522:15;23549:180;23597:77;23594:1;23587:88;23694:4;23691:1;23684:15;23718:4;23715:1;23708:15;23735:233;23774:3;23797:24;23815:5;23797:24;:::i;:::-;23788:33;;23843:66;23836:5;23833:77;23830:103;;23913:18;;:::i;:::-;23830:103;23960:1;23953:5;23949:13;23942:20;;23735:233;;;:::o;23974:228::-;24114:34;24110:1;24102:6;24098:14;24091:58;24183:11;24178:2;24170:6;24166:15;24159:36;23974:228;:::o;24208:366::-;24350:3;24371:67;24435:2;24430:3;24371:67;:::i;:::-;24364:74;;24447:93;24536:3;24447:93;:::i;:::-;24565:2;24560:3;24556:12;24549:19;;24208:366;;;:::o;24580:419::-;24746:4;24784:2;24773:9;24769:18;24761:26;;24833:9;24827:4;24823:20;24819:1;24808:9;24804:17;24797:47;24861:131;24987:4;24861:131;:::i;:::-;24853:139;;24580:419;;;:::o;25005:180::-;25053:77;25050:1;25043:88;25150:4;25147:1;25140:15;25174:4;25171:1;25164:15;25191:185;25231:1;25248:20;25266:1;25248:20;:::i;:::-;25243:25;;25282:20;25300:1;25282:20;:::i;:::-;25277:25;;25321:1;25311:35;;25326:18;;:::i;:::-;25311:35;25368:1;25365;25361:9;25356:14;;25191:185;;;;:::o;25382:194::-;25422:4;25442:20;25460:1;25442:20;:::i;:::-;25437:25;;25476:20;25494:1;25476:20;:::i;:::-;25471:25;;25520:1;25517;25513:9;25505:17;;25544:1;25538:4;25535:11;25532:37;;;25549:18;;:::i;:::-;25532:37;25382:194;;;;:::o;25582:176::-;25614:1;25631:20;25649:1;25631:20;:::i;:::-;25626:25;;25665:20;25683:1;25665:20;:::i;:::-;25660:25;;25704:1;25694:35;;25709:18;;:::i;:::-;25694:35;25750:1;25747;25743:9;25738:14;;25582:176;;;;:::o;25764:191::-;25804:3;25823:20;25841:1;25823:20;:::i;:::-;25818:25;;25857:20;25875:1;25857:20;:::i;:::-;25852:25;;25900:1;25897;25893:9;25886:16;;25921:3;25918:1;25915:10;25912:36;;;25928:18;;:::i;:::-;25912:36;25764:191;;;;:::o;25961:171::-;26000:3;26023:24;26041:5;26023:24;:::i;:::-;26014:33;;26069:4;26062:5;26059:15;26056:41;;26077:18;;:::i;:::-;26056:41;26124:1;26117:5;26113:13;26106:20;;25961:171;;;:::o;26138:220::-;26278:34;26274:1;26266:6;26262:14;26255:58;26347:3;26342:2;26334:6;26330:15;26323:28;26138:220;:::o;26364:366::-;26506:3;26527:67;26591:2;26586:3;26527:67;:::i;:::-;26520:74;;26603:93;26692:3;26603:93;:::i;:::-;26721:2;26716:3;26712:12;26705:19;;26364:366;;;:::o;26736:419::-;26902:4;26940:2;26929:9;26925:18;26917:26;;26989:9;26983:4;26979:20;26975:1;26964:9;26960:17;26953:47;27017:131;27143:4;27017:131;:::i;:::-;27009:139;;26736:419;;;:::o;27161:227::-;27301:34;27297:1;27289:6;27285:14;27278:58;27370:10;27365:2;27357:6;27353:15;27346:35;27161:227;:::o;27394:366::-;27536:3;27557:67;27621:2;27616:3;27557:67;:::i;:::-;27550:74;;27633:93;27722:3;27633:93;:::i;:::-;27751:2;27746:3;27742:12;27735:19;;27394:366;;;:::o;27766:419::-;27932:4;27970:2;27959:9;27955:18;27947:26;;28019:9;28013:4;28009:20;28005:1;27994:9;27990:17;27983:47;28047:131;28173:4;28047:131;:::i;:::-;28039:139;;27766:419;;;:::o;28191:634::-;28412:4;28450:2;28439:9;28435:18;28427:26;;28499:9;28493:4;28489:20;28485:1;28474:9;28470:17;28463:47;28527:108;28630:4;28621:6;28527:108;:::i;:::-;28519:116;;28682:9;28676:4;28672:20;28667:2;28656:9;28652:18;28645:48;28710:108;28813:4;28804:6;28710:108;:::i;:::-;28702:116;;28191:634;;;;;:::o;28831:224::-;28971:34;28967:1;28959:6;28955:14;28948:58;29040:7;29035:2;29027:6;29023:15;29016:32;28831:224;:::o;29061:366::-;29203:3;29224:67;29288:2;29283:3;29224:67;:::i;:::-;29217:74;;29300:93;29389:3;29300:93;:::i;:::-;29418:2;29413:3;29409:12;29402:19;;29061:366;;;:::o;29433:419::-;29599:4;29637:2;29626:9;29622:18;29614:26;;29686:9;29680:4;29676:20;29672:1;29661:9;29657:17;29650:47;29714:131;29840:4;29714:131;:::i;:::-;29706:139;;29433:419;;;:::o;29858:229::-;29998:34;29994:1;29986:6;29982:14;29975:58;30067:12;30062:2;30054:6;30050:15;30043:37;29858:229;:::o;30093:366::-;30235:3;30256:67;30320:2;30315:3;30256:67;:::i;:::-;30249:74;;30332:93;30421:3;30332:93;:::i;:::-;30450:2;30445:3;30441:12;30434:19;;30093:366;;;:::o;30465:419::-;30631:4;30669:2;30658:9;30654:18;30646:26;;30718:9;30712:4;30708:20;30704:1;30693:9;30689:17;30682:47;30746:131;30872:4;30746:131;:::i;:::-;30738:139;;30465:419;;;:::o;30890:332::-;31011:4;31049:2;31038:9;31034:18;31026:26;;31062:71;31130:1;31119:9;31115:17;31106:6;31062:71;:::i;:::-;31143:72;31211:2;31200:9;31196:18;31187:6;31143:72;:::i;:::-;30890:332;;;;;:::o;31228:228::-;31368:34;31364:1;31356:6;31352:14;31345:58;31437:11;31432:2;31424:6;31420:15;31413:36;31228:228;:::o;31462:366::-;31604:3;31625:67;31689:2;31684:3;31625:67;:::i;:::-;31618:74;;31701:93;31790:3;31701:93;:::i;:::-;31819:2;31814:3;31810:12;31803:19;;31462:366;;;:::o;31834:419::-;32000:4;32038:2;32027:9;32023:18;32015:26;;32087:9;32081:4;32077:20;32073:1;32062:9;32058:17;32051:47;32115:131;32241:4;32115:131;:::i;:::-;32107:139;;31834:419;;;:::o;32259:148::-;32361:11;32398:3;32383:18;;32259:148;;;;:::o;32413:390::-;32519:3;32547:39;32580:5;32547:39;:::i;:::-;32602:89;32684:6;32679:3;32602:89;:::i;:::-;32595:96;;32700:65;32758:6;32753:3;32746:4;32739:5;32735:16;32700:65;:::i;:::-;32790:6;32785:3;32781:16;32774:23;;32523:280;32413:390;;;;:::o;32809:915::-;33133:3;33155:95;33246:3;33237:6;33155:95;:::i;:::-;33148:102;;33267:95;33358:3;33349:6;33267:95;:::i;:::-;33260:102;;33379:95;33470:3;33461:6;33379:95;:::i;:::-;33372:102;;33491:95;33582:3;33573:6;33491:95;:::i;:::-;33484:102;;33603:95;33694:3;33685:6;33603:95;:::i;:::-;33596:102;;33715:3;33708:10;;32809:915;;;;;;;;:::o;33730:98::-;33781:6;33815:5;33809:12;33799:22;;33730:98;;;:::o;33834:168::-;33917:11;33951:6;33946:3;33939:19;33991:4;33986:3;33982:14;33967:29;;33834:168;;;;:::o;34008:373::-;34094:3;34122:38;34154:5;34122:38;:::i;:::-;34176:70;34239:6;34234:3;34176:70;:::i;:::-;34169:77;;34255:65;34313:6;34308:3;34301:4;34294:5;34290:16;34255:65;:::i;:::-;34345:29;34367:6;34345:29;:::i;:::-;34340:3;34336:39;34329:46;;34098:283;34008:373;;;;:::o;34387:1053::-;34710:4;34748:3;34737:9;34733:19;34725:27;;34762:71;34830:1;34819:9;34815:17;34806:6;34762:71;:::i;:::-;34843:72;34911:2;34900:9;34896:18;34887:6;34843:72;:::i;:::-;34962:9;34956:4;34952:20;34947:2;34936:9;34932:18;34925:48;34990:108;35093:4;35084:6;34990:108;:::i;:::-;34982:116;;35145:9;35139:4;35135:20;35130:2;35119:9;35115:18;35108:48;35173:108;35276:4;35267:6;35173:108;:::i;:::-;35165:116;;35329:9;35323:4;35319:20;35313:3;35302:9;35298:19;35291:49;35357:76;35428:4;35419:6;35357:76;:::i;:::-;35349:84;;34387:1053;;;;;;;;:::o;35446:141::-;35502:5;35533:6;35527:13;35518:22;;35549:32;35575:5;35549:32;:::i;:::-;35446:141;;;;:::o;35593:349::-;35662:6;35711:2;35699:9;35690:7;35686:23;35682:32;35679:119;;;35717:79;;:::i;:::-;35679:119;35837:1;35862:63;35917:7;35908:6;35897:9;35893:22;35862:63;:::i;:::-;35852:73;;35808:127;35593:349;;;;:::o;35948:106::-;35992:8;36041:5;36036:3;36032:15;36011:36;;35948:106;;;:::o;36060:183::-;36095:3;36133:1;36115:16;36112:23;36109:128;;;36171:1;36168;36165;36150:23;36193:34;36224:1;36218:8;36193:34;:::i;:::-;36186:41;;36109:128;36060:183;:::o;36249:711::-;36288:3;36326:4;36308:16;36305:26;36334:5;36302:39;36363:20;;:::i;:::-;36438:1;36420:16;36416:24;36413:1;36407:4;36392:49;36471:4;36465:11;36570:16;36563:4;36555:6;36551:17;36548:39;36515:18;36507:6;36504:30;36488:113;36485:146;;;36616:5;;;;36485:146;36662:6;36656:4;36652:17;36698:3;36692:10;36725:18;36717:6;36714:30;36711:43;;;36747:5;;;;;;36711:43;36795:6;36788:4;36783:3;36779:14;36775:27;36854:1;36836:16;36832:24;36826:4;36822:35;36817:3;36814:44;36811:57;;;36861:5;;;;;;;36811:57;36878;36926:6;36920:4;36916:17;36908:6;36904:30;36898:4;36878:57;:::i;:::-;36951:3;36944:10;;36292:668;;;;;36249:711;;:::o;36966:239::-;37106:34;37102:1;37094:6;37090:14;37083:58;37175:22;37170:2;37162:6;37158:15;37151:47;36966:239;:::o;37211:366::-;37353:3;37374:67;37438:2;37433:3;37374:67;:::i;:::-;37367:74;;37450:93;37539:3;37450:93;:::i;:::-;37568:2;37563:3;37559:12;37552:19;;37211:366;;;:::o;37583:419::-;37749:4;37787:2;37776:9;37772:18;37764:26;;37836:9;37830:4;37826:20;37822:1;37811:9;37807:17;37800:47;37864:131;37990:4;37864:131;:::i;:::-;37856:139;;37583:419;;;:::o;38008:227::-;38148:34;38144:1;38136:6;38132:14;38125:58;38217:10;38212:2;38204:6;38200:15;38193:35;38008:227;:::o;38241:366::-;38383:3;38404:67;38468:2;38463:3;38404:67;:::i;:::-;38397:74;;38480:93;38569:3;38480:93;:::i;:::-;38598:2;38593:3;38589:12;38582:19;;38241:366;;;:::o;38613:419::-;38779:4;38817:2;38806:9;38802:18;38794:26;;38866:9;38860:4;38856:20;38852:1;38841:9;38837:17;38830:47;38894:131;39020:4;38894:131;:::i;:::-;38886:139;;38613:419;;;:::o;39038:751::-;39261:4;39299:3;39288:9;39284:19;39276:27;;39313:71;39381:1;39370:9;39366:17;39357:6;39313:71;:::i;:::-;39394:72;39462:2;39451:9;39447:18;39438:6;39394:72;:::i;:::-;39476;39544:2;39533:9;39529:18;39520:6;39476:72;:::i;:::-;39558;39626:2;39615:9;39611:18;39602:6;39558:72;:::i;:::-;39678:9;39672:4;39668:20;39662:3;39651:9;39647:19;39640:49;39706:76;39777:4;39768:6;39706:76;:::i;:::-;39698:84;;39038:751;;;;;;;;:::o;39795:167::-;39935:19;39931:1;39923:6;39919:14;39912:43;39795:167;:::o;39968:366::-;40110:3;40131:67;40195:2;40190:3;40131:67;:::i;:::-;40124:74;;40207:93;40296:3;40207:93;:::i;:::-;40325:2;40320:3;40316:12;40309:19;;39968:366;;;:::o;40340:419::-;40506:4;40544:2;40533:9;40529:18;40521:26;;40593:9;40587:4;40583:20;40579:1;40568:9;40564:17;40557:47;40621:131;40747:4;40621:131;:::i;:::-;40613:139;;40340:419;;;:::o

Swarm Source

ipfs://2dc173cf5742d7a3354fdb4c3ec6d05c7896196940c07a2dd66d2d7c3959b7f9
Loading