Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ERC1155Hatches
- Optimization enabled
- false
- Compiler version
- v0.8.20+commit.a1b79de6
- EVM Version
- paris
- Verified at
- 2024-06-01T15:57:15.122745Z
Constructor Arguments
0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f486f706576657273652048617463680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a486174636820466f6d756c6120666f7220486f70657665727365000000000000
Arg [0] (string) : Hopeverse Hatch
Arg [1] (string) : Hatch Fomula for Hopeverse
contracts/Craftable/ERC1155Hatches.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../base/TokenOperatableTemplateContract.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; contract ERC1155Hatches is TokenOperatableTemplateContract { using Math for uint256; using ERC165Checker for address; struct HatchFormula { address input_token_address; uint256 input_token_id; address output_token_address; uint256 output_token_id; bool output_as_multitoken; uint256 hatch_block_count; } struct HatchState { uint256 template_id; uint256 begin_block; uint256 hatched_block; uint256 amount; address hatcher; } mapping(uint256 => HatchFormula) private templates; mapping(address => uint256[]) private user_hatching; mapping (uint256 => HatchState) private hatch_states; uint256 private _templateIds; uint256 private _hatchIds; event OnHatchFormulaDefined(uint256 indexed template_id,HatchFormula formula); event OnHatchFormulaUpdated(uint256 indexed template_id,HatchFormula formula); event OnHatchingBegin(address indexed addr,uint256 indexed hatch_id,HatchState state); event OnHatched(address indexed addr,uint256 indexed hatch_id,HatchState state); constructor(string memory name_,string memory description_) TokenOperatableTemplateContract(name_,description_) { } function get_last_template_id() public view virtual override returns (uint256) {return _templateIds;} function get_last_hatch_id() public view virtual returns (uint256) {return _hatchIds;} function on_hatching(address addr) public view returns (uint256[] memory){ return user_hatching[addr]; } function hatch_state(uint256 id) public view returns (uint256,uint256,uint256,uint256,address){ HatchState memory st = hatch_states[id]; return (st.template_id,st.begin_block,st.hatched_block,st.amount,st.hatcher); } function create_hatch(uint256 template_id,uint256 applyCount) external payable{ require(applyCount > 0,"ZERO_APPLY_COUNT"); require(is_enabled(template_id),"TEMPLATE_DISABLED"); _check_valid_token(template_id); uint256 current_block = block.number - 1; HatchFormula memory template = templates[template_id]; (bool result,uint256 hatch_id) = _hatchIds.tryAdd(1); require(result,"HATCH_ID_OVERFLOW"); (bool block_result,uint256 total_block_count) = template.hatch_block_count.tryMul(applyCount); require(block_result,"BLOCKCOUNT_OVERFLOW"); IOperatableERC1155Token(template.input_token_address).burnNFTFor(msg.sender, template.input_token_id,applyCount); _hatchIds = hatch_id; hatch_states[hatch_id] = HatchState(template_id,current_block,0,applyCount,msg.sender); user_hatching[msg.sender].push(hatch_id); consume_operation_cost(template_id,applyCount); emit OnHatchingBegin(msg.sender,hatch_id,hatch_states[hatch_id]); } function do_hatch(uint256 hatch_id) external { (bool result,uint256 index) = get_user_hatch_index(msg.sender,hatch_id); require(result,"NOT_USER_HATCHING"); HatchState memory st = hatch_states[hatch_id]; require(is_enabled(st.template_id),"TEMPLATE_DISABLED"); _check_valid_token(st.template_id); uint256 current_block = block.number - 1; require(current_block >= st.begin_block,"HATCH_BLOCK_ERR"); HatchFormula memory template = templates[st.template_id]; (bool block_result,uint256 total_block_count) = template.hatch_block_count.tryMul(st.amount); require(block_result && ((current_block - st.begin_block) >= total_block_count),"HATCH_STILL_LOCKED"); bool removed = remove_user_hatch(msg.sender,index); require(removed,"HATCH_CONSUME_ERR"); if(template.output_as_multitoken) IOperatableERC1155Token(template.output_token_address).mintNFTFor(msg.sender, template.output_token_id, st.amount); else IOperatableERC721Token(template.output_token_address).mintNFTsFor(msg.sender, st.amount); hatch_states[hatch_id].hatched_block = current_block; emit OnHatched(msg.sender,hatch_id,hatch_states[hatch_id]); } function remove_user_hatch(address addr,uint256 index) internal returns(bool){ uint256 count = user_hatching[addr].length; if((count > 0) && (index < count)){ uint256 last_index = count - 1; user_hatching[addr][index] = user_hatching[addr][last_index]; delete user_hatching[addr][last_index]; user_hatching[addr].pop(); return true; } return false; } function get_user_hatch_index(address addr,uint256 hatch_id) internal view returns(bool,uint256){ uint256 count = user_hatching[addr].length; for(uint256 i = 0; i < count; i++){ if(user_hatching[addr][i] == hatch_id) return (true,i); } return (false,0); } function onUndefineTemplate(uint256 template_id) internal virtual override{ delete templates[template_id]; } function define_template(string memory name,string memory desc, address input_token_address,uint256 input_token_id, address output_token_address,uint256 output_token_id,uint256 block_count, uint256 op_price,bool start_enabled,address merchant,address currency) external onlyOwner returns (uint256){ require(bytes(name).length > 0,"NO_TPL_NAME"); (bool result,uint256 tpl_id) = _templateIds.tryAdd(1); require(result,"TPL_ID_OVERFLOW"); _templateIds = tpl_id; _fill_template_metadata(tpl_id,name,desc,op_price,start_enabled,merchant,currency); _check_template_input(input_token_address,input_token_id); bool as_multitoken = _check_template_output(output_token_address,output_token_id); templates[tpl_id] = HatchFormula(input_token_address,input_token_id,output_token_address,output_token_id,as_multitoken,block_count); emit OnHatchFormulaDefined(tpl_id,templates[tpl_id]); return tpl_id; } function udpate_template_formula(uint256 template_id, address input_token_address,uint256 input_token_id, address output_token_address,uint256 output_token_id, uint256 block_count) external onlyOwner { require(is_defined(template_id),"NO_TPL_DEFINED"); _check_template_input(input_token_address,input_token_id); bool as_multitoken = _check_template_output(output_token_address,output_token_id); templates[template_id] = HatchFormula(input_token_address,input_token_id,output_token_address,output_token_id,as_multitoken,block_count); emit OnHatchFormulaUpdated(template_id,templates[template_id]); } function get_template_formula(uint256 template_id) external view returns (address,uint256,address,uint256,bool,uint256){ HatchFormula memory fml = templates[template_id]; return (fml.input_token_address,fml.input_token_id,fml.output_token_address,fml.output_token_id,fml.output_as_multitoken,fml.hatch_block_count); } function _check_template_input(address token_address,uint256 token_id) internal view { require(_is_operatable_erc1155(token_address),"I_BAD_TOKEN"); IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(token_address); require(asErc1155.isTokenDefined(token_id),"NO_TOKEN_ID"); } function _check_template_output(address token_address,uint256 token_id) internal view returns(bool){ bool is_erc1155 = _is_operatable_erc1155(token_address); bool is_erc721 = _is_operatable_erc721(token_address); require(is_erc1155 || is_erc721,"O_BAD_TOKEN"); if(is_erc1155){ IOperatableERC1155Token asErc1155 = IOperatableERC1155Token(token_address); require(asErc1155.isTokenDefined(token_id),"NO_TOKEN_ID"); } return is_erc1155; } function _check_valid_token(uint256 tpl_id) internal view { HatchFormula memory fml = templates[tpl_id]; IOperatableERC1155Token i_asErc1155 = IOperatableERC1155Token(fml.input_token_address); require(i_asErc1155.isTokenDefined(fml.input_token_id),"NO_TOKEN_ID"); if(fml.output_as_multitoken){ IOperatableERC1155Token o_asErc1155 = IOperatableERC1155Token(fml.output_token_address); require(o_asErc1155.isTokenDefined(fml.output_token_id),"NO_TOKEN_ID"); } } }
contracts/Interfaces/ITokenOperatableTemplate.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITokenOperatableTemplate { function get_name() external view returns (string memory); function get_description() external view returns (string memory); function get_template_metadata(uint256 template_id) external view returns (string memory,string memory,uint256,bool,address); function is_template_defined(uint256 template_id) external view returns (bool); function is_template_enabled(uint256 template_id) external view returns (bool); }
contracts/base/TokenOperatableTemplateContract.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../Interfaces/ITokenOperatableTemplate.sol"; import "../Interfaces/IOperatableERC1155Token.sol"; import "../Interfaces/IOperatableERC721Token.sol"; abstract contract TokenOperatableTemplateContract is Ownable2Step,ITokenOperatableTemplate { using Math for uint256; using ERC165Checker for address; string private name; string private description; mapping(uint256 => string) private template_names; mapping(uint256 => string) private template_descs; mapping(uint256 => uint256) private operation_prices; mapping(uint256 => bool) private template_enabled; //For some reason in marketing we have template specific merchant if not set just use merchant address. mapping(uint256 => address) private template_merchants; mapping(uint256 => address) private template_currencies; address private merchant_address; address private currency_address = address(0); mapping(address => bool) private _operators; error OperatorAccount(address account); constructor(string memory name_,string memory description_) Ownable(msg.sender) { name = name_; description = description_; merchant_address = msg.sender; } event OnTemplateUndefined(uint256 template_id); function set_currency(address addr) external onlyOperator { require(addr == address(0) || addr.supportsInterface(type(IERC20).interfaceId),"UNSUPPORT_CURRENCY"); currency_address = addr; } function set_merchant(address merchant) external onlyOperator { require((merchant_address != merchant) && (merchant != address(0)),"INVALID_MERCHANT"); merchant_address = merchant; } function get_last_template_id() public view virtual returns (uint256) {return 0;} function get_currency_address(uint256 template_id) public view returns (address){ address addr = template_currencies[template_id]; return addr != address(0) ? addr : currency_address; } function get_merchant_address(uint256 template_id) public view returns(address){ address addr = template_merchants[template_id]; return addr != address(0) ? addr : merchant_address; } function undefine_templates(uint256[] memory template_ids) external onlyOperator { for(uint256 i = 0; i < template_ids.length; i++) _undefine_template(template_ids[i]); } function update_template_names(uint256[] memory template_ids,string[] memory template_names_) external onlyOperator { require(template_ids.length == template_names_.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _udpate_template_name(template_ids[i],template_names_[i]); } function update_template_descs(uint256[] memory template_ids,string[] memory descs) external onlyOperator { require(template_ids.length == descs.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_desc(template_ids[i],descs[i]); } function update_operation_prices(uint256[] memory template_ids,uint256[] memory prices) external onlyOperator { require(template_ids.length == prices.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_operation_price(template_ids[i],prices[i]); } function update_template_merchants(uint256[] memory template_ids,address[] memory merchants) external onlyOperator { require(template_ids.length == merchants.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_merchant(template_ids[i],merchants[i]); } function update_template_currencies(uint256[] memory template_ids,address[] memory currencies) external onlyOperator { require(template_ids.length == currencies.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _update_template_currency(template_ids[i],currencies[i]); } function enable_templates(uint256[] memory template_ids,bool[] memory enables) external onlyOperator { require(template_ids.length == enables.length,"PARAM_DIM_MISMATCH"); for(uint256 i = 0; i < template_ids.length; i++) _enable_template(template_ids[i],enables[i]); } function is_defined(uint256 template_id) public view returns(bool) {return (bytes(template_names[template_id]).length > 0);} function is_enabled(uint256 template_id) public view returns(bool) {return template_enabled[template_id];} function _undefine_template(uint256 template_id) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); _clear_template_metadata(template_id); onUndefineTemplate(template_id); emit OnTemplateUndefined(template_id); } function _fill_template_metadata(uint256 template_id,string memory name_,string memory desc,uint256 op_price,bool start_enabled,address merchant,address currency) internal{ template_names[template_id] = name_; template_descs[template_id] = desc; operation_prices[template_id] = op_price; template_enabled[template_id] = start_enabled; template_merchants[template_id] = merchant; template_currencies[template_id] = currency; } function _clear_template_metadata(uint256 template_id) internal{ delete template_names[template_id]; delete template_descs[template_id]; delete operation_prices[template_id]; delete template_enabled[template_id]; delete template_merchants[template_id]; delete template_currencies[template_id]; } function _udpate_template_name(uint256 template_id,string memory name_) internal{ require(bytes(template_names[template_id]).length > 0,"NO_TPL_DEFINED"); require(bytes(name_).length > 0,"NO_TPL_NAME"); template_names[template_id] = name_; } function _update_template_desc(uint256 template_id,string memory desc) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); template_descs[template_id] = desc; } function _update_operation_price(uint256 template_id,uint256 price) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); operation_prices[template_id] = price; } function _update_template_merchant(uint256 template_id,address merchant) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); require(merchant != address(0),"NULL_ADDRESS"); template_merchants[template_id] = merchant; } function _update_template_currency(uint256 template_id,address currency) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); require(currency != address(0),"NULL_ADDRESS"); template_currencies[template_id] = currency; } function _enable_template(uint256 template_id,bool enabled) internal { require(is_defined(template_id),"NO_TPL_DEFINED"); template_enabled[template_id] = enabled; } function consume_operation_cost(uint256 template_id,uint256 applyCount) internal { require(applyCount > 0,"ZERO_APPLYCOUNT"); uint256 op_price = operation_prices[template_id]; if(op_price == 0) return; address _merchant_addr = get_merchant_address(template_id); require(_merchant_addr != address(0),"NO_MERCHANT_ADDR"); (bool total_op_cost_result,uint256 total_op_cost) = op_price.tryMul(applyCount); require(total_op_cost_result,"OP_COST_OVERFLOW"); address _currency_addr = get_currency_address(template_id); if(_currency_addr != address(0)){ uint256 available_balance = IERC20(_currency_addr).balanceOf(msg.sender); require(available_balance >= total_op_cost,"UNSUFFICIENT_BALANCE"); IERC20(_currency_addr).transferFrom(msg.sender, _merchant_addr, total_op_cost); if(msg.value > 0) payable(msg.sender).transfer(msg.value); } else{ require(msg.value >= total_op_cost,"UNSUFFICIENT_BALANCE"); uint256 remain_value = msg.value - total_op_cost; payable(_merchant_addr).transfer(total_op_cost); payable(msg.sender).transfer(remain_value); } } function isTemplateValid(uint256) internal virtual returns (bool) {return false;} function onUndefineTemplate(uint256) internal virtual {} function get_template_metadata(uint256 template_id) external view virtual override returns (string memory,string memory,uint256,bool,address){ return (template_names[template_id],template_descs[template_id],operation_prices[template_id],template_enabled[template_id],get_merchant_address(template_id)); } function is_template_defined(uint256 template_id) external view virtual override returns (bool){return is_defined(template_id);} function is_template_enabled(uint256 template_id) external view virtual override returns (bool){return template_enabled[template_id];} function get_name() external view virtual override returns (string memory){return name;} function get_description() external view virtual override returns (string memory){return description;} function set_operator(address addr,bool set) external virtual onlyOwner { require(addr != address(0),"Null Address allowed"); _operators[addr] = set; } function as_operator(address addr) public view virtual returns(bool) { return _operators[addr]; } modifier onlyOperator() { _checkIsOperator(); _; } function _check_operator(address addr) internal view virtual returns(bool) { return _operators[addr]; } function _checkIsOperator() internal view virtual { address _sender = _msgSender(); if ((owner() != _sender) && (!_check_operator(_sender))) { revert OperatorAccount(_sender); } } function _is_operatable_erc1155(address addr) internal view returns(bool) { return (addr != address(0)) && addr.supportsInterface(type(IOperatableERC1155Token).interfaceId); } function _is_operatable_erc721(address addr) internal view returns (bool){ return (addr != address(0)) && addr.supportsInterface(type(IOperatableERC721Token).interfaceId); } }
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
@openzeppelin/contracts/access/Ownable2Step.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol) pragma solidity ^0.8.20; import {Ownable} from "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is specified at deployment time in the constructor for `Ownable`. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); if (pendingOwner() != sender) { revert OwnableUnauthorizedAccount(sender); } _transferOwnership(sender); } }
@openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
@openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
@openzeppelin/contracts/utils/introspection/ERC165Checker.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. */ function getSupportedInterfaces( address account, bytes4[] memory interfaceIds ) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeCall(IERC165.supportsInterface, (interfaceId)); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
@openzeppelin/contracts/utils/introspection/IERC165.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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); }
@openzeppelin/contracts/utils/math/Math.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or * denominator == 0. * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by * Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. // Always >= 1. See https://cs.stackexchange.com/q/138556/92363. uint256 twos = denominator & (0 - denominator); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also // works in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded * towards zero. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
contracts/Interfaces/IOperatableERC1155Token.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IOperatableERC1155Token { //Get Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function contractURI() external view returns (string memory); //Set Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function setContractURI(string memory contractURI_) external; function lastTokenIds() external view returns (uint256); //Return token ids and amount. function ownedTokenOf(address _addr) external view returns(uint256[] memory,uint256[] memory); function canMintForAmount(uint256 tokenId,uint256 tokmentAmount) external view returns(bool); function canMintBulkForAmount(uint256[] memory tokenIds,uint256[] memory tokmentAmounts) external view returns(bool); //Mint nft for some user by contact owner. use for bleeding/crafting or mint NFT from App function mintNFTsFor(address _addr,uint256[] memory tokenIds,uint256[] memory amounts) external; //Burn nft for some user by contact owner. use for crafting or burn NFT from App function burnNFTsFor(address _addr,uint256[] memory tokenIds,uint256[] memory amounts) external; //Mint nft for some user by contact owner. use for bleeding/crafting or mint NFT from App function mintNFTFor(address _addr,uint256 tokenId,uint256 amount) external; //Burn nft for some user by contact owner. use for crafting or burn NFT from App function burnNFTFor(address _addr,uint256 tokenId,uint256 amount) external; //Get total supply of Token function totalSupply(uint256 tokenId) external view returns(uint256); //Token id is defined or not function isTokenDefined(uint256 token_id) external view returns (bool); }
contracts/Interfaces/IOperatableERC721Token.sol
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @dev Interface of use for all of ScrewUp NFT token. */ interface IOperatableERC721Token { //Get Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function contractURI() external view returns (string memory); //Set Contract Level metadata uri - See https://docs.opensea.io/docs/contract-level-metadata function setContractURI(string memory contractURI_) external; //Get all of items for address. function ownedTokenOf(address _addr) external view returns (uint256[] memory); //Check address is really own item. function isOwnedToken(address _addr,uint256 tokenId) external view returns(bool); //Update token URI for token Id function updateTokenURI(uint256 tokenId,string memory tokenURI) external; //Mint nft (unreveal only) for some user by contact owner. use for bleeding or mint NFT from App function mintNFTsFor(address addr,uint256 amount) external; //Mint nft for some user by contact owner. use for bleeding or mint NFT from App function mintNFTFor(address addr,string memory tokenURI) external; //Mint nft for some user by contact owner. use for bleeding or mint NFT from App function burnNFTFor(address addr,uint256 tokenId) external; //Update display name of token when unreveal. function getUnrevealName() external view returns (string memory); //Update token uri of token when unreveal. function getUnrevealTokenUri() external view returns (string memory); function getUnrevealMetadata() external view returns (string memory,string memory); }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":false},"libraries":{},"evmVersion":"paris"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"description_","internalType":"string"}]},{"type":"error","name":"OperatorAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"OnHatchFormulaDefined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Hatches.HatchFormula","indexed":false,"components":[{"type":"address","name":"input_token_address","internalType":"address"},{"type":"uint256","name":"input_token_id","internalType":"uint256"},{"type":"address","name":"output_token_address","internalType":"address"},{"type":"uint256","name":"output_token_id","internalType":"uint256"},{"type":"bool","name":"output_as_multitoken","internalType":"bool"},{"type":"uint256","name":"hatch_block_count","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"OnHatchFormulaUpdated","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"formula","internalType":"struct ERC1155Hatches.HatchFormula","indexed":false,"components":[{"type":"address","name":"input_token_address","internalType":"address"},{"type":"uint256","name":"input_token_id","internalType":"uint256"},{"type":"address","name":"output_token_address","internalType":"address"},{"type":"uint256","name":"output_token_id","internalType":"uint256"},{"type":"bool","name":"output_as_multitoken","internalType":"bool"},{"type":"uint256","name":"hatch_block_count","internalType":"uint256"}]}],"anonymous":false},{"type":"event","name":"OnHatched","inputs":[{"type":"address","name":"addr","internalType":"address","indexed":true},{"type":"uint256","name":"hatch_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"state","internalType":"struct ERC1155Hatches.HatchState","indexed":false,"components":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"uint256","name":"begin_block","internalType":"uint256"},{"type":"uint256","name":"hatched_block","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"hatcher","internalType":"address"}]}],"anonymous":false},{"type":"event","name":"OnHatchingBegin","inputs":[{"type":"address","name":"addr","internalType":"address","indexed":true},{"type":"uint256","name":"hatch_id","internalType":"uint256","indexed":true},{"type":"tuple","name":"state","internalType":"struct ERC1155Hatches.HatchState","indexed":false,"components":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"uint256","name":"begin_block","internalType":"uint256"},{"type":"uint256","name":"hatched_block","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"address","name":"hatcher","internalType":"address"}]}],"anonymous":false},{"type":"event","name":"OnTemplateUndefined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"as_operator","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"create_hatch","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"uint256","name":"applyCount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"define_template","inputs":[{"type":"string","name":"name","internalType":"string"},{"type":"string","name":"desc","internalType":"string"},{"type":"address","name":"input_token_address","internalType":"address"},{"type":"uint256","name":"input_token_id","internalType":"uint256"},{"type":"address","name":"output_token_address","internalType":"address"},{"type":"uint256","name":"output_token_id","internalType":"uint256"},{"type":"uint256","name":"block_count","internalType":"uint256"},{"type":"uint256","name":"op_price","internalType":"uint256"},{"type":"bool","name":"start_enabled","internalType":"bool"},{"type":"address","name":"merchant","internalType":"address"},{"type":"address","name":"currency","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"do_hatch","inputs":[{"type":"uint256","name":"hatch_id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"enable_templates","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"bool[]","name":"enables","internalType":"bool[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_currency_address","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"get_description","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_last_hatch_id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_last_template_id","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"get_merchant_address","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"get_name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"get_template_formula","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"},{"type":"string","name":"","internalType":"string"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"bool","name":"","internalType":"bool"},{"type":"address","name":"","internalType":"address"}],"name":"get_template_metadata","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}],"name":"hatch_state","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_defined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_enabled","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_template_defined","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"is_template_enabled","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"on_hatching","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_currency","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_merchant","inputs":[{"type":"address","name":"merchant","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"set_operator","inputs":[{"type":"address","name":"addr","internalType":"address"},{"type":"bool","name":"set","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"udpate_template_formula","inputs":[{"type":"uint256","name":"template_id","internalType":"uint256"},{"type":"address","name":"input_token_address","internalType":"address"},{"type":"uint256","name":"input_token_id","internalType":"uint256"},{"type":"address","name":"output_token_address","internalType":"address"},{"type":"uint256","name":"output_token_id","internalType":"uint256"},{"type":"uint256","name":"block_count","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"undefine_templates","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_operation_prices","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"uint256[]","name":"prices","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_currencies","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"address[]","name":"currencies","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_descs","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"string[]","name":"descs","internalType":"string[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_merchants","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"address[]","name":"merchants","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update_template_names","inputs":[{"type":"uint256[]","name":"template_ids","internalType":"uint256[]"},{"type":"string[]","name":"template_names_","internalType":"string[]"}]}]
Contract Creation Code
0x60806040526000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503480156200005357600080fd5b506040516200669338038062006693833981810160405281019062000079919062000402565b818133600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000f15760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000e89190620004cc565b60405180910390fd5b62000102816200017260201b60201c565b50816002908162000114919062000734565b50806003908162000126919062000734565b5033600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050506200081b565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055620001a881620001ab60201b60201c565b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620002d8826200028d565b810181811067ffffffffffffffff82111715620002fa57620002f96200029e565b5b80604052505050565b60006200030f6200026f565b90506200031d8282620002cd565b919050565b600067ffffffffffffffff82111562000340576200033f6200029e565b5b6200034b826200028d565b9050602081019050919050565b60005b83811015620003785780820151818401526020810190506200035b565b60008484015250505050565b60006200039b620003958462000322565b62000303565b905082815260208101848484011115620003ba57620003b962000288565b5b620003c784828562000358565b509392505050565b600082601f830112620003e757620003e662000283565b5b8151620003f984826020860162000384565b91505092915050565b600080604083850312156200041c576200041b62000279565b5b600083015167ffffffffffffffff8111156200043d576200043c6200027e565b5b6200044b85828601620003cf565b925050602083015167ffffffffffffffff8111156200046f576200046e6200027e565b5b6200047d85828601620003cf565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004b48262000487565b9050919050565b620004c681620004a7565b82525050565b6000602082019050620004e36000830184620004bb565b92915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200053c57607f821691505b602082108103620005525762000551620004f4565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005bc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057d565b620005c886836200057d565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006156200060f6200060984620005e0565b620005ea565b620005e0565b9050919050565b6000819050919050565b6200063183620005f4565b6200064962000640826200061c565b8484546200058a565b825550505050565b600090565b6200066062000651565b6200066d81848462000626565b505050565b5b8181101562000695576200068960008262000656565b60018101905062000673565b5050565b601f821115620006e457620006ae8162000558565b620006b9846200056d565b81016020851015620006c9578190505b620006e1620006d8856200056d565b83018262000672565b50505b505050565b600082821c905092915050565b60006200070960001984600802620006e9565b1980831691505092915050565b6000620007248383620006f6565b9150826002028217905092915050565b6200073f82620004e9565b67ffffffffffffffff8111156200075b576200075a6200029e565b5b62000767825462000523565b6200077482828562000699565b600060209050601f831160018114620007ac576000841562000797578287015190505b620007a3858262000716565b86555062000813565b601f198416620007bc8662000558565b60005b82811015620007e657848901518255600182019150602085019450602081019050620007bf565b8683101562000806578489015162000802601f891682620006f6565b8355505b6001600288020188555050505b505050505050565b615e68806200082b6000396000f3fe6080604052600436106101f95760003560e01c806376967cbf1161010d578063bb21ac54116100a0578063e30c39781161006f578063e30c397814610763578063e55661bd1461078e578063eaed4d70146107cb578063f2fde38b146107f4578063f674c8311461081d576101f9565b8063bb21ac541461067f578063dd99b73d146106a8578063dda0da00146106e9578063df8e759a14610726576101f9565b80639e9cceac116100dc5780639e9cceac146105b3578063a3066e43146105dc578063b8c7871a14610605578063ba84860814610642576101f9565b806376967cbf1461051d57806379ba509714610546578063839d7f111461055d5780638da5cb5b14610588576101f9565b80633a525c29116101905780635458c28e1161015f5780635458c28e146104575780635af9d736146104805780636302690c146104c15780636586bb70146104dd578063715018a614610506576101f9565b80633a525c291461039b5780633b9ebeec146103c65780633f84dc1b146103ef57806348ec0ffb1461041a576101f9565b80631a7db56e116101cc5780631a7db56e146102cf5780632680976d146102f8578063284293cf1461033557806330546c9b14610372576101f9565b80630f6bec9a146101fe5780630fe4215914610227578063189357ff1461025057806319df118214610292575b600080fd5b34801561020a57600080fd5b506102256004803603810190610220919061412f565b610848565b005b34801561023357600080fd5b5061024e6004803603810190610249919061423d565b6108f6565b005b34801561025c57600080fd5b506102776004803603810190610272919061427d565b6109c8565b604051610289969594939291906142d7565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b4919061427d565b610b0c565b6040516102c69190614338565b60405180910390f35b3480156102db57600080fd5b506102f660048036038101906102f19190614416565b610b36565b005b34801561030457600080fd5b5061031f600480360381019061031a9190614543565b610be4565b60405161032c919061466f565b60405180910390f35b34801561034157600080fd5b5061035c6004803603810190610357919061427d565b610e59565b6040516103699190614338565b60405180910390f35b34801561037e57600080fd5b506103996004803603810190610394919061468a565b610e83565b005b3480156103a757600080fd5b506103b0610ed1565b6040516103bd9190614752565b60405180910390f35b3480156103d257600080fd5b506103ed60048036038101906103e89190614837565b610f63565b005b3480156103fb57600080fd5b50610404611011565b604051610411919061466f565b60405180910390f35b34801561042657600080fd5b50610441600480360381019061043c91906148af565b61101b565b60405161044e919061499a565b60405180910390f35b34801561046357600080fd5b5061047e60048036038101906104799190614416565b6110b2565b005b34801561048c57600080fd5b506104a760048036038101906104a2919061427d565b611160565b6040516104b89594939291906149bc565b60405180910390f35b6104db60048036038101906104d69190614a0f565b611234565b005b3480156104e957600080fd5b5061050460048036038101906104ff91906148af565b6116b7565b005b34801561051257600080fd5b5061051b6117cd565b005b34801561052957600080fd5b50610544600480360381019061053f9190614b30565b6117e1565b005b34801561055257600080fd5b5061055b61188f565b005b34801561056957600080fd5b5061057261191e565b60405161057f9190614752565b60405180910390f35b34801561059457600080fd5b5061059d6119b0565b6040516105aa9190614ba8565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d5919061427d565b6119d9565b005b3480156105e857600080fd5b5061060360048036038101906105fe9190614b30565b611ed8565b005b34801561061157600080fd5b5061062c6004803603810190610627919061427d565b611f86565b6040516106399190614338565b60405180910390f35b34801561064e57600080fd5b50610669600480360381019061066491906148af565b611fb1565b6040516106769190614338565b60405180910390f35b34801561068b57600080fd5b506106a660048036038101906106a191906148af565b612007565b005b3480156106b457600080fd5b506106cf60048036038101906106ca919061427d565b612112565b6040516106e0959493929190614bc3565b60405180910390f35b3480156106f557600080fd5b50610710600480360381019061070b919061427d565b6122a9565b60405161071d9190614338565b60405180910390f35b34801561073257600080fd5b5061074d6004803603810190610748919061427d565b6122bb565b60405161075a9190614ba8565b60405180910390f35b34801561076f57600080fd5b5061077861235a565b6040516107859190614ba8565b60405180910390f35b34801561079a57600080fd5b506107b560048036038101906107b0919061427d565b612384565b6040516107c29190614ba8565b60405180910390f35b3480156107d757600080fd5b506107f260048036038101906107ed9190614c24565b612423565b005b34801561080057600080fd5b5061081b600480360381019061081691906148af565b61261b565b005b34801561082957600080fd5b506108326126c8565b60405161083f919061466f565b60405180910390f35b6108506126d2565b8051825114610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b90614cfd565b60405180910390fd5b60005b82518110156108f1576108de8382815181106108b6576108b5614d1d565b5b60200260200101518383815181106108d1576108d0614d1d565b5b602002602001015161276c565b80806108e990614d7b565b915050610897565b505050565b6108fe6127d0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361096d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096490614e0f565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000806000806000806000600d60008981526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff161515151581526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610b3e6126d2565b8051825114610b82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7990614cfd565b60405180910390fd5b60005b8251811015610bdf57610bcc838281518110610ba457610ba3614d1d565b5b6020026020010151838381518110610bbf57610bbe614d1d565b5b6020026020010151612857565b8080610bd790614d7b565b915050610b85565b505050565b6000610bee6127d0565b60008c5111610c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2990614e7b565b60405180910390fd5b600080610c4b600160105461296490919063ffffffff16565b9150915081610c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8690614ee7565b60405180910390fd5b80601081905550610ca5818f8f8a8a8a8a612993565b610caf8c8c612ac5565b6000610cbb8b8b612bd0565b90506040518060c001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018d81526020018c73ffffffffffffffffffffffffffffffffffffffff1681526020018b815260200182151581526020018a815250600d600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160050155905050817fdcbded9d6d08a735a46516026e72f3d8a35ed314ba69e1f86393f87fe79fed90600d6000858152602001908152602001600020604051610e3c9190615076565b60405180910390a28193505050509b9a5050505050505050505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610e8b6126d2565b60005b8151811015610ecd57610eba828281518110610ead57610eac614d1d565b5b6020026020010151612d04565b8080610ec590614d7b565b915050610e8e565b5050565b606060028054610ee0906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054610f0c906150c0565b8015610f595780601f10610f2e57610100808354040283529160200191610f59565b820191906000526020600020905b815481529060010190602001808311610f3c57829003601f168201915b5050505050905090565b610f6b6126d2565b8051825114610faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa690614cfd565b60405180910390fd5b60005b825181101561100c57610ff9838281518110610fd157610fd0614d1d565b5b6020026020010151838381518110610fec57610feb614d1d565b5b6020026020010151612d98565b808061100490614d7b565b915050610fb2565b505050565b6000601054905090565b6060600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156110a657602002820191906000526020600020905b815481526020019060010190808311611092575b50505050509050919050565b6110ba6126d2565b80518251146110fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f590614cfd565b60405180910390fd5b60005b825181101561115b576111488382815181106111205761111f614d1d565b5b602002602001015183838151811061113b5761113a614d1d565b5b6020026020010151612e0f565b808061115390614d7b565b915050611101565b505050565b600080600080600080600f60008881526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905080600001518160200151826040015183606001518460800151955095509550955095505091939590929450565b60008111611277576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126e9061513d565b60405180910390fd5b61128082610b0c565b6112bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b6906151a9565b60405180910390fd5b6112c882612f1c565b60006001436112d791906151c9565b90506000600d60008581526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152505090506000806113f9600160115461296490919063ffffffff16565b915091508161143d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143490615249565b60405180910390fd5b600080611457878660a001516131c090919063ffffffff16565b915091508161149b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611492906152b5565b60405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff1663cbc7067c3387602001518a6040518463ffffffff1660e01b81526004016114e0939291906152d5565b600060405180830381600087803b1580156114fa57600080fd5b505af115801561150e573d6000803e3d6000fd5b50505050826011819055506040518060a00160405280898152602001878152602001600081526020018881526020013373ffffffffffffffffffffffffffffffffffffffff16815250600f60008581526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083908060018154018082558091505060019003906000526020600020016000909190919091505561164c8888613213565b823373ffffffffffffffffffffffffffffffffffffffff167f8f4924c453b998e3a92f80c1cd55a4040260f3077b645e092c25bd98505ce915600f60008781526020019081526020016000206040516116a591906153ad565b60405180910390a35050505050505050565b6116bf6126d2565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415801561174a5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b611789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178090615414565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6117d56127d0565b6117df6000613619565b565b6117e96126d2565b805182511461182d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182490614cfd565b60405180910390fd5b60005b825181101561188a5761187783828151811061184f5761184e614d1d565b5b602002602001015183838151811061186a57611869614d1d565b5b602002602001015161364a565b808061188290614d7b565b915050611830565b505050565b6000611899613715565b90508073ffffffffffffffffffffffffffffffffffffffff166118ba61235a565b73ffffffffffffffffffffffffffffffffffffffff161461191257806040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119099190614ba8565b60405180910390fd5b61191b81613619565b50565b60606003805461192d906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054611959906150c0565b80156119a65780601f1061197b576101008083540402835291602001916119a6565b820191906000526020600020905b81548152906001019060200180831161198957829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806119e6338461371d565b9150915081611a2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2190615480565b60405180910390fd5b6000600f60008581526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050611ad78160000151610b0c565b611b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0d906151a9565b60405180910390fd5b611b238160000151612f1c565b6000600143611b3291906151c9565b90508160200151811015611b7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b72906154ec565b60405180910390fd5b6000600d6000846000015181526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff161515151581526020016005820154815250509050600080611ca485606001518460a001516131c090919063ffffffff16565b91509150818015611cc4575080856020015185611cc191906151c9565b10155b611d03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cfa90615558565b60405180910390fd5b6000611d0f3388613806565b905080611d51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d48906155c4565b60405180910390fd5b836080015115611ddb57836040015173ffffffffffffffffffffffffffffffffffffffff166325f5e8ee33866060015189606001516040518463ffffffff1660e01b8152600401611da4939291906152d5565b600060405180830381600087803b158015611dbe57600080fd5b505af1158015611dd2573d6000803e3d6000fd5b50505050611e51565b836040015173ffffffffffffffffffffffffffffffffffffffff1663f0a8587b3388606001516040518363ffffffff1660e01b8152600401611e1e9291906155e4565b600060405180830381600087803b158015611e3857600080fd5b505af1158015611e4c573d6000803e3d6000fd5b505050505b84600f60008b815260200190815260200160002060020181905550883373ffffffffffffffffffffffffffffffffffffffff167f63380c9bc749b31ce5d02727247809f2271e76e71f272ddab5fe2d20ef1f094f600f60008d8152602001908152602001600020604051611ec591906153ad565b60405180910390a3505050505050505050565b611ee06126d2565b8051825114611f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1b90614cfd565b60405180910390fd5b60005b8251811015611f8157611f6e838281518110611f4657611f45614d1d565b5b6020026020010151838381518110611f6157611f60614d1d565b5b6020026020010151613a09565b8080611f7990614d7b565b915050611f27565b505050565b600080600460008481526020019081526020016000208054611fa7906150c0565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b61200f6126d2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061208f575061208e7f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b6120ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c590615659565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff1661217e8a6122bb565b84805461218a906150c0565b80601f01602080910402602001604051908101604052809291908181526020018280546121b6906150c0565b80156122035780601f106121d857610100808354040283529160200191612203565b820191906000526020600020905b8154815290600101906020018083116121e657829003601f168201915b50505050509450838054612216906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054612242906150c0565b801561228f5780601f106122645761010080835404028352916020019161228f565b820191906000526020600020905b81548152906001019060200180831161227257829003601f168201915b505050505093509450945094509450945091939590929450565b60006122b482611f86565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361235057600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612352565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361241957600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661241b565b805b915050919050565b61242b6127d0565b61243486611f86565b612473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246a906156c5565b60405180910390fd5b61247d8585612ac5565b60006124898484612bd0565b90506040518060c001604052808773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001821515815260200183815250600d600089815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160050155905050867fbc06c35f688bd191247fc768d528b4450014fe12b7d0ff806a8c0310cf9d9e29600d60008a815260200190815260200160002060405161260a9190615076565b60405180910390a250505050505050565b6126236127d0565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166126836119b0565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000601154905090565b60006126dc613715565b90508073ffffffffffffffffffffffffffffffffffffffff166126fd6119b0565b73ffffffffffffffffffffffffffffffffffffffff1614158015612727575061272581613a9b565b155b1561276957806040517f8a08cbf50000000000000000000000000000000000000000000000000000000081526004016127609190614ba8565b60405180910390fd5b50565b61277582611f86565b6127b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127ab906156c5565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b6127d8613715565b73ffffffffffffffffffffffffffffffffffffffff166127f66119b0565b73ffffffffffffffffffffffffffffffffffffffff161461285557612819613715565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161284c9190614ba8565b60405180910390fd5b565b61286082611f86565b61289f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612896906156c5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361290e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290590615731565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080600083850190508481101561298357600080925092505061298c565b60018192509250505b9250929050565b856004600089815260200190815260200160002090816129b391906158fd565b50846005600089815260200190815260200160002090816129d491906158fd565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b612ace82613af1565b612b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0490615a1b565b60405180910390fd5b60008290508073ffffffffffffffffffffffffffffffffffffffff1663b419c807836040518263ffffffff1660e01b8152600401612b4b919061466f565b602060405180830381865afa158015612b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8c9190615a50565b612bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc290615ac9565b60405180910390fd5b505050565b600080612bdc84613af1565b90506000612be985613b7b565b90508180612bf45750805b612c33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2a90615b35565b60405180910390fd5b8115612cf95760008590508073ffffffffffffffffffffffffffffffffffffffff1663b419c807866040518263ffffffff1660e01b8152600401612c77919061466f565b602060405180830381865afa158015612c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb89190615a50565b612cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cee90615ac9565b60405180910390fd5b505b819250505092915050565b612d0d81611f86565b612d4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d43906156c5565b60405180910390fd5b612d5581613c05565b612d5e81613cec565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b781604051612d8d919061466f565b60405180910390a150565b612da182611f86565b612de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd7906156c5565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b612e1882611f86565b612e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4e906156c5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615731565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600d60008381526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152505090506000816000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80783602001516040518263ffffffff1660e01b8152600401613069919061466f565b602060405180830381865afa158015613086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130aa9190615a50565b6130e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130e090615ac9565b60405180910390fd5b8160800151156131bb576000826040015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80784606001516040518263ffffffff1660e01b8152600401613139919061466f565b602060405180830381865afa158015613156573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317a9190615a50565b6131b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131b090615ac9565b60405180910390fd5b505b505050565b600080600084036131d857600160009150915061320c565b60008385029050838582816131f0576131ef615b55565b5b041461320357600080925092505061320c565b60018192509250505b9250929050565b60008111613256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324d90615bd0565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361327c5750613615565b6000613287846122bb565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036132f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ef90615c3c565b60405180910390fd5b60008061330e85856131c090919063ffffffff16565b9150915081613352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161334990615ca8565b60405180910390fd5b600061335d87612384565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461352c5760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016133ce9190614ba8565b602060405180830381865afa1580156133eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340f9190615cdd565b905082811015613454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161344b90615d56565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b815260040161349193929190615d76565b6020604051808303816000875af11580156134b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d49190615a50565b506000341115613526573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015613524573d6000803e3d6000fd5b505b5061360f565b8134101561356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161356690615d56565b60405180910390fd5b6000823461357d91906151c9565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156135c5573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561360c573d6000803e3d6000fd5b50505b50505050505b5050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905561364781613d7f565b50565b600060046000848152602001908152602001600020805461366a906150c0565b9050116136ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a3906156c5565b60405180910390fd5b60008151116136f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136e790614e7b565b60405180910390fd5b8060046000848152602001908152602001600020908161371091906158fd565b505050565b600033905090565b6000806000600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060005b818110156137f55784600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106137c4576137c3614d1d565b5b9060005260206000200154036137e2576001819350935050506137ff565b80806137ed90614d7b565b91505061376a565b5060008092509250505b9250929050565b600080600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060008111801561385d57508083105b156139fd57600060018261387191906151c9565b9050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081815481106138c4576138c3614d1d565b5b9060005260206000200154600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106139205761391f614d1d565b5b9060005260206000200181905550600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020818154811061397f5761397e614d1d565b5b9060005260206000200160009055600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806139dc576139db615dad565b5b60019003818190600052602060002001600090559055600192505050613a03565b60009150505b92915050565b613a1282611f86565b613a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a48906156c5565b60405180910390fd5b80600560008481526020019081526020016000209081613a7191906158fd565b505050565b6000613a8183613e43565b8015613a935750613a928383613e90565b5b905092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613b745750613b737ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613bfe5750613bfd7f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b9050919050565b600460008281526020019081526020016000206000613c249190613f2f565b600560008281526020019081526020016000206000613c439190613f2f565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600d6000828152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038201600090556004820160006101000a81549060ff02191690556005820160009055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613e6f827f01ffc9a700000000000000000000000000000000000000000000000000000000613e90565b8015613e895750613e878263ffffffff60e01b613e90565b155b9050919050565b60008082604051602401613ea49190615e17565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d91506000519050828015613f17575060208210155b8015613f235750600081115b94505050505092915050565b508054613f3b906150c0565b6000825580601f10613f4d5750613f6c565b601f016020900490600052602060002090810190613f6b9190613f6f565b5b50565b5b80821115613f88576000816000905550600101613f70565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fee82613fa5565b810181811067ffffffffffffffff8211171561400d5761400c613fb6565b5b80604052505050565b6000614020613f8c565b905061402c8282613fe5565b919050565b600067ffffffffffffffff82111561404c5761404b613fb6565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b61407581614062565b811461408057600080fd5b50565b6000813590506140928161406c565b92915050565b60006140ab6140a684614031565b614016565b905080838252602082019050602084028301858111156140ce576140cd61405d565b5b835b818110156140f757806140e38882614083565b8452602084019350506020810190506140d0565b5050509392505050565b600082601f83011261411657614115613fa0565b5b8135614126848260208601614098565b91505092915050565b6000806040838503121561414657614145613f96565b5b600083013567ffffffffffffffff81111561416457614163613f9b565b5b61417085828601614101565b925050602083013567ffffffffffffffff81111561419157614190613f9b565b5b61419d85828601614101565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006141d2826141a7565b9050919050565b6141e2816141c7565b81146141ed57600080fd5b50565b6000813590506141ff816141d9565b92915050565b60008115159050919050565b61421a81614205565b811461422557600080fd5b50565b60008135905061423781614211565b92915050565b6000806040838503121561425457614253613f96565b5b6000614262858286016141f0565b925050602061427385828601614228565b9150509250929050565b60006020828403121561429357614292613f96565b5b60006142a184828501614083565b91505092915050565b6142b3816141c7565b82525050565b6142c281614062565b82525050565b6142d181614205565b82525050565b600060c0820190506142ec60008301896142aa565b6142f960208301886142b9565b61430660408301876142aa565b61431360608301866142b9565b61432060808301856142c8565b61432d60a08301846142b9565b979650505050505050565b600060208201905061434d60008301846142c8565b92915050565b600067ffffffffffffffff82111561436e5761436d613fb6565b5b602082029050602081019050919050565b600061439261438d84614353565b614016565b905080838252602082019050602084028301858111156143b5576143b461405d565b5b835b818110156143de57806143ca88826141f0565b8452602084019350506020810190506143b7565b5050509392505050565b600082601f8301126143fd576143fc613fa0565b5b813561440d84826020860161437f565b91505092915050565b6000806040838503121561442d5761442c613f96565b5b600083013567ffffffffffffffff81111561444b5761444a613f9b565b5b61445785828601614101565b925050602083013567ffffffffffffffff81111561447857614477613f9b565b5b614484858286016143e8565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156144ae576144ad613fb6565b5b6144b782613fa5565b9050602081019050919050565b82818337600083830152505050565b60006144e66144e184614493565b614016565b9050828152602081018484840111156145025761450161448e565b5b61450d8482856144c4565b509392505050565b600082601f83011261452a57614529613fa0565b5b813561453a8482602086016144d3565b91505092915050565b60008060008060008060008060008060006101608c8e03121561456957614568613f96565b5b60008c013567ffffffffffffffff81111561458757614586613f9b565b5b6145938e828f01614515565b9b505060208c013567ffffffffffffffff8111156145b4576145b3613f9b565b5b6145c08e828f01614515565b9a505060406145d18e828f016141f0565b99505060606145e28e828f01614083565b98505060806145f38e828f016141f0565b97505060a06146048e828f01614083565b96505060c06146158e828f01614083565b95505060e06146268e828f01614083565b9450506101006146388e828f01614228565b93505061012061464a8e828f016141f0565b92505061014061465c8e828f016141f0565b9150509295989b509295989b9093969950565b600060208201905061468460008301846142b9565b92915050565b6000602082840312156146a05761469f613f96565b5b600082013567ffffffffffffffff8111156146be576146bd613f9b565b5b6146ca84828501614101565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561470d5780820151818401526020810190506146f2565b60008484015250505050565b6000614724826146d3565b61472e81856146de565b935061473e8185602086016146ef565b61474781613fa5565b840191505092915050565b6000602082019050818103600083015261476c8184614719565b905092915050565b600067ffffffffffffffff82111561478f5761478e613fb6565b5b602082029050602081019050919050565b60006147b36147ae84614774565b614016565b905080838252602082019050602084028301858111156147d6576147d561405d565b5b835b818110156147ff57806147eb8882614228565b8452602084019350506020810190506147d8565b5050509392505050565b600082601f83011261481e5761481d613fa0565b5b813561482e8482602086016147a0565b91505092915050565b6000806040838503121561484e5761484d613f96565b5b600083013567ffffffffffffffff81111561486c5761486b613f9b565b5b61487885828601614101565b925050602083013567ffffffffffffffff81111561489957614898613f9b565b5b6148a585828601614809565b9150509250929050565b6000602082840312156148c5576148c4613f96565b5b60006148d3848285016141f0565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61491181614062565b82525050565b60006149238383614908565b60208301905092915050565b6000602082019050919050565b6000614947826148dc565b61495181856148e7565b935061495c836148f8565b8060005b8381101561498d5781516149748882614917565b975061497f8361492f565b925050600181019050614960565b5085935050505092915050565b600060208201905081810360008301526149b4818461493c565b905092915050565b600060a0820190506149d160008301886142b9565b6149de60208301876142b9565b6149eb60408301866142b9565b6149f860608301856142b9565b614a0560808301846142aa565b9695505050505050565b60008060408385031215614a2657614a25613f96565b5b6000614a3485828601614083565b9250506020614a4585828601614083565b9150509250929050565b600067ffffffffffffffff821115614a6a57614a69613fb6565b5b602082029050602081019050919050565b6000614a8e614a8984614a4f565b614016565b90508083825260208201905060208402830185811115614ab157614ab061405d565b5b835b81811015614af857803567ffffffffffffffff811115614ad657614ad5613fa0565b5b808601614ae38982614515565b85526020850194505050602081019050614ab3565b5050509392505050565b600082601f830112614b1757614b16613fa0565b5b8135614b27848260208601614a7b565b91505092915050565b60008060408385031215614b4757614b46613f96565b5b600083013567ffffffffffffffff811115614b6557614b64613f9b565b5b614b7185828601614101565b925050602083013567ffffffffffffffff811115614b9257614b91613f9b565b5b614b9e85828601614b02565b9150509250929050565b6000602082019050614bbd60008301846142aa565b92915050565b600060a0820190508181036000830152614bdd8188614719565b90508181036020830152614bf18187614719565b9050614c0060408301866142b9565b614c0d60608301856142c8565b614c1a60808301846142aa565b9695505050505050565b60008060008060008060c08789031215614c4157614c40613f96565b5b6000614c4f89828a01614083565b9650506020614c6089828a016141f0565b9550506040614c7189828a01614083565b9450506060614c8289828a016141f0565b9350506080614c9389828a01614083565b92505060a0614ca489828a01614083565b9150509295509295509295565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b6000614ce76012836146de565b9150614cf282614cb1565b602082019050919050565b60006020820190508181036000830152614d1681614cda565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614d8682614062565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614db857614db7614d4c565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b6000614df96014836146de565b9150614e0482614dc3565b602082019050919050565b60006020820190508181036000830152614e2881614dec565b9050919050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b6000614e65600b836146de565b9150614e7082614e2f565b602082019050919050565b60006020820190508181036000830152614e9481614e58565b9050919050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614ed1600f836146de565b9150614edc82614e9b565b602082019050919050565b60006020820190508181036000830152614f0081614ec4565b9050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614f47614f4283614f07565b614f14565b9050919050565b614f57816141c7565b82525050565b6000819050919050565b6000614f7a614f7583614f07565b614f5d565b9050919050565b600060ff82169050919050565b6000614fa1614f9c83614f07565b614f81565b9050919050565b614fb181614205565b82525050565b60c082016000808301549050614fcc81614f34565b614fd96000860182614f4e565b5060018301549050614fea81614f67565b614ff76020860182614908565b506002830154905061500881614f34565b6150156040860182614f4e565b506003830154905061502681614f67565b6150336060860182614908565b506004830154905061504481614f8e565b6150516080860182614fa8565b506005830154905061506281614f67565b61506f60a0860182614908565b5050505050565b600060c08201905061508b6000830184614fb7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806150d857607f821691505b6020821081036150eb576150ea615091565b5b50919050565b7f5a45524f5f4150504c595f434f554e5400000000000000000000000000000000600082015250565b60006151276010836146de565b9150615132826150f1565b602082019050919050565b600060208201905081810360008301526151568161511a565b9050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b60006151936011836146de565b915061519e8261515d565b602082019050919050565b600060208201905081810360008301526151c281615186565b9050919050565b60006151d482614062565b91506151df83614062565b92508282039050818111156151f7576151f6614d4c565b5b92915050565b7f48415443485f49445f4f564552464c4f57000000000000000000000000000000600082015250565b60006152336011836146de565b915061523e826151fd565b602082019050919050565b6000602082019050818103600083015261526281615226565b9050919050565b7f424c4f434b434f554e545f4f564552464c4f5700000000000000000000000000600082015250565b600061529f6013836146de565b91506152aa82615269565b602082019050919050565b600060208201905081810360008301526152ce81615292565b9050919050565b60006060820190506152ea60008301866142aa565b6152f760208301856142b9565b61530460408301846142b9565b949350505050565b60a08201600080830154905061532181614f67565b61532e6000860182614908565b506001830154905061533f81614f67565b61534c6020860182614908565b506002830154905061535d81614f67565b61536a6040860182614908565b506003830154905061537b81614f67565b6153886060860182614908565b506004830154905061539981614f34565b6153a66080860182614f4e565b5050505050565b600060a0820190506153c2600083018461530c565b92915050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b60006153fe6010836146de565b9150615409826153c8565b602082019050919050565b6000602082019050818103600083015261542d816153f1565b9050919050565b7f4e4f545f555345525f4841544348494e47000000000000000000000000000000600082015250565b600061546a6011836146de565b915061547582615434565b602082019050919050565b600060208201905081810360008301526154998161545d565b9050919050565b7f48415443485f424c4f434b5f4552520000000000000000000000000000000000600082015250565b60006154d6600f836146de565b91506154e1826154a0565b602082019050919050565b60006020820190508181036000830152615505816154c9565b9050919050565b7f48415443485f5354494c4c5f4c4f434b45440000000000000000000000000000600082015250565b60006155426012836146de565b915061554d8261550c565b602082019050919050565b6000602082019050818103600083015261557181615535565b9050919050565b7f48415443485f434f4e53554d455f455252000000000000000000000000000000600082015250565b60006155ae6011836146de565b91506155b982615578565b602082019050919050565b600060208201905081810360008301526155dd816155a1565b9050919050565b60006040820190506155f960008301856142aa565b61560660208301846142b9565b9392505050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b60006156436012836146de565b915061564e8261560d565b602082019050919050565b6000602082019050818103600083015261567281615636565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b60006156af600e836146de565b91506156ba82615679565b602082019050919050565b600060208201905081810360008301526156de816156a2565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b600061571b600c836146de565b9150615726826156e5565b602082019050919050565b6000602082019050818103600083015261574a8161570e565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026157b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615776565b6157bd8683615776565b95508019841693508086168417925050509392505050565b6000819050919050565b60006157fa6157f56157f084614062565b6157d5565b614062565b9050919050565b6000819050919050565b615814836157df565b61582861582082615801565b848454615783565b825550505050565b600090565b61583d615830565b61584881848461580b565b505050565b5b8181101561586c57615861600082615835565b60018101905061584e565b5050565b601f8211156158b15761588281615751565b61588b84615766565b8101602085101561589a578190505b6158ae6158a685615766565b83018261584d565b50505b505050565b600082821c905092915050565b60006158d4600019846008026158b6565b1980831691505092915050565b60006158ed83836158c3565b9150826002028217905092915050565b615906826146d3565b67ffffffffffffffff81111561591f5761591e613fb6565b5b61592982546150c0565b615934828285615870565b600060209050601f8311600181146159675760008415615955578287015190505b61595f85826158e1565b8655506159c7565b601f19841661597586615751565b60005b8281101561599d57848901518255600182019150602085019450602081019050615978565b868310156159ba57848901516159b6601f8916826158c3565b8355505b6001600288020188555050505b505050505050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615a05600b836146de565b9150615a10826159cf565b602082019050919050565b60006020820190508181036000830152615a34816159f8565b9050919050565b600081519050615a4a81614211565b92915050565b600060208284031215615a6657615a65613f96565b5b6000615a7484828501615a3b565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615ab3600b836146de565b9150615abe82615a7d565b602082019050919050565b60006020820190508181036000830152615ae281615aa6565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615b1f600b836146de565b9150615b2a82615ae9565b602082019050919050565b60006020820190508181036000830152615b4e81615b12565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615bba600f836146de565b9150615bc582615b84565b602082019050919050565b60006020820190508181036000830152615be981615bad565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b6000615c266010836146de565b9150615c3182615bf0565b602082019050919050565b60006020820190508181036000830152615c5581615c19565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b6000615c926010836146de565b9150615c9d82615c5c565b602082019050919050565b60006020820190508181036000830152615cc181615c85565b9050919050565b600081519050615cd78161406c565b92915050565b600060208284031215615cf357615cf2613f96565b5b6000615d0184828501615cc8565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b6000615d406014836146de565b9150615d4b82615d0a565b602082019050919050565b60006020820190508181036000830152615d6f81615d33565b9050919050565b6000606082019050615d8b60008301866142aa565b615d9860208301856142aa565b615da560408301846142b9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615e1181615ddc565b82525050565b6000602082019050615e2c6000830184615e08565b9291505056fea2646970667358221220364668ac37d7c2ebd924c059c2b23b273dd8c2afc705d5ed6142dfbba6dc261064736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f486f706576657273652048617463680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a486174636820466f6d756c6120666f7220486f70657665727365000000000000
Deployed ByteCode
0x6080604052600436106101f95760003560e01c806376967cbf1161010d578063bb21ac54116100a0578063e30c39781161006f578063e30c397814610763578063e55661bd1461078e578063eaed4d70146107cb578063f2fde38b146107f4578063f674c8311461081d576101f9565b8063bb21ac541461067f578063dd99b73d146106a8578063dda0da00146106e9578063df8e759a14610726576101f9565b80639e9cceac116100dc5780639e9cceac146105b3578063a3066e43146105dc578063b8c7871a14610605578063ba84860814610642576101f9565b806376967cbf1461051d57806379ba509714610546578063839d7f111461055d5780638da5cb5b14610588576101f9565b80633a525c29116101905780635458c28e1161015f5780635458c28e146104575780635af9d736146104805780636302690c146104c15780636586bb70146104dd578063715018a614610506576101f9565b80633a525c291461039b5780633b9ebeec146103c65780633f84dc1b146103ef57806348ec0ffb1461041a576101f9565b80631a7db56e116101cc5780631a7db56e146102cf5780632680976d146102f8578063284293cf1461033557806330546c9b14610372576101f9565b80630f6bec9a146101fe5780630fe4215914610227578063189357ff1461025057806319df118214610292575b600080fd5b34801561020a57600080fd5b506102256004803603810190610220919061412f565b610848565b005b34801561023357600080fd5b5061024e6004803603810190610249919061423d565b6108f6565b005b34801561025c57600080fd5b506102776004803603810190610272919061427d565b6109c8565b604051610289969594939291906142d7565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b4919061427d565b610b0c565b6040516102c69190614338565b60405180910390f35b3480156102db57600080fd5b506102f660048036038101906102f19190614416565b610b36565b005b34801561030457600080fd5b5061031f600480360381019061031a9190614543565b610be4565b60405161032c919061466f565b60405180910390f35b34801561034157600080fd5b5061035c6004803603810190610357919061427d565b610e59565b6040516103699190614338565b60405180910390f35b34801561037e57600080fd5b506103996004803603810190610394919061468a565b610e83565b005b3480156103a757600080fd5b506103b0610ed1565b6040516103bd9190614752565b60405180910390f35b3480156103d257600080fd5b506103ed60048036038101906103e89190614837565b610f63565b005b3480156103fb57600080fd5b50610404611011565b604051610411919061466f565b60405180910390f35b34801561042657600080fd5b50610441600480360381019061043c91906148af565b61101b565b60405161044e919061499a565b60405180910390f35b34801561046357600080fd5b5061047e60048036038101906104799190614416565b6110b2565b005b34801561048c57600080fd5b506104a760048036038101906104a2919061427d565b611160565b6040516104b89594939291906149bc565b60405180910390f35b6104db60048036038101906104d69190614a0f565b611234565b005b3480156104e957600080fd5b5061050460048036038101906104ff91906148af565b6116b7565b005b34801561051257600080fd5b5061051b6117cd565b005b34801561052957600080fd5b50610544600480360381019061053f9190614b30565b6117e1565b005b34801561055257600080fd5b5061055b61188f565b005b34801561056957600080fd5b5061057261191e565b60405161057f9190614752565b60405180910390f35b34801561059457600080fd5b5061059d6119b0565b6040516105aa9190614ba8565b60405180910390f35b3480156105bf57600080fd5b506105da60048036038101906105d5919061427d565b6119d9565b005b3480156105e857600080fd5b5061060360048036038101906105fe9190614b30565b611ed8565b005b34801561061157600080fd5b5061062c6004803603810190610627919061427d565b611f86565b6040516106399190614338565b60405180910390f35b34801561064e57600080fd5b50610669600480360381019061066491906148af565b611fb1565b6040516106769190614338565b60405180910390f35b34801561068b57600080fd5b506106a660048036038101906106a191906148af565b612007565b005b3480156106b457600080fd5b506106cf60048036038101906106ca919061427d565b612112565b6040516106e0959493929190614bc3565b60405180910390f35b3480156106f557600080fd5b50610710600480360381019061070b919061427d565b6122a9565b60405161071d9190614338565b60405180910390f35b34801561073257600080fd5b5061074d6004803603810190610748919061427d565b6122bb565b60405161075a9190614ba8565b60405180910390f35b34801561076f57600080fd5b5061077861235a565b6040516107859190614ba8565b60405180910390f35b34801561079a57600080fd5b506107b560048036038101906107b0919061427d565b612384565b6040516107c29190614ba8565b60405180910390f35b3480156107d757600080fd5b506107f260048036038101906107ed9190614c24565b612423565b005b34801561080057600080fd5b5061081b600480360381019061081691906148af565b61261b565b005b34801561082957600080fd5b506108326126c8565b60405161083f919061466f565b60405180910390f35b6108506126d2565b8051825114610894576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161088b90614cfd565b60405180910390fd5b60005b82518110156108f1576108de8382815181106108b6576108b5614d1d565b5b60200260200101518383815181106108d1576108d0614d1d565b5b602002602001015161276c565b80806108e990614d7b565b915050610897565b505050565b6108fe6127d0565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361096d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161096490614e0f565b60405180910390fd5b80600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6000806000806000806000600d60008981526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff161515151581526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610b3e6126d2565b8051825114610b82576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7990614cfd565b60405180910390fd5b60005b8251811015610bdf57610bcc838281518110610ba457610ba3614d1d565b5b6020026020010151838381518110610bbf57610bbe614d1d565b5b6020026020010151612857565b8080610bd790614d7b565b915050610b85565b505050565b6000610bee6127d0565b60008c5111610c32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2990614e7b565b60405180910390fd5b600080610c4b600160105461296490919063ffffffff16565b9150915081610c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8690614ee7565b60405180910390fd5b80601081905550610ca5818f8f8a8a8a8a612993565b610caf8c8c612ac5565b6000610cbb8b8b612bd0565b90506040518060c001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018d81526020018c73ffffffffffffffffffffffffffffffffffffffff1681526020018b815260200182151581526020018a815250600d600084815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160050155905050817fdcbded9d6d08a735a46516026e72f3d8a35ed314ba69e1f86393f87fe79fed90600d6000858152602001908152602001600020604051610e3c9190615076565b60405180910390a28193505050509b9a5050505050505050505050565b60006007600083815260200190815260200160002060009054906101000a900460ff169050919050565b610e8b6126d2565b60005b8151811015610ecd57610eba828281518110610ead57610eac614d1d565b5b6020026020010151612d04565b8080610ec590614d7b565b915050610e8e565b5050565b606060028054610ee0906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054610f0c906150c0565b8015610f595780601f10610f2e57610100808354040283529160200191610f59565b820191906000526020600020905b815481529060010190602001808311610f3c57829003601f168201915b5050505050905090565b610f6b6126d2565b8051825114610faf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fa690614cfd565b60405180910390fd5b60005b825181101561100c57610ff9838281518110610fd157610fd0614d1d565b5b6020026020010151838381518110610fec57610feb614d1d565b5b6020026020010151612d98565b808061100490614d7b565b915050610fb2565b505050565b6000601054905090565b6060600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806020026020016040519081016040528092919081815260200182805480156110a657602002820191906000526020600020905b815481526020019060010190808311611092575b50505050509050919050565b6110ba6126d2565b80518251146110fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110f590614cfd565b60405180910390fd5b60005b825181101561115b576111488382815181106111205761111f614d1d565b5b602002602001015183838151811061113b5761113a614d1d565b5b6020026020010151612e0f565b808061115390614d7b565b915050611101565b505050565b600080600080600080600f60008881526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050905080600001518160200151826040015183606001518460800151955095509550955095505091939590929450565b60008111611277576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126e9061513d565b60405180910390fd5b61128082610b0c565b6112bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b6906151a9565b60405180910390fd5b6112c882612f1c565b60006001436112d791906151c9565b90506000600d60008581526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152505090506000806113f9600160115461296490919063ffffffff16565b915091508161143d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143490615249565b60405180910390fd5b600080611457878660a001516131c090919063ffffffff16565b915091508161149b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611492906152b5565b60405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff1663cbc7067c3387602001518a6040518463ffffffff1660e01b81526004016114e0939291906152d5565b600060405180830381600087803b1580156114fa57600080fd5b505af115801561150e573d6000803e3d6000fd5b50505050826011819055506040518060a00160405280898152602001878152602001600081526020018881526020013373ffffffffffffffffffffffffffffffffffffffff16815250600f60008581526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083908060018154018082558091505060019003906000526020600020016000909190919091505561164c8888613213565b823373ffffffffffffffffffffffffffffffffffffffff167f8f4924c453b998e3a92f80c1cd55a4040260f3077b645e092c25bd98505ce915600f60008781526020019081526020016000206040516116a591906153ad565b60405180910390a35050505050505050565b6116bf6126d2565b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415801561174a5750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b611789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178090615414565b60405180910390fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6117d56127d0565b6117df6000613619565b565b6117e96126d2565b805182511461182d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182490614cfd565b60405180910390fd5b60005b825181101561188a5761187783828151811061184f5761184e614d1d565b5b602002602001015183838151811061186a57611869614d1d565b5b602002602001015161364a565b808061188290614d7b565b915050611830565b505050565b6000611899613715565b90508073ffffffffffffffffffffffffffffffffffffffff166118ba61235a565b73ffffffffffffffffffffffffffffffffffffffff161461191257806040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016119099190614ba8565b60405180910390fd5b61191b81613619565b50565b60606003805461192d906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054611959906150c0565b80156119a65780601f1061197b576101008083540402835291602001916119a6565b820191906000526020600020905b81548152906001019060200180831161198957829003601f168201915b5050505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806119e6338461371d565b9150915081611a2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2190615480565b60405180910390fd5b6000600f60008581526020019081526020016000206040518060a0016040529081600082015481526020016001820154815260200160028201548152602001600382015481526020016004820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250509050611ad78160000151610b0c565b611b16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0d906151a9565b60405180910390fd5b611b238160000151612f1c565b6000600143611b3291906151c9565b90508160200151811015611b7b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b72906154ec565b60405180910390fd5b6000600d6000846000015181526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff161515151581526020016005820154815250509050600080611ca485606001518460a001516131c090919063ffffffff16565b91509150818015611cc4575080856020015185611cc191906151c9565b10155b611d03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cfa90615558565b60405180910390fd5b6000611d0f3388613806565b905080611d51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d48906155c4565b60405180910390fd5b836080015115611ddb57836040015173ffffffffffffffffffffffffffffffffffffffff166325f5e8ee33866060015189606001516040518463ffffffff1660e01b8152600401611da4939291906152d5565b600060405180830381600087803b158015611dbe57600080fd5b505af1158015611dd2573d6000803e3d6000fd5b50505050611e51565b836040015173ffffffffffffffffffffffffffffffffffffffff1663f0a8587b3388606001516040518363ffffffff1660e01b8152600401611e1e9291906155e4565b600060405180830381600087803b158015611e3857600080fd5b505af1158015611e4c573d6000803e3d6000fd5b505050505b84600f60008b815260200190815260200160002060020181905550883373ffffffffffffffffffffffffffffffffffffffff167f63380c9bc749b31ce5d02727247809f2271e76e71f272ddab5fe2d20ef1f094f600f60008d8152602001908152602001600020604051611ec591906153ad565b60405180910390a3505050505050505050565b611ee06126d2565b8051825114611f24576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1b90614cfd565b60405180910390fd5b60005b8251811015611f8157611f6e838281518110611f4657611f45614d1d565b5b6020026020010151838381518110611f6157611f60614d1d565b5b6020026020010151613a09565b8080611f7990614d7b565b915050611f27565b505050565b600080600460008481526020019081526020016000208054611fa7906150c0565b9050119050919050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b61200f6126d2565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16148061208f575061208e7f36372b07000000000000000000000000000000000000000000000000000000008273ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b6120ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c590615659565b60405180910390fd5b80600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606080600080600060046000878152602001908152602001600020600560008881526020019081526020016000206006600089815260200190815260200160002054600760008a815260200190815260200160002060009054906101000a900460ff1661217e8a6122bb565b84805461218a906150c0565b80601f01602080910402602001604051908101604052809291908181526020018280546121b6906150c0565b80156122035780601f106121d857610100808354040283529160200191612203565b820191906000526020600020905b8154815290600101906020018083116121e657829003601f168201915b50505050509450838054612216906150c0565b80601f0160208091040260200160405190810160405280929190818152602001828054612242906150c0565b801561228f5780601f106122645761010080835404028352916020019161228f565b820191906000526020600020905b81548152906001019060200180831161227257829003601f168201915b505050505093509450945094509450945091939590929450565b60006122b482611f86565b9050919050565b6000806008600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361235057600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612352565b805b915050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806009600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361241957600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661241b565b805b915050919050565b61242b6127d0565b61243486611f86565b612473576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246a906156c5565b60405180910390fd5b61247d8585612ac5565b60006124898484612bd0565b90506040518060c001604052808773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001821515815260200183815250600d600089815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160050155905050867fbc06c35f688bd191247fc768d528b4450014fe12b7d0ff806a8c0310cf9d9e29600d60008a815260200190815260200160002060405161260a9190615076565b60405180910390a250505050505050565b6126236127d0565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff166126836119b0565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000601154905090565b60006126dc613715565b90508073ffffffffffffffffffffffffffffffffffffffff166126fd6119b0565b73ffffffffffffffffffffffffffffffffffffffff1614158015612727575061272581613a9b565b155b1561276957806040517f8a08cbf50000000000000000000000000000000000000000000000000000000081526004016127609190614ba8565b60405180910390fd5b50565b61277582611f86565b6127b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127ab906156c5565b60405180910390fd5b8060066000848152602001908152602001600020819055505050565b6127d8613715565b73ffffffffffffffffffffffffffffffffffffffff166127f66119b0565b73ffffffffffffffffffffffffffffffffffffffff161461285557612819613715565b6040517f118cdaa700000000000000000000000000000000000000000000000000000000815260040161284c9190614ba8565b60405180910390fd5b565b61286082611f86565b61289f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612896906156c5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361290e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161290590615731565b60405180910390fd5b806008600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080600083850190508481101561298357600080925092505061298c565b60018192509250505b9250929050565b856004600089815260200190815260200160002090816129b391906158fd565b50846005600089815260200190815260200160002090816129d491906158fd565b50836006600089815260200190815260200160002081905550826007600089815260200190815260200160002060006101000a81548160ff021916908315150217905550816008600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806009600089815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050505050565b612ace82613af1565b612b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0490615a1b565b60405180910390fd5b60008290508073ffffffffffffffffffffffffffffffffffffffff1663b419c807836040518263ffffffff1660e01b8152600401612b4b919061466f565b602060405180830381865afa158015612b68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b8c9190615a50565b612bcb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bc290615ac9565b60405180910390fd5b505050565b600080612bdc84613af1565b90506000612be985613b7b565b90508180612bf45750805b612c33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c2a90615b35565b60405180910390fd5b8115612cf95760008590508073ffffffffffffffffffffffffffffffffffffffff1663b419c807866040518263ffffffff1660e01b8152600401612c77919061466f565b602060405180830381865afa158015612c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb89190615a50565b612cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cee90615ac9565b60405180910390fd5b505b819250505092915050565b612d0d81611f86565b612d4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d43906156c5565b60405180910390fd5b612d5581613c05565b612d5e81613cec565b7f63990d06670189d4fb8d01ea4be2772448398bd273ca4e119185ef26ee5007b781604051612d8d919061466f565b60405180910390a150565b612da182611f86565b612de0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612dd7906156c5565b60405180910390fd5b806007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b612e1882611f86565b612e57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e4e906156c5565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612ec6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebd90615731565b60405180910390fd5b806009600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600d60008381526020019081526020016000206040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152505090506000816000015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80783602001516040518263ffffffff1660e01b8152600401613069919061466f565b602060405180830381865afa158015613086573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130aa9190615a50565b6130e9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130e090615ac9565b60405180910390fd5b8160800151156131bb576000826040015190508073ffffffffffffffffffffffffffffffffffffffff1663b419c80784606001516040518263ffffffff1660e01b8152600401613139919061466f565b602060405180830381865afa158015613156573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061317a9190615a50565b6131b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131b090615ac9565b60405180910390fd5b505b505050565b600080600084036131d857600160009150915061320c565b60008385029050838582816131f0576131ef615b55565b5b041461320357600080925092505061320c565b60018192509250505b9250929050565b60008111613256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161324d90615bd0565b60405180910390fd5b6000600660008481526020019081526020016000205490506000810361327c5750613615565b6000613287846122bb565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036132f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ef90615c3c565b60405180910390fd5b60008061330e85856131c090919063ffffffff16565b9150915081613352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161334990615ca8565b60405180910390fd5b600061335d87612384565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461352c5760008173ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016133ce9190614ba8565b602060405180830381865afa1580156133eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061340f9190615cdd565b905082811015613454576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161344b90615d56565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166323b872dd3387866040518463ffffffff1660e01b815260040161349193929190615d76565b6020604051808303816000875af11580156134b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d49190615a50565b506000341115613526573373ffffffffffffffffffffffffffffffffffffffff166108fc349081150290604051600060405180830381858888f19350505050158015613524573d6000803e3d6000fd5b505b5061360f565b8134101561356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161356690615d56565b60405180910390fd5b6000823461357d91906151c9565b90508473ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156135c5573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561360c573d6000803e3d6000fd5b50505b50505050505b5050565b600160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905561364781613d7f565b50565b600060046000848152602001908152602001600020805461366a906150c0565b9050116136ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136a3906156c5565b60405180910390fd5b60008151116136f0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136e790614e7b565b60405180910390fd5b8060046000848152602001908152602001600020908161371091906158fd565b505050565b600033905090565b6000806000600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060005b818110156137f55784600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002082815481106137c4576137c3614d1d565b5b9060005260206000200154036137e2576001819350935050506137ff565b80806137ed90614d7b565b91505061376a565b5060008092509250505b9250929050565b600080600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060008111801561385d57508083105b156139fd57600060018261387191906151c9565b9050600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081815481106138c4576138c3614d1d565b5b9060005260206000200154600e60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002085815481106139205761391f614d1d565b5b9060005260206000200181905550600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020818154811061397f5761397e614d1d565b5b9060005260206000200160009055600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054806139dc576139db615dad565b5b60019003818190600052602060002001600090559055600192505050613a03565b60009150505b92915050565b613a1282611f86565b613a51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a48906156c5565b60405180910390fd5b80600560008481526020019081526020016000209081613a7191906158fd565b505050565b6000613a8183613e43565b8015613a935750613a928383613e90565b5b905092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613b745750613b737ff4e25cdb000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614158015613bfe5750613bfd7f87c91820000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff16613a7690919063ffffffff16565b5b9050919050565b600460008281526020019081526020016000206000613c249190613f2f565b600560008281526020019081526020016000206000613c439190613f2f565b60066000828152602001908152602001600020600090556007600082815260200190815260200160002060006101000a81549060ff02191690556008600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556009600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550565b600d6000828152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905560038201600090556004820160006101000a81549060ff02191690556005820160009055505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000613e6f827f01ffc9a700000000000000000000000000000000000000000000000000000000613e90565b8015613e895750613e878263ffffffff60e01b613e90565b155b9050919050565b60008082604051602401613ea49190615e17565b6040516020818303038152906040526301ffc9a760e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000806000602060008551602087018a617530fa92503d91506000519050828015613f17575060208210155b8015613f235750600081115b94505050505092915050565b508054613f3b906150c0565b6000825580601f10613f4d5750613f6c565b601f016020900490600052602060002090810190613f6b9190613f6f565b5b50565b5b80821115613f88576000816000905550600101613f70565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613fee82613fa5565b810181811067ffffffffffffffff8211171561400d5761400c613fb6565b5b80604052505050565b6000614020613f8c565b905061402c8282613fe5565b919050565b600067ffffffffffffffff82111561404c5761404b613fb6565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b61407581614062565b811461408057600080fd5b50565b6000813590506140928161406c565b92915050565b60006140ab6140a684614031565b614016565b905080838252602082019050602084028301858111156140ce576140cd61405d565b5b835b818110156140f757806140e38882614083565b8452602084019350506020810190506140d0565b5050509392505050565b600082601f83011261411657614115613fa0565b5b8135614126848260208601614098565b91505092915050565b6000806040838503121561414657614145613f96565b5b600083013567ffffffffffffffff81111561416457614163613f9b565b5b61417085828601614101565b925050602083013567ffffffffffffffff81111561419157614190613f9b565b5b61419d85828601614101565b9150509250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006141d2826141a7565b9050919050565b6141e2816141c7565b81146141ed57600080fd5b50565b6000813590506141ff816141d9565b92915050565b60008115159050919050565b61421a81614205565b811461422557600080fd5b50565b60008135905061423781614211565b92915050565b6000806040838503121561425457614253613f96565b5b6000614262858286016141f0565b925050602061427385828601614228565b9150509250929050565b60006020828403121561429357614292613f96565b5b60006142a184828501614083565b91505092915050565b6142b3816141c7565b82525050565b6142c281614062565b82525050565b6142d181614205565b82525050565b600060c0820190506142ec60008301896142aa565b6142f960208301886142b9565b61430660408301876142aa565b61431360608301866142b9565b61432060808301856142c8565b61432d60a08301846142b9565b979650505050505050565b600060208201905061434d60008301846142c8565b92915050565b600067ffffffffffffffff82111561436e5761436d613fb6565b5b602082029050602081019050919050565b600061439261438d84614353565b614016565b905080838252602082019050602084028301858111156143b5576143b461405d565b5b835b818110156143de57806143ca88826141f0565b8452602084019350506020810190506143b7565b5050509392505050565b600082601f8301126143fd576143fc613fa0565b5b813561440d84826020860161437f565b91505092915050565b6000806040838503121561442d5761442c613f96565b5b600083013567ffffffffffffffff81111561444b5761444a613f9b565b5b61445785828601614101565b925050602083013567ffffffffffffffff81111561447857614477613f9b565b5b614484858286016143e8565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156144ae576144ad613fb6565b5b6144b782613fa5565b9050602081019050919050565b82818337600083830152505050565b60006144e66144e184614493565b614016565b9050828152602081018484840111156145025761450161448e565b5b61450d8482856144c4565b509392505050565b600082601f83011261452a57614529613fa0565b5b813561453a8482602086016144d3565b91505092915050565b60008060008060008060008060008060006101608c8e03121561456957614568613f96565b5b60008c013567ffffffffffffffff81111561458757614586613f9b565b5b6145938e828f01614515565b9b505060208c013567ffffffffffffffff8111156145b4576145b3613f9b565b5b6145c08e828f01614515565b9a505060406145d18e828f016141f0565b99505060606145e28e828f01614083565b98505060806145f38e828f016141f0565b97505060a06146048e828f01614083565b96505060c06146158e828f01614083565b95505060e06146268e828f01614083565b9450506101006146388e828f01614228565b93505061012061464a8e828f016141f0565b92505061014061465c8e828f016141f0565b9150509295989b509295989b9093969950565b600060208201905061468460008301846142b9565b92915050565b6000602082840312156146a05761469f613f96565b5b600082013567ffffffffffffffff8111156146be576146bd613f9b565b5b6146ca84828501614101565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561470d5780820151818401526020810190506146f2565b60008484015250505050565b6000614724826146d3565b61472e81856146de565b935061473e8185602086016146ef565b61474781613fa5565b840191505092915050565b6000602082019050818103600083015261476c8184614719565b905092915050565b600067ffffffffffffffff82111561478f5761478e613fb6565b5b602082029050602081019050919050565b60006147b36147ae84614774565b614016565b905080838252602082019050602084028301858111156147d6576147d561405d565b5b835b818110156147ff57806147eb8882614228565b8452602084019350506020810190506147d8565b5050509392505050565b600082601f83011261481e5761481d613fa0565b5b813561482e8482602086016147a0565b91505092915050565b6000806040838503121561484e5761484d613f96565b5b600083013567ffffffffffffffff81111561486c5761486b613f9b565b5b61487885828601614101565b925050602083013567ffffffffffffffff81111561489957614898613f9b565b5b6148a585828601614809565b9150509250929050565b6000602082840312156148c5576148c4613f96565b5b60006148d3848285016141f0565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61491181614062565b82525050565b60006149238383614908565b60208301905092915050565b6000602082019050919050565b6000614947826148dc565b61495181856148e7565b935061495c836148f8565b8060005b8381101561498d5781516149748882614917565b975061497f8361492f565b925050600181019050614960565b5085935050505092915050565b600060208201905081810360008301526149b4818461493c565b905092915050565b600060a0820190506149d160008301886142b9565b6149de60208301876142b9565b6149eb60408301866142b9565b6149f860608301856142b9565b614a0560808301846142aa565b9695505050505050565b60008060408385031215614a2657614a25613f96565b5b6000614a3485828601614083565b9250506020614a4585828601614083565b9150509250929050565b600067ffffffffffffffff821115614a6a57614a69613fb6565b5b602082029050602081019050919050565b6000614a8e614a8984614a4f565b614016565b90508083825260208201905060208402830185811115614ab157614ab061405d565b5b835b81811015614af857803567ffffffffffffffff811115614ad657614ad5613fa0565b5b808601614ae38982614515565b85526020850194505050602081019050614ab3565b5050509392505050565b600082601f830112614b1757614b16613fa0565b5b8135614b27848260208601614a7b565b91505092915050565b60008060408385031215614b4757614b46613f96565b5b600083013567ffffffffffffffff811115614b6557614b64613f9b565b5b614b7185828601614101565b925050602083013567ffffffffffffffff811115614b9257614b91613f9b565b5b614b9e85828601614b02565b9150509250929050565b6000602082019050614bbd60008301846142aa565b92915050565b600060a0820190508181036000830152614bdd8188614719565b90508181036020830152614bf18187614719565b9050614c0060408301866142b9565b614c0d60608301856142c8565b614c1a60808301846142aa565b9695505050505050565b60008060008060008060c08789031215614c4157614c40613f96565b5b6000614c4f89828a01614083565b9650506020614c6089828a016141f0565b9550506040614c7189828a01614083565b9450506060614c8289828a016141f0565b9350506080614c9389828a01614083565b92505060a0614ca489828a01614083565b9150509295509295509295565b7f504152414d5f44494d5f4d49534d415443480000000000000000000000000000600082015250565b6000614ce76012836146de565b9150614cf282614cb1565b602082019050919050565b60006020820190508181036000830152614d1681614cda565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614d8682614062565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614db857614db7614d4c565b5b600182019050919050565b7f4e756c6c204164647265737320616c6c6f776564000000000000000000000000600082015250565b6000614df96014836146de565b9150614e0482614dc3565b602082019050919050565b60006020820190508181036000830152614e2881614dec565b9050919050565b7f4e4f5f54504c5f4e414d45000000000000000000000000000000000000000000600082015250565b6000614e65600b836146de565b9150614e7082614e2f565b602082019050919050565b60006020820190508181036000830152614e9481614e58565b9050919050565b7f54504c5f49445f4f564552464c4f570000000000000000000000000000000000600082015250565b6000614ed1600f836146de565b9150614edc82614e9b565b602082019050919050565b60006020820190508181036000830152614f0081614ec4565b9050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000614f47614f4283614f07565b614f14565b9050919050565b614f57816141c7565b82525050565b6000819050919050565b6000614f7a614f7583614f07565b614f5d565b9050919050565b600060ff82169050919050565b6000614fa1614f9c83614f07565b614f81565b9050919050565b614fb181614205565b82525050565b60c082016000808301549050614fcc81614f34565b614fd96000860182614f4e565b5060018301549050614fea81614f67565b614ff76020860182614908565b506002830154905061500881614f34565b6150156040860182614f4e565b506003830154905061502681614f67565b6150336060860182614908565b506004830154905061504481614f8e565b6150516080860182614fa8565b506005830154905061506281614f67565b61506f60a0860182614908565b5050505050565b600060c08201905061508b6000830184614fb7565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806150d857607f821691505b6020821081036150eb576150ea615091565b5b50919050565b7f5a45524f5f4150504c595f434f554e5400000000000000000000000000000000600082015250565b60006151276010836146de565b9150615132826150f1565b602082019050919050565b600060208201905081810360008301526151568161511a565b9050919050565b7f54454d504c4154455f44495341424c4544000000000000000000000000000000600082015250565b60006151936011836146de565b915061519e8261515d565b602082019050919050565b600060208201905081810360008301526151c281615186565b9050919050565b60006151d482614062565b91506151df83614062565b92508282039050818111156151f7576151f6614d4c565b5b92915050565b7f48415443485f49445f4f564552464c4f57000000000000000000000000000000600082015250565b60006152336011836146de565b915061523e826151fd565b602082019050919050565b6000602082019050818103600083015261526281615226565b9050919050565b7f424c4f434b434f554e545f4f564552464c4f5700000000000000000000000000600082015250565b600061529f6013836146de565b91506152aa82615269565b602082019050919050565b600060208201905081810360008301526152ce81615292565b9050919050565b60006060820190506152ea60008301866142aa565b6152f760208301856142b9565b61530460408301846142b9565b949350505050565b60a08201600080830154905061532181614f67565b61532e6000860182614908565b506001830154905061533f81614f67565b61534c6020860182614908565b506002830154905061535d81614f67565b61536a6040860182614908565b506003830154905061537b81614f67565b6153886060860182614908565b506004830154905061539981614f34565b6153a66080860182614f4e565b5050505050565b600060a0820190506153c2600083018461530c565b92915050565b7f494e56414c49445f4d45524348414e5400000000000000000000000000000000600082015250565b60006153fe6010836146de565b9150615409826153c8565b602082019050919050565b6000602082019050818103600083015261542d816153f1565b9050919050565b7f4e4f545f555345525f4841544348494e47000000000000000000000000000000600082015250565b600061546a6011836146de565b915061547582615434565b602082019050919050565b600060208201905081810360008301526154998161545d565b9050919050565b7f48415443485f424c4f434b5f4552520000000000000000000000000000000000600082015250565b60006154d6600f836146de565b91506154e1826154a0565b602082019050919050565b60006020820190508181036000830152615505816154c9565b9050919050565b7f48415443485f5354494c4c5f4c4f434b45440000000000000000000000000000600082015250565b60006155426012836146de565b915061554d8261550c565b602082019050919050565b6000602082019050818103600083015261557181615535565b9050919050565b7f48415443485f434f4e53554d455f455252000000000000000000000000000000600082015250565b60006155ae6011836146de565b91506155b982615578565b602082019050919050565b600060208201905081810360008301526155dd816155a1565b9050919050565b60006040820190506155f960008301856142aa565b61560660208301846142b9565b9392505050565b7f554e535550504f52545f43555252454e43590000000000000000000000000000600082015250565b60006156436012836146de565b915061564e8261560d565b602082019050919050565b6000602082019050818103600083015261567281615636565b9050919050565b7f4e4f5f54504c5f444546494e4544000000000000000000000000000000000000600082015250565b60006156af600e836146de565b91506156ba82615679565b602082019050919050565b600060208201905081810360008301526156de816156a2565b9050919050565b7f4e554c4c5f414444524553530000000000000000000000000000000000000000600082015250565b600061571b600c836146de565b9150615726826156e5565b602082019050919050565b6000602082019050818103600083015261574a8161570e565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026157b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615776565b6157bd8683615776565b95508019841693508086168417925050509392505050565b6000819050919050565b60006157fa6157f56157f084614062565b6157d5565b614062565b9050919050565b6000819050919050565b615814836157df565b61582861582082615801565b848454615783565b825550505050565b600090565b61583d615830565b61584881848461580b565b505050565b5b8181101561586c57615861600082615835565b60018101905061584e565b5050565b601f8211156158b15761588281615751565b61588b84615766565b8101602085101561589a578190505b6158ae6158a685615766565b83018261584d565b50505b505050565b600082821c905092915050565b60006158d4600019846008026158b6565b1980831691505092915050565b60006158ed83836158c3565b9150826002028217905092915050565b615906826146d3565b67ffffffffffffffff81111561591f5761591e613fb6565b5b61592982546150c0565b615934828285615870565b600060209050601f8311600181146159675760008415615955578287015190505b61595f85826158e1565b8655506159c7565b601f19841661597586615751565b60005b8281101561599d57848901518255600182019150602085019450602081019050615978565b868310156159ba57848901516159b6601f8916826158c3565b8355505b6001600288020188555050505b505050505050565b7f495f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615a05600b836146de565b9150615a10826159cf565b602082019050919050565b60006020820190508181036000830152615a34816159f8565b9050919050565b600081519050615a4a81614211565b92915050565b600060208284031215615a6657615a65613f96565b5b6000615a7484828501615a3b565b91505092915050565b7f4e4f5f544f4b454e5f4944000000000000000000000000000000000000000000600082015250565b6000615ab3600b836146de565b9150615abe82615a7d565b602082019050919050565b60006020820190508181036000830152615ae281615aa6565b9050919050565b7f4f5f4241445f544f4b454e000000000000000000000000000000000000000000600082015250565b6000615b1f600b836146de565b9150615b2a82615ae9565b602082019050919050565b60006020820190508181036000830152615b4e81615b12565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f5a45524f5f4150504c59434f554e540000000000000000000000000000000000600082015250565b6000615bba600f836146de565b9150615bc582615b84565b602082019050919050565b60006020820190508181036000830152615be981615bad565b9050919050565b7f4e4f5f4d45524348414e545f4144445200000000000000000000000000000000600082015250565b6000615c266010836146de565b9150615c3182615bf0565b602082019050919050565b60006020820190508181036000830152615c5581615c19565b9050919050565b7f4f505f434f53545f4f564552464c4f5700000000000000000000000000000000600082015250565b6000615c926010836146de565b9150615c9d82615c5c565b602082019050919050565b60006020820190508181036000830152615cc181615c85565b9050919050565b600081519050615cd78161406c565b92915050565b600060208284031215615cf357615cf2613f96565b5b6000615d0184828501615cc8565b91505092915050565b7f554e53554646494349454e545f42414c414e4345000000000000000000000000600082015250565b6000615d406014836146de565b9150615d4b82615d0a565b602082019050919050565b60006020820190508181036000830152615d6f81615d33565b9050919050565b6000606082019050615d8b60008301866142aa565b615d9860208301856142aa565b615da560408301846142b9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b615e1181615ddc565b82525050565b6000602082019050615e2c6000830184615e08565b9291505056fea2646970667358221220364668ac37d7c2ebd924c059c2b23b273dd8c2afc705d5ed6142dfbba6dc261064736f6c63430008140033