Contract Address Details

0x9888F37b5828F4A1D22DaB30BF192DF75B469F5d

Token
0x9888f3-469f5d
Creator
0x2a8434–3550b9 at 0xc91243–6a5e15
Balance
0 VT
Tokens
Fetching tokens...
Transactions
1 Transactions
Transfers
0 Transfers
Gas Used
34,423
Last Balance Update
31938858
Contract name:
RegistryExtended




Optimization enabled
true
Compiler version
v0.8.4+commit.c7e474f2




Optimization runs
200
EVM Version
default




Verified at
2022-06-29T13:06:20.190017Z

Constructor Arguments

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000

Arg [0] (string) : 

              

Contract source code

//./packages/traceability/issuer/contracts$ truffle-flattener RegistryExtended.sol 
// File: @openzeppelin/contracts/utils/introspection/IERC165.sol

// 
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

/**
 * @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: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @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: @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

/**
 * @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: @openzeppelin/contracts/utils/Address.sol

// 
// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol

// 
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol

// 
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/token/ERC1155/ERC1155.sol

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;






/**
 * @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_) {
        _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");
        unchecked {
            _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");
            unchecked {
                _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");
        unchecked {
            _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");
            unchecked {
                _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: contracts/ERC1888/IERC1888.sol

// 
pragma solidity 0.8.4;

interface ERC1888 is IERC1155 {

    struct Certificate {
        uint256 topic;
        address issuer;
        bytes validityData;
        bytes data;
    }

   event IssuanceSingle(address indexed _issuer, uint256 indexed _topic, uint256 _id, uint256 _value);
   event IssuanceBatch(address indexed _issuer, uint256[] indexed _topics, uint256[] _ids, uint256[] _values);
   
   event ClaimSingle(address indexed _claimIssuer, address indexed _claimSubject, uint256 indexed _topic, uint256 _id, uint256 _value, bytes _claimData);
   event ClaimBatch(address indexed _claimIssuer, address indexed _claimSubject, uint256[] indexed _topics, uint256[] _ids, uint256[] _values, bytes[] _claimData);
   
   function issue(address _to, bytes calldata _validityData, uint256 _topic, uint256 _value, bytes calldata _data) external returns (uint256 id);
   function batchIssue(address _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external returns (uint256[] memory ids);
   
   function safeTransferAndClaimFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data, bytes calldata _claimData) external;
   function safeBatchTransferAndClaimFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data, bytes[] calldata _claimData) external;

   function claimedBalanceOf(address _owner, uint256 _id) external view returns (uint256);
   function claimedBalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

   function getCertificate(uint256 _id) external view returns (address issuer, uint256 topic, bytes memory validityCall, bytes memory data);
}

// File: contracts/Registry.sol

// 
pragma solidity 0.8.4;


/// @title Implementation of the Transferable Certificate standard ERC-1888.
/// @dev Also complies to ERC-1155: https://eips.ethereum.org/EIPS/eip-1155.
/// @dev ** Data set to 0 because there is no meaningful check yet to be done on the data
contract Registry is ERC1155, ERC1888 {

	// Storage for the Certificate structs
	mapping(uint256 => Certificate) public certificateStorage;

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

	// Incrementing nonce, used for generating certificate IDs
    uint256 internal _latestCertificateId;

	constructor(string memory _uri) ERC1155(_uri) {
		// Trigger ERC1155 constructor
	}

	/// @notice See {IERC1888-issue}.
    /// @dev `_to` cannot be the zero address.
	function issue(address _to, bytes calldata _validityData, uint256 _topic, uint256 _value, bytes calldata _data) external override returns (uint256 id) {
		require(_to != address(0x0), "_to must be non-zero.");
		
		_validate(_msgSender(), _validityData);

		id = ++_latestCertificateId;
		ERC1155._mint(_to, id, _value, new bytes(0)); // Check **

		certificateStorage[id] = Certificate({
			topic: _topic,
			issuer: _msgSender(),
			validityData: _validityData,
			data: _data
		});

		emit IssuanceSingle(_msgSender(), _topic, id, _value);
	}

	/// @notice See {IERC1888-batchIssue}.
    /// @dev `_to` cannot be the zero address.
    /// @dev `_data`, `_values` and `_validityData` must have the same length.
	function batchIssue(address _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external override returns (uint256[] memory ids) {
		require(_to != address(0x0), "_to must be non-zero.");
		require(_data.length == _values.length, "Arrays not same length");
		require(_values.length == _validityData.length, "Arrays not same length");

		ids = new uint256[](_values.length);

		address operator = _msgSender();

		for (uint256 i = 0; i <= _values.length; i++) {
			ids[i] = i + _latestCertificateId + 1;
			_validate(operator, _validityData[i]);
		}
			
		ERC1155._mintBatch(_to, ids, _values, new bytes(0)); // Check **

		for (uint256 i = 0; i < ids.length; i++) {
			certificateStorage[ids[i]] = Certificate({
				topic: _topics[i],
				issuer: operator,
				validityData: _validityData[i],
				data: _data[i]
			});
		}

		emit IssuanceBatch(operator, _topics, ids, _values);
	}

	/// @notice Allows the issuer to mint more fungible tokens for existing ERC-188 certificates.
    /// @dev Allows batch issuing to an array of _to addresses.
    /// @dev `_to` cannot be the zero address.
	function mint(uint256 _id, address _to, uint256 _quantity) external {
		require(_to != address(0x0), "_to must be non-zero.");
		require(_quantity > 0, "_quantity must be above 0.");

		Certificate memory cert = certificateStorage[_id];
		require(_msgSender() == cert.issuer, "Not original issuer");

		ERC1155._mint(_to, _id, _quantity, new bytes(0)); // Check **
	}

	/// @notice See {IERC1888-safeTransferAndClaimFrom}.
    /// @dev `_to` cannot be the zero address.
    /// @dev `_from` has to have a balance above or equal `_value`.
	function safeTransferAndClaimFrom(
		address _from,
		address _to,
		uint256 _id,
		uint256 _value,
		bytes calldata _data,
		bytes calldata _claimData
	) external override {
		Certificate memory cert = certificateStorage[_id];

		_validate(cert.issuer,  cert.validityData);

        require(_to != address(0x0), "_to must be non-zero.");
		require(_from != address(0x0), "_from address must be non-zero.");

        require(_from == _msgSender() || ERC1155.isApprovedForAll(_from, _msgSender()), "No operator approval");
        require(ERC1155.balanceOf(_from, _id) >= _value, "_from balance less than _value");

		if (_from != _to) {
			safeTransferFrom(_from, _to, _id, _value, _data);
		}

		_burn(_to, _id, _value);

		emit ClaimSingle(_from, _to, cert.topic, _id, _value, _claimData); //_claimSubject address ??
	}

	/// @notice See {IERC1888-safeBatchTransferAndClaimFrom}.
    /// @dev `_to` and `_from` cannot be the zero addresses.
    /// @dev `_from` has to have a balance above 0.
	function safeBatchTransferAndClaimFrom(
		address _from,
		address _to,
		uint256[] calldata _ids,
		uint256[] calldata _values,
		bytes calldata _data,
		bytes[] calldata _claimData
	) external override {

        require(_to != address(0x0), "_to address must be non-zero");
		require(_from != address(0x0), "_from address must be non-zero");

        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _claimData.length, "Arrays not same length.");
        require(_from == _msgSender() || ERC1155.isApprovedForAll(_from, _msgSender()), "No operator approval");

		require(_ids.length > 0, "no certificates specified");

		uint256 numberOfClaims = _ids.length;

		uint256[] memory topics = new uint256[](numberOfClaims);

		for (uint256 i = 0; i < numberOfClaims; i++) {
			Certificate memory cert = certificateStorage[_ids[i]];
			_validate(cert.issuer,  cert.validityData);
			topics[i] = cert.topic;
		}

		if (_from != _to) {
			safeBatchTransferFrom(_from, _to, _ids, _values, _data);
		}

		for (uint256 i = 0; i < numberOfClaims; i++) {
			_burn(_to, _ids[i], _values[i]);
		}

		emit ClaimBatch(_from, _to, topics, _ids, _values, _claimData);
	}

	/// @notice See {IERC1888-claimedBalanceOf}.
	function claimedBalanceOf(address _owner, uint256 _id) external override view returns (uint256) {
		return claimedBalances[_id][_owner];
	}

	/// @notice See {IERC1888-claimedBalanceOfBatch}.
	function claimedBalanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external override view returns (uint256[] memory) {
        require(_owners.length == _ids.length, "owners and ids length mismatch");

        uint256[] memory batchClaimBalances = new uint256[](_owners.length);

        for (uint256 i = 0; i < _owners.length; i++) {
            batchClaimBalances[i] = this.claimedBalanceOf(_owners[i], _ids[i]);
        }

        return batchClaimBalances;
	}

	/// @notice See {IERC1888-getCertificate}.
	function getCertificate(uint256 _id) public view override returns (address issuer, uint256 topic, bytes memory validityCall, bytes memory data) {
		require(_id <= _latestCertificateId, "_id out of bounds");

		Certificate memory certificate = certificateStorage[_id];
		return (certificate.issuer, certificate.topic, certificate.validityData, certificate.data);
	}

	/// @notice Burn certificates after they've been claimed, and increase the claimed balance.
	function _burn(address _from, uint256 _id, uint256 _value) internal override {
		ERC1155._burn(_from, _id, _value);

		claimedBalances[_id][_from] = claimedBalances[_id][_from] + _value;
	}

	/// @notice Validate if the certificate is valid against an external `_verifier` contract.
	function _validate(address _verifier, bytes memory _validityData) internal view {
		(bool success, bytes memory result) = _verifier.staticcall(_validityData);

		require(success && abi.decode(result, (bool)), "Request/certificate invalid");
	}
}

// File: contracts/RegistryExtended.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

/// @title Extension of the Transferable Certificate standard ERC-1888.
contract RegistryExtended is Registry {

    event TransferBatchMultiple(address indexed operator, address[] from, address[] to, uint256[] ids, uint256[] values);
    event ClaimBatchMultiple(address[] _claimIssuer, address[] _claimSubject, uint256[] indexed _topics, uint256[] _ids, uint256[] _values, bytes[] _claimData);

	constructor(string memory _uri) Registry(_uri) {
		// Trigger Registry constructor
	}

	/// @notice Similar to {IERC1888-batchIssue}, but not a part of the ERC-1888 standard.
    /// @dev Allows batch issuing to an array of _to addresses.
    /// @dev `_to` cannot be the zero addresses.
    /// @dev `_to`, `_data`, `_values`, `_topics` and `_validityData` must have the same length.
	function batchIssueMultiple(address[] calldata _to, bytes[] calldata _validityData, uint256[] calldata _topics, uint256[] calldata _values, bytes[] calldata _data) external returns (uint256[] memory ids) {
        require(_values.length > 0, "no values specified");

		require(_to.length == _data.length, "Arrays not same length");
		require(_data.length == _values.length, "Arrays not same length");
		require(_values.length == _validityData.length, "Arrays not same length");
		require(_validityData.length == _topics.length, "Arrays not same length");

		ids = new uint256[](_values.length);

		address operator = _msgSender();

		for (uint256 i = 0; i < _values.length; i++) {
			require(_to[i] != address(0x0), "_to must be non-zero.");
			ids[i] = i + _latestCertificateId + 1;
			_validate(operator, _validityData[i]);
		}
			
		for (uint256 i = 0; i < ids.length; i++) {
			ERC1155._mint(_to[i], ids[i], _values[i], _data[i]); // Check **

			certificateStorage[ids[i]] = Certificate({
				topic: _topics[i],
				issuer: operator,
				validityData: _validityData[i],
				data: _data[i]
			});
		}

		_latestCertificateId = ids[ids.length - 1];

		emit IssuanceBatch(operator, _topics, ids, _values);
	}

	/// @notice Similar to {ERC1155-safeBatchTransferFrom}, but not a part of the ERC-1155 standard.
    /// @dev Allows batch transferring to/from an array of addresses.
    function safeBatchTransferFromMultiple(
        address[] calldata _from,
        address[] calldata _to,
        uint256[] calldata _ids,
        uint256[] calldata _values,
        bytes[] calldata _data
    ) external {
        require(_from.length == _to.length, "Arrays not same length");
        require(_to.length == _ids.length, "Arrays not same length");
        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _data.length, "Arrays not same length.");

		for (uint256 i = 0; i < _ids.length; i++) {
            require(_from[i] != address(0x0), "_from must be non-zero.");
            require(_to[i] != address(0x0), "_to must be non-zero.");
            require(_from[i] == _msgSender() || ERC1155.isApprovedForAll(_from[i], _msgSender()), "No operator approval");
			require(ERC1155.balanceOf(_from[i], _ids[i]) >= _values[i], "Not enough balance to transfer");

            Certificate memory cert = certificateStorage[_ids[i]];

			_validate(cert.issuer,  cert.validityData);
		}

        address operator = _msgSender();

        for (uint256 i = 0; i < _ids.length; ++i) {
            _safeTransferFrom(_from[i], _to[i], _ids[i], _values[i], _data[i]);
        }

        emit TransferBatchMultiple(operator, _from, _to, _ids, _values);
    }

	/// @notice Similar to {IERC1888-safeBatchTransferAndClaimFrom}, but not a part of the ERC-1888 standard.
	/// @dev Allows batch claiming to/from an array of addresses.
	function safeBatchTransferAndClaimFromMultiple(
		address[] calldata _from,
		address[] calldata _to,
		uint256[] calldata _ids,
		uint256[] calldata _values,
		bytes[] calldata _data,
		bytes[] calldata _claimData
	) external {
        require(_ids.length > 0, "no certificates specified");

        require(_from.length == _to.length, "Arrays not same length");
        require(_to.length == _ids.length, "Arrays not same length");
        require(_ids.length == _values.length, "Arrays not same length");
		require(_values.length == _data.length, "Arrays not same length.");
		require(_data.length == _claimData.length, "Arrays not same length.");

		uint256[] memory topics = new uint256[](_ids.length);

		for (uint256 i = 0; i < _ids.length; i++) {
            require(_from[i] != address(0x0), "_from must be non-zero.");
            require(_to[i] != address(0x0), "_to must be non-zero.");
            require(_from[i] == _msgSender() || ERC1155.isApprovedForAll(_from[i], _msgSender()), "No operator approval");
			require(ERC1155.balanceOf(_from[i], _ids[i]) >= _values[i], "Not enough balance to claim");

            Certificate memory cert = certificateStorage[_ids[i]];

			_validate(cert.issuer,  cert.validityData);
		}

		for (uint256 i = 0; i < _ids.length; i++) {
			Certificate memory cert = certificateStorage[_ids[i]];
			topics[i] = cert.topic;

			if (_from[i] != _to[i]) {
            	_safeTransferFrom(_from[i], _to[i], _ids[i], _values[i], _data[i]);
			}

			_burn(_to[i], _ids[i], _values[i]);
		}

		emit ClaimBatchMultiple(_from, _to, topics, _ids, _values, _claimData);
	}
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"_uri","internalType":"string"}]},{"type":"event","name":"ApprovalForAll","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"bool","name":"approved","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimBatch","inputs":[{"type":"address","name":"_claimIssuer","internalType":"address","indexed":true},{"type":"address","name":"_claimSubject","internalType":"address","indexed":true},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimBatchMultiple","inputs":[{"type":"address[]","name":"_claimIssuer","internalType":"address[]","indexed":false},{"type":"address[]","name":"_claimSubject","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimSingle","inputs":[{"type":"address","name":"_claimIssuer","internalType":"address","indexed":true},{"type":"address","name":"_claimSubject","internalType":"address","indexed":true},{"type":"uint256","name":"_topic","internalType":"uint256","indexed":true},{"type":"uint256","name":"_id","internalType":"uint256","indexed":false},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false},{"type":"bytes","name":"_claimData","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"IssuanceBatch","inputs":[{"type":"address","name":"_issuer","internalType":"address","indexed":true},{"type":"uint256[]","name":"_topics","internalType":"uint256[]","indexed":true},{"type":"uint256[]","name":"_ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"_values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"IssuanceSingle","inputs":[{"type":"address","name":"_issuer","internalType":"address","indexed":true},{"type":"uint256","name":"_topic","internalType":"uint256","indexed":true},{"type":"uint256","name":"_id","internalType":"uint256","indexed":false},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferBatch","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransferBatchMultiple","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address[]","name":"from","internalType":"address[]","indexed":false},{"type":"address[]","name":"to","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"ids","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"values","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransferSingle","inputs":[{"type":"address","name":"operator","internalType":"address","indexed":true},{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"id","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"URI","inputs":[{"type":"string","name":"value","internalType":"string","indexed":false},{"type":"uint256","name":"id","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"balanceOfBatch","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"ids","internalType":"uint256[]"}],"name":"batchIssue","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"bytes[]","name":"_validityData","internalType":"bytes[]"},{"type":"uint256[]","name":"_topics","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"ids","internalType":"uint256[]"}],"name":"batchIssueMultiple","inputs":[{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"bytes[]","name":"_validityData","internalType":"bytes[]"},{"type":"uint256[]","name":"_topics","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"topic","internalType":"uint256"},{"type":"address","name":"issuer","internalType":"address"},{"type":"bytes","name":"validityData","internalType":"bytes"},{"type":"bytes","name":"data","internalType":"bytes"}],"name":"certificateStorage","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedBalanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"claimedBalanceOfBatch","inputs":[{"type":"address[]","name":"_owners","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimedBalances","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"issuer","internalType":"address"},{"type":"uint256","name":"topic","internalType":"uint256"},{"type":"bytes","name":"validityCall","internalType":"bytes"},{"type":"bytes","name":"data","internalType":"bytes"}],"name":"getCertificate","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApprovedForAll","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"id","internalType":"uint256"}],"name":"issue","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"bytes","name":"_validityData","internalType":"bytes"},{"type":"uint256","name":"_topic","internalType":"uint256"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mint","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_quantity","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferAndClaimFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferAndClaimFromMultiple","inputs":[{"type":"address[]","name":"_from","internalType":"address[]"},{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"},{"type":"bytes[]","name":"_claimData","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeBatchTransferFromMultiple","inputs":[{"type":"address[]","name":"_from","internalType":"address[]"},{"type":"address[]","name":"_to","internalType":"address[]"},{"type":"uint256[]","name":"_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"_values","internalType":"uint256[]"},{"type":"bytes[]","name":"_data","internalType":"bytes[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferAndClaimFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"},{"type":"bytes","name":"_claimData","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"safeTransferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"id","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setApprovalForAll","inputs":[{"type":"address","name":"operator","internalType":"address"},{"type":"bool","name":"approved","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"uri","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638673605a116100b8578063ba688a941161007c578063ba688a94146102c9578063c48238b0146102dc578063c5308dd814610307578063d6878ffb1461031a578063e985e9c51461033d578063f242432a1461037957600080fd5b80638673605a1461026a5780638838a9d71461027d5780638ed8707514610290578063a22cb465146102a3578063b93bbaa0146102b657600080fd5b80634e1273f4116100ff5780634e1273f4146101ee57806351640fee1461020e578063543d526d14610231578063760c6caf14610244578063836a10401461025757600080fd5b8062fdd58e1461013b57806301ffc9a7146101615780630e89341c146101845780632eb2c2d6146101a45780633ebbaaa5146101b9575b600080fd5b61014e610149366004614497565b61038c565b6040519081526020015b60405180910390f35b61017461016f366004614808565b610423565b6040519015158152602001610158565b610197610192366004614840565b610475565b6040516101589190614d30565b6101b76101b2366004614159565b610509565b005b61014e6101c7366004614497565b60009081526004602090815260408083206001600160a01b03949094168352929052205490565b6102016101fc366004614722565b6105a0565b6040516101589190614cbf565b61022161021c366004614840565b610701565b6040516101589493929190614b66565b61014e61023f366004614407565b6108ca565b6101b7610252366004614077565b610aed565b6101b7610265366004614892565b611056565b610201610278366004614300565b61129c565b61020161028b3660046144c0565b6116e8565b61020161029e3660046146ba565b611c63565b6101b76102b13660046143d1565b611e3a565b6101b76102c43660046144c0565b611e49565b6101b76102d7366004614584565b612482565b61014e6102ea366004614870565b600460209081526000928352604080842090915290825290205481565b6101b76103153660046141fe565b612dd6565b61032d610328366004614840565b613119565b6040516101589493929190614f67565b61017461034b366004614045565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b6101b761038736600461429e565b61325c565b60006001600160a01b0383166103fd5760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b60648201526084015b60405180910390fd5b506000908152602081815260408083206001600160a01b03949094168352929052205490565b60006001600160e01b03198216636cdb3d1360e11b148061045457506001600160e01b031982166303a24d0760e21b145b8061046f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606002805461048490615073565b80601f01602080910402602001604051908101604052809291908181526020018280546104b090615073565b80156104fd5780601f106104d2576101008083540402835291602001916104fd565b820191906000526020600020905b8154815290600101906020018083116104e057829003601f168201915b50505050509050919050565b6001600160a01b0385163314806105255750610525853361034b565b61058c5760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b60648201526084016103f4565b61059985858585856132e3565b5050505050565b606081518351146106055760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016103f4565b600083516001600160401b0381111561062e57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610657578160200160208202803683370190505b50905060005b84518110156106f9576106be85828151811061068957634e487b7160e01b600052603260045260246000fd5b60200260200101518583815181106106b157634e487b7160e01b600052603260045260246000fd5b602002602001015161038c565b8282815181106106de57634e487b7160e01b600052603260045260246000fd5b60209081029190910101526106f2816150da565b905061065d565b509392505050565b60008060608060055485111561074d5760405162461bcd60e51b81526020600482015260116024820152705f6964206f7574206f6620626f756e647360781b60448201526064016103f4565b600085815260036020908152604080832081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161079390615073565b80601f01602080910402602001604051908101604052809291908181526020018280546107bf90615073565b801561080c5780601f106107e15761010080835404028352916020019161080c565b820191906000526020600020905b8154815290600101906020018083116107ef57829003601f168201915b5050505050815260200160038201805461082590615073565b80601f016020809104026020016040519081016040528092919081815260200182805461085190615073565b801561089e5780601f106108735761010080835404028352916020019161089e565b820191906000526020600020905b81548152906001019060200180831161088157829003601f168201915b505050919092525050506020810151815160408301516060909301519199909850919650945092505050565b60006001600160a01b0388166108f25760405162461bcd60e51b81526004016103f490614f38565b6109323388888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061349b92505050565b600560008154610941906150da565b9182905550905061098188828660005b6040519080825280601f01601f19166020018201604052801561097b576020820181803683370190505b50613563565b60405180608001604052808681526020016109993390565b6001600160a01b0316815260200188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250604080516020601f87018190048102820181019092528581529181019190869086908190840183828082843760009201829052509390945250508381526003602090815260409182902084518155848201516001820180546001600160a01b0319166001600160a01b03909216919091179055918401518051929350610a6f9260028501929190910190613e05565b5060608201518051610a8b916003840191602090910190613e05565b5090505084610a973390565b6001600160a01b03167f19fdba3b3fa810260206510aa7278c70ea23c0d104195bed67bfb27a3d82fbfe8387604051610ada929190918252602082015260400190565b60405180910390a3979650505050505050565b6001600160a01b038916610b435760405162461bcd60e51b815260206004820152601c60248201527f5f746f2061646472657373206d757374206265206e6f6e2d7a65726f0000000060448201526064016103f4565b6001600160a01b038a16610b995760405162461bcd60e51b815260206004820152601e60248201527f5f66726f6d2061646472657373206d757374206265206e6f6e2d7a65726f000060448201526064016103f4565b868514610bb85760405162461bcd60e51b81526004016103f490614e7f565b848114610bd75760405162461bcd60e51b81526004016103f490614e48565b6001600160a01b038a16331480610bf35750610bf38a3361034b565b610c0f5760405162461bcd60e51b81526004016103f490614d8b565b86610c585760405162461bcd60e51b81526020600482015260196024820152781b9bc818d95c9d1a599a58d85d195cc81cdc1958da599a5959603a1b60448201526064016103f4565b866000816001600160401b03811115610c8157634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610caa578160200160208202803683370190505b50905060005b82811015610e9a576000600360008d8d85818110610cde57634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191610d2f90615073565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5b90615073565b8015610da85780601f10610d7d57610100808354040283529160200191610da8565b820191906000526020600020905b815481529060010190602001808311610d8b57829003601f168201915b50505050508152602001600382018054610dc190615073565b80601f0160208091040260200160405190810160405280929190818152602001828054610ded90615073565b8015610e3a5780601f10610e0f57610100808354040283529160200191610e3a565b820191906000526020600020905b815481529060010190602001808311610e1d57829003601f168201915b5050505050815250509050610e578160200151826040015161349b565b8060000151838381518110610e7c57634e487b7160e01b600052603260045260246000fd5b60209081029190910101525080610e92816150da565b915050610cb0565b508a6001600160a01b03168c6001600160a01b031614610f6857610f688c8c8c8c80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508b8b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c908190840183828082843760009201919091525061050992505050565b60005b82811015610fdc57610fca8c8c8c84818110610f9757634e487b7160e01b600052603260045260246000fd5b905060200201358b8b85818110610fbe57634e487b7160e01b600052603260045260246000fd5b90506020020135613633565b80610fd4816150da565b915050610f6b565b5080604051610feb9190614a71565b60405180910390208b6001600160a01b03168d6001600160a01b03167f61a69d58bffe77be60879031f7e6d3d17fab9c88a681899a549d20ae8a39f8d08d8d8d8d8b8b60405161104096959493929190614c76565b60405180910390a4505050505050505050505050565b6001600160a01b03821661107c5760405162461bcd60e51b81526004016103f490614f38565b600081116110cc5760405162461bcd60e51b815260206004820152601a60248201527f5f7175616e74697479206d7573742062652061626f766520302e00000000000060448201526064016103f4565b600083815260036020908152604080832081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161111290615073565b80601f016020809104026020016040519081016040528092919081815260200182805461113e90615073565b801561118b5780601f106111605761010080835404028352916020019161118b565b820191906000526020600020905b81548152906001019060200180831161116e57829003601f168201915b505050505081526020016003820180546111a490615073565b80601f01602080910402602001604051908101604052809291908181526020018280546111d090615073565b801561121d5780601f106111f25761010080835404028352916020019161121d565b820191906000526020600020905b81548152906001019060200180831161120057829003601f168201915b505050505081525050905080602001516001600160a01b031661123d3390565b6001600160a01b0316146112895760405162461bcd60e51b81526020600482015260136024820152722737ba1037b934b3b4b730b61034b9b9bab2b960691b60448201526064016103f4565b6112968385846000610951565b50505050565b60606001600160a01b038a166112c45760405162461bcd60e51b81526004016103f490614f38565b8184146112e35760405162461bcd60e51b81526004016103f490614e7f565b8388146113025760405162461bcd60e51b81526004016103f490614e7f565b836001600160401b0381111561132857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611351578160200160208202803683370190505b5090503360005b8581116114255760055461136c9082615018565b611377906001615018565b83828151811061139757634e487b7160e01b600052603260045260246000fd5b602002602001018181525050611413828c8c848181106113c757634e487b7160e01b600052603260045260246000fd5b90506020028101906113d99190614fb1565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061349b92505050565b8061141d816150da565b915050611358565b506114948b8388888080602002602001604051908101604052809392919081815260200183836020028082843760009201829052509250611464915050565b6040519080825280601f01601f19166020018201604052801561148e576020820181803683370190505b50613698565b60005b825181101561167c5760405180608001604052808a8a848181106114cb57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001836001600160a01b031681526020018c8c8481811061150657634e487b7160e01b600052603260045260246000fd5b90506020028101906115189190614fb1565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509082525060200186868481811061157257634e487b7160e01b600052603260045260246000fd5b90506020028101906115849190614fb1565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509390945250508551600392508690859081106115e057634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002019080519060200190611649929190613e05565b5060608201518051611665916003840191602090910190613e05565b509050508080611674906150da565b915050611497565b50878760405161168d929190614a47565b6040518091039020816001600160a01b03167f4337762bcc37db59d5eea698d442c9782e625db731704f4f83ed376a09b64e6c8489896040516116d293929190614cd2565b60405180910390a3509998505050505050505050565b60608361172d5760405162461bcd60e51b81526020600482015260136024820152721b9bc81d985b1d595cc81cdc1958da599a5959606a1b60448201526064016103f4565b89821461174c5760405162461bcd60e51b81526004016103f490614e7f565b81841461176b5760405162461bcd60e51b81526004016103f490614e7f565b83881461178a5760405162461bcd60e51b81526004016103f490614e7f565b8786146117a95760405162461bcd60e51b81526004016103f490614e7f565b836001600160401b038111156117cf57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156117f8578160200160208202803683370190505b5090503360005b858110156118df5760008d8d8381811061182957634e487b7160e01b600052603260045260246000fd5b905060200201602081019061183e9190614024565b6001600160a01b031614156118655760405162461bcd60e51b81526004016103f490614f38565b6005546118729082615018565b61187d906001615018565b83828151811061189d57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506118cd828c8c848181106113c757634e487b7160e01b600052603260045260246000fd5b806118d7816150da565b9150506117ff565b5060005b8251811015611bbb576119df8d8d8381811061190f57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906119249190614024565b84838151811061194457634e487b7160e01b600052603260045260246000fd5b602002602001015189898581811061196c57634e487b7160e01b600052603260045260246000fd5b9050602002013588888681811061199357634e487b7160e01b600052603260045260246000fd5b90506020028101906119a59190614fb1565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061356392505050565b60405180608001604052808a8a84818110611a0a57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001836001600160a01b031681526020018c8c84818110611a4557634e487b7160e01b600052603260045260246000fd5b9050602002810190611a579190614fb1565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001868684818110611ab157634e487b7160e01b600052603260045260246000fd5b9050602002810190611ac39190614fb1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939094525050855160039250869085908110611b1f57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506040820151816002019080519060200190611b88929190613e05565b5060608201518051611ba4916003840191602090910190613e05565b509050508080611bb3906150da565b9150506118e3565b508160018351611bcb9190615030565b81518110611be957634e487b7160e01b600052603260045260246000fd5b60200260200101516005819055508787604051611c07929190614a47565b6040518091039020816001600160a01b03167f4337762bcc37db59d5eea698d442c9782e625db731704f4f83ed376a09b64e6c848989604051611c4c93929190614cd2565b60405180910390a3509a9950505050505050505050565b6060838214611cb45760405162461bcd60e51b815260206004820152601e60248201527f6f776e65727320616e6420696473206c656e677468206d69736d61746368000060448201526064016103f4565b6000846001600160401b03811115611cdc57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611d05578160200160208202803683370190505b50905060005b85811015611e305730633ebbaaa5888884818110611d3957634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611d4e9190614024565b878785818110611d6e57634e487b7160e01b600052603260045260246000fd5b6040516001600160e01b031960e087901b1681526001600160a01b039094166004850152602002919091013560248301525060440160206040518083038186803b158015611dbb57600080fd5b505afa158015611dcf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df39190614858565b828281518110611e1357634e487b7160e01b600052603260045260246000fd5b602090810291909101015280611e28816150da565b915050611d0b565b5095945050505050565b611e453383836137ff565b5050565b888714611e685760405162461bcd60e51b81526004016103f490614e7f565b868514611e875760405162461bcd60e51b81526004016103f490614e7f565b848314611ea65760405162461bcd60e51b81526004016103f490614e7f565b828114611ec55760405162461bcd60e51b81526004016103f490614e48565b60005b858110156122e15760008b8b83818110611ef257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611f079190614024565b6001600160a01b03161415611f585760405162461bcd60e51b81526020600482015260176024820152762fb33937b69036bab9ba103132903737b716bd32b9379760491b60448201526064016103f4565b6000898983818110611f7a57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611f8f9190614024565b6001600160a01b03161415611fb65760405162461bcd60e51b81526004016103f490614f38565b338b8b83818110611fd757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611fec9190614024565b6001600160a01b0316148061203a575061203a8b8b8381811061201f57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906120349190614024565b3361034b565b6120565760405162461bcd60e51b81526004016103f490614d8b565b84848281811061207657634e487b7160e01b600052603260045260246000fd5b905060200201356120e18c8c848181106120a057634e487b7160e01b600052603260045260246000fd5b90506020020160208101906120b59190614024565b8989858181106120d557634e487b7160e01b600052603260045260246000fd5b9050602002013561038c565b101561212f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682062616c616e636520746f207472616e73666572000060448201526064016103f4565b60006003600089898581811061215557634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b03169381019390935260028101805491928401916121a690615073565b80601f01602080910402602001604051908101604052809291908181526020018280546121d290615073565b801561221f5780601f106121f45761010080835404028352916020019161221f565b820191906000526020600020905b81548152906001019060200180831161220257829003601f168201915b5050505050815260200160038201805461223890615073565b80601f016020809104026020016040519081016040528092919081815260200182805461226490615073565b80156122b15780601f10612286576101008083540402835291602001916122b1565b820191906000526020600020905b81548152906001019060200180831161229457829003601f168201915b50505050508152505090506122ce8160200151826040015161349b565b50806122d9816150da565b915050611ec8565b503360005b86811015612425576124158c8c8381811061231157634e487b7160e01b600052603260045260246000fd5b90506020020160208101906123269190614024565b8b8b8481811061234657634e487b7160e01b600052603260045260246000fd5b905060200201602081019061235b9190614024565b8a8a8581811061237b57634e487b7160e01b600052603260045260246000fd5b905060200201358989868181106123a257634e487b7160e01b600052603260045260246000fd5b905060200201358888878181106123c957634e487b7160e01b600052603260045260246000fd5b90506020028101906123db9190614fb1565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506138e092505050565b61241e816150da565b90506122e6565b50806001600160a01b03167f9a17c5980bc0d14e313aaa844f04cd0ee291f743df00bf06337a3ce1db563be48c8c8c8c8c8c8c8c60405161246d989796959493929190614b9f565b60405180910390a25050505050505050505050565b866124cb5760405162461bcd60e51b81526020600482015260196024820152781b9bc818d95c9d1a599a58d85d195cc81cdc1958da599a5959603a1b60448201526064016103f4565b8a89146124ea5760405162461bcd60e51b81526004016103f490614e7f565b8887146125095760405162461bcd60e51b81526004016103f490614e7f565b8685146125285760405162461bcd60e51b81526004016103f490614e7f565b8483146125475760405162461bcd60e51b81526004016103f490614e48565b8281146125665760405162461bcd60e51b81526004016103f490614e48565b6000876001600160401b0381111561258e57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156125b7578160200160208202803683370190505b50905060005b888110156129af5760008e8e838181106125e757634e487b7160e01b600052603260045260246000fd5b90506020020160208101906125fc9190614024565b6001600160a01b0316141561264d5760405162461bcd60e51b81526020600482015260176024820152762fb33937b69036bab9ba103132903737b716bd32b9379760491b60448201526064016103f4565b60008c8c8381811061266f57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906126849190614024565b6001600160a01b031614156126ab5760405162461bcd60e51b81526004016103f490614f38565b338e8e838181106126cc57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906126e19190614024565b6001600160a01b0316148061271457506127148e8e8381811061201f57634e487b7160e01b600052603260045260246000fd5b6127305760405162461bcd60e51b81526004016103f490614d8b565b87878281811061275057634e487b7160e01b600052603260045260246000fd5b905060200201356127af8f8f8481811061277a57634e487b7160e01b600052603260045260246000fd5b905060200201602081019061278f9190614024565b8c8c858181106120d557634e487b7160e01b600052603260045260246000fd5b10156127fd5760405162461bcd60e51b815260206004820152601b60248201527f4e6f7420656e6f7567682062616c616e636520746f20636c61696d000000000060448201526064016103f4565b6000600360008c8c8581811061282357634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b031693810193909352600281018054919284019161287490615073565b80601f01602080910402602001604051908101604052809291908181526020018280546128a090615073565b80156128ed5780601f106128c2576101008083540402835291602001916128ed565b820191906000526020600020905b8154815290600101906020018083116128d057829003601f168201915b5050505050815260200160038201805461290690615073565b80601f016020809104026020016040519081016040528092919081815260200182805461293290615073565b801561297f5780601f106129545761010080835404028352916020019161297f565b820191906000526020600020905b81548152906001019060200180831161296257829003601f168201915b505050505081525050905061299c8160200151826040015161349b565b50806129a7816150da565b9150506125bd565b5060005b88811015612d67576000600360008c8c858181106129e157634e487b7160e01b600052603260045260246000fd5b6020908102929092013583525081810192909252604090810160002081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191612a3290615073565b80601f0160208091040260200160405190810160405280929190818152602001828054612a5e90615073565b8015612aab5780601f10612a8057610100808354040283529160200191612aab565b820191906000526020600020905b815481529060010190602001808311612a8e57829003601f168201915b50505050508152602001600382018054612ac490615073565b80601f0160208091040260200160405190810160405280929190818152602001828054612af090615073565b8015612b3d5780601f10612b1257610100808354040283529160200191612b3d565b820191906000526020600020905b815481529060010190602001808311612b2057829003601f168201915b50505050508152505090508060000151838381518110612b6d57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508c8c83818110612b9957634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612bae9190614024565b6001600160a01b03168f8f84818110612bd757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612bec9190614024565b6001600160a01b031614612cd557612cd58f8f84818110612c1d57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612c329190614024565b8e8e85818110612c5257634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612c679190614024565b8d8d86818110612c8757634e487b7160e01b600052603260045260246000fd5b905060200201358c8c87818110612cae57634e487b7160e01b600052603260045260246000fd5b905060200201358b8b888181106123c957634e487b7160e01b600052603260045260246000fd5b612d548d8d84818110612cf857634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612d0d9190614024565b8c8c85818110612d2d57634e487b7160e01b600052603260045260246000fd5b905060200201358b8b86818110610fbe57634e487b7160e01b600052603260045260246000fd5b5080612d5f816150da565b9150506129b3565b5080604051612d769190614a71565b60405180910390207f5fb4aec6c096dfcae3899570b7e14f9743bb4b1801780db6d8a9c4ffe21aaaac8e8e8e8e8e8e8e8e8c8c604051612dbf9a99989796959493929190614bff565b60405180910390a250505050505050505050505050565b600086815260036020908152604080832081516080810183528154815260018201546001600160a01b0316938101939093526002810180549192840191612e1c90615073565b80601f0160208091040260200160405190810160405280929190818152602001828054612e4890615073565b8015612e955780601f10612e6a57610100808354040283529160200191612e95565b820191906000526020600020905b815481529060010190602001808311612e7857829003601f168201915b50505050508152602001600382018054612eae90615073565b80601f0160208091040260200160405190810160405280929190818152602001828054612eda90615073565b8015612f275780601f10612efc57610100808354040283529160200191612f27565b820191906000526020600020905b815481529060010190602001808311612f0a57829003601f168201915b5050505050815250509050612f448160200151826040015161349b565b6001600160a01b038816612f6a5760405162461bcd60e51b81526004016103f490614f38565b6001600160a01b038916612fc05760405162461bcd60e51b815260206004820152601f60248201527f5f66726f6d2061646472657373206d757374206265206e6f6e2d7a65726f2e0060448201526064016103f4565b6001600160a01b038916331480612fdc5750612fdc893361034b565b612ff85760405162461bcd60e51b81526004016103f490614d8b565b856130038a8961038c565b10156130515760405162461bcd60e51b815260206004820152601e60248201527f5f66726f6d2062616c616e6365206c657373207468616e205f76616c7565000060448201526064016103f4565b876001600160a01b0316896001600160a01b0316146130ad576130ad8989898989898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061325c92505050565b6130b8888888613633565b8060000151886001600160a01b03168a6001600160a01b03167fde6a12665e566ee081354e23cd8474944fb8e89a25b46f2f9b50d378e7e536088a8a88886040516131069493929190614f91565b60405180910390a4505050505050505050565b60036020526000908152604090208054600182015460028301805492936001600160a01b039092169261314b90615073565b80601f016020809104026020016040519081016040528092919081815260200182805461317790615073565b80156131c45780601f10613199576101008083540402835291602001916131c4565b820191906000526020600020905b8154815290600101906020018083116131a757829003601f168201915b5050505050908060030180546131d990615073565b80601f016020809104026020016040519081016040528092919081815260200182805461320590615073565b80156132525780601f1061322757610100808354040283529160200191613252565b820191906000526020600020905b81548152906001019060200180831161323557829003601f168201915b5050505050905084565b6001600160a01b0385163314806132785750613278853361034b565b6132d65760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016103f4565b61059985858585856138e0565b81518351146133045760405162461bcd60e51b81526004016103f490614eaf565b6001600160a01b03841661332a5760405162461bcd60e51b81526004016103f490614db9565b3360005b845181101561342d57600085828151811061335957634e487b7160e01b600052603260045260246000fd5b60200260200101519050600085838151811061338557634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600084815280835260408082206001600160a01b038e1683529093529190912054909150818110156133d55760405162461bcd60e51b81526004016103f490614dfe565b6000838152602081815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290613412908490615018565b9250508190555050505080613426906150da565b905061332e565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161347d929190614d02565b60405180910390a46134938187878787876139fd565b505050505050565b600080836001600160a01b0316836040516134b69190614aa7565b600060405180830381855afa9150503d80600081146134f1576040519150601f19603f3d011682016040523d82523d6000602084013e6134f6565b606091505b509150915081801561351757508080602001905181019061351791906147ec565b6112965760405162461bcd60e51b815260206004820152601b60248201527f526571756573742f636572746966696361746520696e76616c6964000000000060448201526064016103f4565b6001600160a01b0384166135895760405162461bcd60e51b81526004016103f490614ef7565b336135a38160008761359a88613b68565b61059988613b68565b6000848152602081815260408083206001600160a01b0389168452909152812080548592906135d3908490615018565b909155505060408051858152602081018590526001600160a01b0380881692600092918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a461059981600087878787613bc1565b61363e838383613c8b565b60008281526004602090815260408083206001600160a01b038716845290915290205461366c908290615018565b60009283526004602090815260408085206001600160a01b039096168552949052929091209190915550565b6001600160a01b0384166136be5760405162461bcd60e51b81526004016103f490614ef7565b81518351146136df5760405162461bcd60e51b81526004016103f490614eaf565b3360005b84518110156137975783818151811061370c57634e487b7160e01b600052603260045260246000fd5b602002602001015160008087848151811061373757634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461377f9190615018565b9091555081905061378f816150da565b9150506136e3565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516137e8929190614d02565b60405180910390a4610599816000878787876139fd565b816001600160a01b0316836001600160a01b031614156138735760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016103f4565b6001600160a01b03838116600081815260016020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0384166139065760405162461bcd60e51b81526004016103f490614db9565b3361391681878761359a88613b68565b6000848152602081815260408083206001600160a01b038a168452909152902054838110156139575760405162461bcd60e51b81526004016103f490614dfe565b6000858152602081815260408083206001600160a01b038b8116855292528083208785039055908816825281208054869290613994908490615018565b909155505060408051868152602081018690526001600160a01b03808916928a821692918616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46139f4828888888888613bc1565b50505050505050565b6001600160a01b0384163b156134935760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190613a419089908990889088908890600401614ac3565b602060405180830381600087803b158015613a5b57600080fd5b505af1925050508015613a8b575060408051601f3d908101601f19168201909252613a8891810190614824565b60015b613b3857613a97615121565b806308c379a01415613ad15750613aac615139565b80613ab75750613ad3565b8060405162461bcd60e51b81526004016103f49190614d30565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e20455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016103f4565b6001600160e01b0319811663bc197c8160e01b146139f45760405162461bcd60e51b81526004016103f490614d43565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110613bb057634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b156134935760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190613c059089908990889088908890600401614b21565b602060405180830381600087803b158015613c1f57600080fd5b505af1925050508015613c4f575060408051601f3d908101601f19168201909252613c4c91810190614824565b60015b613c5b57613a97615121565b6001600160e01b0319811663f23a6e6160e01b146139f45760405162461bcd60e51b81526004016103f490614d43565b6001600160a01b038316613ced5760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201526265737360e81b60648201526084016103f4565b33613d1d81856000613cfe87613b68565b613d0787613b68565b5050604080516020810190915260009052505050565b6000838152602081815260408083206001600160a01b038816845290915290205482811015613d9a5760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c604482015263616e636560e01b60648201526084016103f4565b6000848152602081815260408083206001600160a01b03898116808652918452828520888703905582518981529384018890529092908616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b828054613e1190615073565b90600052602060002090601f016020900481019282613e335760008555613e79565b82601f10613e4c57805160ff1916838001178555613e79565b82800160010185558215613e79579182015b82811115613e79578251825591602001919060010190613e5e565b50613e85929150613e89565b5090565b5b80821115613e855760008155600101613e8a565b80356001600160a01b0381168114613eb557600080fd5b919050565b60008083601f840112613ecb578182fd5b5081356001600160401b03811115613ee1578182fd5b6020830191508360208260051b8501011115613efc57600080fd5b9250929050565b600082601f830112613f13578081fd5b81356020613f2082614ff5565b604051613f2d82826150ae565b8381528281019150858301600585901b87018401881015613f4c578586fd5b855b85811015613f6a57813584529284019290840190600101613f4e565b5090979650505050505050565b60008083601f840112613f88578182fd5b5081356001600160401b03811115613f9e578182fd5b602083019150836020828501011115613efc57600080fd5b600082601f830112613fc6578081fd5b81356001600160401b03811115613fdf57613fdf61510b565b604051613ff6601f8301601f1916602001826150ae565b81815284602083860101111561400a578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215614035578081fd5b61403e82613e9e565b9392505050565b60008060408385031215614057578081fd5b61406083613e9e565b915061406e60208401613e9e565b90509250929050565b60008060008060008060008060008060c08b8d031215614095578586fd5b61409e8b613e9e565b99506140ac60208c01613e9e565b985060408b01356001600160401b03808211156140c7578788fd5b6140d38e838f01613eba565b909a50985060608d01359150808211156140eb578788fd5b6140f78e838f01613eba565b909850965060808d013591508082111561410f578586fd5b61411b8e838f01613f77565b909650945060a08d0135915080821115614133578384fd5b506141408d828e01613eba565b915080935050809150509295989b9194979a5092959850565b600080600080600060a08688031215614170578081fd5b61417986613e9e565b945061418760208701613e9e565b935060408601356001600160401b03808211156141a2578283fd5b6141ae89838a01613f03565b945060608801359150808211156141c3578283fd5b6141cf89838a01613f03565b935060808801359150808211156141e4578283fd5b506141f188828901613fb6565b9150509295509295909350565b60008060008060008060008060c0898b031215614219578384fd5b61422289613e9e565b975061423060208a01613e9e565b9650604089013595506060890135945060808901356001600160401b0380821115614259578586fd5b6142658c838d01613f77565b909650945060a08b013591508082111561427d578384fd5b5061428a8b828c01613f77565b999c989b5096995094979396929594505050565b600080600080600060a086880312156142b5578283fd5b6142be86613e9e565b94506142cc60208701613e9e565b9350604086013592506060860135915060808601356001600160401b038111156142f4578182fd5b6141f188828901613fb6565b600080600080600080600080600060a08a8c03121561431d578283fd5b6143268a613e9e565b985060208a01356001600160401b0380821115614341578485fd5b61434d8d838e01613eba565b909a50985060408c0135915080821115614365578485fd5b6143718d838e01613eba565b909850965060608c0135915080821115614389578485fd5b6143958d838e01613eba565b909650945060808c01359150808211156143ad578384fd5b506143ba8c828d01613eba565b915080935050809150509295985092959850929598565b600080604083850312156143e3578182fd5b6143ec83613e9e565b915060208301356143fc816151c2565b809150509250929050565b600080600080600080600060a0888a031215614421578081fd5b61442a88613e9e565b965060208801356001600160401b0380821115614445578283fd5b6144518b838c01613f77565b909850965060408a0135955060608a0135945060808a0135915080821115614477578283fd5b506144848a828b01613f77565b989b979a50959850939692959293505050565b600080604083850312156144a9578182fd5b6144b283613e9e565b946020939093013593505050565b60008060008060008060008060008060a08b8d0312156144de578384fd5b8a356001600160401b03808211156144f4578586fd5b6145008e838f01613eba565b909c509a5060208d0135915080821115614518578586fd5b6145248e838f01613eba565b909a50985060408d013591508082111561453c578586fd5b6145488e838f01613eba565b909850965060608d0135915080821115614560578586fd5b61456c8e838f01613eba565b909650945060808d0135915080821115614133578384fd5b60008060008060008060008060008060008060c08d8f0312156145a5578586fd5b6001600160401b038d3511156145b9578586fd5b6145c68e8e358f01613eba565b909c509a506001600160401b0360208e013511156145e2578586fd5b6145f28e60208f01358f01613eba565b909a5098506001600160401b0360408e0135111561460e578586fd5b61461e8e60408f01358f01613eba565b90985096506001600160401b0360608e0135111561463a578586fd5b61464a8e60608f01358f01613eba565b90965094506001600160401b0360808e01351115614666578081fd5b6146768e60808f01358f01613eba565b90945092506001600160401b0360a08e01351115614692578081fd5b6146a28e60a08f01358f01613eba565b81935080925050509295989b509295989b509295989b565b600080600080604085870312156146cf578182fd5b84356001600160401b03808211156146e5578384fd5b6146f188838901613eba565b90965094506020870135915080821115614709578384fd5b5061471687828801613eba565b95989497509550505050565b60008060408385031215614734578182fd5b82356001600160401b038082111561474a578384fd5b818501915085601f83011261475d578384fd5b8135602061476a82614ff5565b60405161477782826150ae565b8381528281019150858301600585901b870184018b1015614796578889fd5b8896505b848710156147bf576147ab81613e9e565b83526001969096019591830191830161479a565b50965050860135925050808211156147d5578283fd5b506147e285828601613f03565b9150509250929050565b6000602082840312156147fd578081fd5b815161403e816151c2565b600060208284031215614819578081fd5b813561403e816151d3565b600060208284031215614835578081fd5b815161403e816151d3565b600060208284031215614851578081fd5b5035919050565b600060208284031215614869578081fd5b5051919050565b60008060408385031215614882578182fd5b8235915061406e60208401613e9e565b6000806000606084860312156148a6578081fd5b833592506148b660208501613e9e565b9150604084013590509250925092565b81835260006020808501945082825b85811015614901576001600160a01b036148ee83613e9e565b16875295820195908201906001016148d5565b509495945050505050565b60008383855260208086019550808560051b83010184845b87811015613f6a57848303601f19018952813536889003601e19018112614949578687fd5b870180356001600160401b03811115614960578788fd5b80360389131561496e578788fd5b61497b85828885016149f2565b9a86019a9450505090830190600101614924565b81835260006001600160fb1b038311156149a7578081fd5b8260051b80836020870137939093016020019283525090919050565b6000815180845260208085019450808401835b83811015614901578151875295820195908201906001016149d6565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60008151808452614a33816020860160208601615047565b601f01601f19169290920160200192915050565b60006001600160fb1b03831115614a5c578081fd5b8260051b808584379190910190815292915050565b815160009082906020808601845b83811015614a9b57815185529382019390820190600101614a7f565b50929695505050505050565b60008251614ab9818460208701615047565b9190910192915050565b6001600160a01b0386811682528516602082015260a060408201819052600090614aef908301866149c3565b8281036060840152614b0181866149c3565b90508281036080840152614b158185614a1b565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a060808201819052600090614b5b90830184614a1b565b979650505050505050565b60018060a01b0385168152836020820152608060408201526000614b8d6080830185614a1b565b8281036060840152614b5b8185614a1b565b608081526000614bb3608083018a8c6148c6565b8281036020840152614bc681898b6148c6565b90508281036040840152614bdb81878961498f565b90508281036060840152614bf081858761498f565b9b9a5050505050505050505050565b60a081526000614c1360a083018c8e6148c6565b8281036020840152614c26818b8d6148c6565b90508281036040840152614c3b81898b61498f565b90508281036060840152614c5081878961498f565b90508281036080840152614c6581858761490c565b9d9c50505050505050505050505050565b606081526000614c8a60608301888a61498f565b8281036020840152614c9d81878961498f565b90508281036040840152614cb281858761490c565b9998505050505050505050565b60208152600061403e60208301846149c3565b604081526000614ce560408301866149c3565b8281036020840152614cf881858761498f565b9695505050505050565b604081526000614d1560408301856149c3565b8281036020840152614d2781856149c3565b95945050505050565b60208152600061403e6020830184614a1b565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b602080825260149082015273139bc81bdc195c985d1bdc88185c1c1c9bdd985b60621b604082015260600190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b60208082526017908201527f417272617973206e6f742073616d65206c656e6774682e000000000000000000604082015260600190565b602080825260169082015275082e4e4c2f2e640dcdee840e6c2daca40d8cadccee8d60531b604082015260600190565b60208082526028908201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b60208082526021908201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736040820152607360f81b606082015260800190565b6020808252601590820152742fba379036bab9ba103132903737b716bd32b9379760591b604082015260600190565b8481526001600160a01b0384166020820152608060408201819052600090614b8d90830185614a1b565b848152836020820152606060408201526000614cf86060830184866149f2565b6000808335601e19843603018112614fc7578283fd5b8301803591506001600160401b03821115614fe0578283fd5b602001915036819003821315613efc57600080fd5b60006001600160401b0382111561500e5761500e61510b565b5060051b60200190565b6000821982111561502b5761502b6150f5565b500190565b600082821015615042576150426150f5565b500390565b60005b8381101561506257818101518382015260200161504a565b838111156112965750506000910152565b600181811c9082168061508757607f821691505b602082108114156150a857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f191681016001600160401b03811182821017156150d3576150d361510b565b6040525050565b60006000198214156150ee576150ee6150f5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d111561513657600481823e5160e01c5b90565b600060443d10156151475790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561517657505050505090565b828501915081518181111561518e5750505050505090565b843d87010160208285010111156151a85750505050505090565b6151b7602082860101876150ae565b509095945050505050565b80151581146151d057600080fd5b50565b6001600160e01b0319811681146151d057600080fdfea264697066735822122046750d6d1b96298264a7e23c3b8923a5608900dfbc4cbe71fef61ee1a98decd464736f6c63430008040033