Address Details
contract

0x253c85B8398cCDd941F97D12009103967f159Cc2

Contract Name
Billing
Creator
0x11a626–bdf79f at 0xff4bf0–c120dd
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
100 Transactions
Transfers
0 Transfers
Gas Used
10,327,314
Last Balance Update
14733761
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
Billing




Optimization enabled
false
Compiler version
v0.8.15+commit.e14f2714




EVM Version
london




Verified at
2022-09-30T08:26:00.641991Z

contracts/Invoice.sol

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.0 <0.9.0;

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

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

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @title Owner
 * @dev Set & change owner
 */
contract Owner {

    address private owner;
    
    // event for EVM logging
    event OwnerSet(address indexed oldOwner, address indexed newOwner);
    
    // modifier to check if caller is owner
    modifier isOwner() {
        // If the first argument of 'require' evaluates to 'false', execution terminates and all
        // changes to the state and to Ether balances are reverted.
        // This used to consume all gas in old EVM versions, but not anymore.
        // It is often a good idea to use 'require' to check if functions are called correctly.
        // As a second argument, you can also provide an explanation about what went wrong.
        require(msg.sender == owner, "Caller is not owner");
        _;
    }
    
    /**
     * @dev Set contract deployer as owner
     */
    constructor() {
        owner = msg.sender; // 'msg.sender' is sender of current call, contract deployer for a constructor
        emit OwnerSet(address(0), owner);
    }

    /**
     * @dev Change owner
     * @param newOwner address of new owner
     */
    function changeOwner(address newOwner) public isOwner {
        emit OwnerSet(owner, newOwner);
        owner = newOwner;
    }

    /**
     * @dev Return owner address 
     * @return address of owner
     */
    function getOwner() external view returns (address) {
        return owner;
    }
}

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

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

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

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

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

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

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

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

/**
 * @dev Contract to allow generate Invoice which can be paid by others.
 */
contract Billing is Pausable,Owner {

    using SafeMath for uint;

    // Events created for creating logs 
    event InvoiceCreated(
        uint invoiceID,
        address invoiceCreator,
        address tokenAddress,
        uint tokenAmountInWei,      
        address receiver
    );
    event InvoiceCancelled(
        uint invoiceID
    );
    event InvoicePaid(
        uint invoiceID,
        address isPaidBy,
        bool byReceiver
    );

    uint _invoiceID;

    struct invoice {
        address _invoiceCreator;
        address _tokenAddress;
        uint _tokenAmountInWei;      
        address payable _receiver;
        address _isPaidBy;
        bool _isCancelled;
    }

    mapping (uint => invoice) public invoices;

    /**
     * @dev Constructer to Initialize _invoiceID to 1
     */
    constructor(){
        _invoiceID = 1;
    }

    /**
     * @dev Return next Invoice ID, useful for making stream links. 
     * @return nextInvoiceID Next Invoice ID
     */
    function getNextInvoiceID() external view returns (uint nextInvoiceID){
        return _invoiceID;
    }

    /**
     * @dev Get details of an invoice
     *
     * @return invoiceCreator Address who created the invoice
     * @return tokenAddress Address of the token which token is to be transferred
     * @return tokenAmountInWei Number of tokens to be paid in smallest decimal of the token
     * @return receiver Address who should be paying for the invoice
     * @return isPaidBy Who paid for the stream, 0x00 if unpaid.
     * @return isCancelled If the stream is cancelled.
     */
    function getInvoice(
        uint invoiceID
        ) external view returns (
            address invoiceCreator,
            address tokenAddress,
            uint tokenAmountInWei,      
            address payable receiver,
            address isPaidBy,
            bool isCancelled
        ){
            return (invoices[invoiceID]._invoiceCreator, invoices[invoiceID]._tokenAddress, invoices[invoiceID]._tokenAmountInWei, invoices[invoiceID]._receiver, invoices[invoiceID]._isPaidBy, invoices[invoiceID]._isCancelled );
    }


    /**
     * @dev When invoice creator creates the invoice for themselves.
     *
     * @param tokenAddress Address of the token which token is to be transferred
     * @param tokenAmountInWei Number of tokens to be paid in smallest decimal of the token
     *
     * @return invoiceID the invoice ID
     */
    function createInvoice(
        address tokenAddress, 
        uint tokenAmountInWei
        ) external whenNotPaused returns (uint invoiceID) {
            return createInvoice(tokenAddress,tokenAmountInWei,_msgSender());
    }

    /**
     * @dev When invoice creator creates the invoice for Someoneelse.
     *
     * @param tokenAddress Address of the token which token is to be transferred
     * @param tokenAmountInWei Number of tokens to be paid in smallest decimal of the token
     * @param receiver the receiver who will receive the tokens
     * 
     * @return invoiceID the invoice ID
     */
    function createInvoice(
        address tokenAddress, 
        uint tokenAmountInWei,
        address receiver
        ) public whenNotPaused returns (uint invoiceID) {
            require(tokenAmountInWei > 0, "Token amount has to be greated than zero");
            require(tokenAddress != address(0), "Token address cannot be zero");
            require(invoices[_invoiceID]._invoiceCreator == address(0), "Invoice ID already used");

               uint currentInvoiceID = _invoiceID;
             _invoiceID = _invoiceID + 1;

            invoices[currentInvoiceID]._invoiceCreator        = _msgSender();
            invoices[currentInvoiceID]._tokenAddress          = tokenAddress;
            invoices[currentInvoiceID]._tokenAmountInWei      = tokenAmountInWei;
            invoices[currentInvoiceID]._receiver              = payable(receiver);
            invoices[currentInvoiceID]._isCancelled           = false;

         

            emit InvoiceCreated(
                currentInvoiceID,
                invoices[currentInvoiceID]._invoiceCreator, 
                invoices[currentInvoiceID]._tokenAddress,
                invoices[currentInvoiceID]._tokenAmountInWei,
                invoices[currentInvoiceID]._receiver
                );
          
            return currentInvoiceID;

    }

    /**
     * @dev Function to check if the invoice can be cancelled
     *
     * @param invoiceID the invoice ID
     * 
     * @return boolean value if the invoice can be cancelled by the caller
     */
    function canCancelInvoice(
        uint invoiceID
        ) public view returns (bool) {
            require(invoiceID > 0, "Invoice ID should be more than zero");
            require(! invoices[invoiceID]._isCancelled, "Invoice already cancelled");
            require(invoices[invoiceID]._isPaidBy == address(0), "Cannot cancel a paid invoice");
            require(invoices[invoiceID]._invoiceCreator == _msgSender(), "Invoice can only be cancelled by creater");

            return true;
    }

    /**
     * @dev Function to check if the invoice can be cancelled
     *
     * @param invoiceID the invoice ID
     * 
     * @return boolean value if the invoice is cancelled
     */
    function cancelInvoice(uint invoiceID) external returns (bool){
        require(canCancelInvoice(invoiceID));
        invoices[invoiceID]._isCancelled = true;
        
        // Emit event
        emit InvoiceCancelled(invoiceID);
        
        return true;
    }

    /**
     * @dev Function to check if the invoice is payable
     *
     * @param invoiceID the invoice ID
     * 
     * @return boolean value if the invoice can be paid
     */
    function canIPayTheInvoice(
            uint invoiceID
        ) public view returns (bool) {

            require(invoiceID > 0, "Invoice ID should be more than zero");

            // Check if this contract has allowance to transfer tokens on behalf of Invoice payer
            require(IERC20(invoices[invoiceID]._tokenAddress).allowance(_msgSender(),address(this)) >= invoices[invoiceID]._tokenAmountInWei, "Token approval amount not enough");

            //Check if the invoice is not cancelled
            require(! invoices[invoiceID]._isCancelled, "Invoice already cancelled");

            //Check if the invoice is not paid already
            require(invoices[invoiceID]._isPaidBy == address(0), "Invoice paid already");

            return true;
    }


    /**
     * @dev Function to pay the invoice
     *
     * @param invoiceID the invoice ID
     * 
     * @return boolean value if the invoice got paid
     */
    function payInvoice(
            uint invoiceID
        ) external returns (bool){
            require(canIPayTheInvoice(invoiceID), "You cannot pay for the invoice");
            
            // Transfer token from Invoice payer to receiver
            IERC20(invoices[invoiceID]._tokenAddress).transferFrom(_msgSender(), invoices[invoiceID]._invoiceCreator, invoices[invoiceID]._tokenAmountInWei);
            invoices[invoiceID]._isPaidBy = _msgSender();

            // Emit event
            emit InvoicePaid(invoiceID, _msgSender(), (invoices[invoiceID]._receiver == _msgSender()));

            return true;
    }

}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"InvoiceCancelled","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"InvoiceCreated","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256","indexed":false},{"type":"address","name":"invoiceCreator","internalType":"address","indexed":false},{"type":"address","name":"tokenAddress","internalType":"address","indexed":false},{"type":"uint256","name":"tokenAmountInWei","internalType":"uint256","indexed":false},{"type":"address","name":"receiver","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"InvoicePaid","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256","indexed":false},{"type":"address","name":"isPaidBy","internalType":"address","indexed":false},{"type":"bool","name":"byReceiver","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerSet","inputs":[{"type":"address","name":"oldOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"canCancelInvoice","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"canIPayTheInvoice","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"cancelInvoice","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeOwner","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}],"name":"createInvoice","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmountInWei","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}],"name":"createInvoice","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmountInWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"invoiceCreator","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmountInWei","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address payable"},{"type":"address","name":"isPaidBy","internalType":"address"},{"type":"bool","name":"isCancelled","internalType":"bool"}],"name":"getInvoice","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"nextInvoiceID","internalType":"uint256"}],"name":"getNextInvoiceID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"_invoiceCreator","internalType":"address"},{"type":"address","name":"_tokenAddress","internalType":"address"},{"type":"uint256","name":"_tokenAmountInWei","internalType":"uint256"},{"type":"address","name":"_receiver","internalType":"address payable"},{"type":"address","name":"_isPaidBy","internalType":"address"},{"type":"bool","name":"_isCancelled","internalType":"bool"}],"name":"invoices","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"payInvoice","inputs":[{"type":"uint256","name":"invoiceID","internalType":"uint256"}]}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b5060008060006101000a81548160ff02191690831515021790555033600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a360018081905550611ce1806100ff6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80636ed91d0f116100715780636ed91d0f146101bf578063893d20e8146101ef578063a6f9dae11461020d578063ac60a6cd14610229578063b095853214610259578063da9c273d14610289576100b4565b806308553e36146100b95780630be1177d146100e95780631ad6688b146101075780633a23cc0a146101375780634e6d14051461016c5780635c975abb146101a1575b600080fd5b6100d360048036038101906100ce91906112b6565b6102b9565b6040516100e09190611318565b60405180910390f35b6100f16106c9565b6040516100fe9190611318565b60405180910390f35b610121600480360381019061011c9190611333565b6106d3565b60405161012e919061137b565b60405180910390f35b610151600480360381019061014c9190611333565b6108d4565b604051610163969594939291906113c6565b60405180910390f35b61018660048036038101906101819190611333565b610a09565b604051610198969594939291906113c6565b60405180910390f35b6101a9610ad2565b6040516101b6919061137b565b60405180910390f35b6101d960048036038101906101d49190611333565b610ae8565b6040516101e6919061137b565b60405180910390f35b6101f7610d4f565b6040516102049190611427565b60405180910390f35b61022760048036038101906102229190611442565b610d78565b005b610243600480360381019061023e9190611333565b610ec8565b604051610250919061137b565b60405180910390f35b610273600480360381019061026e919061146f565b61112e565b6040516102809190611318565b60405180910390f35b6102a3600480360381019061029e9190611333565b611192565b6040516102b0919061137b565b60405180910390f35b60006102c3610ad2565b15610303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fa9061150c565b60405180910390fd5b60008311610346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161033d9061159e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036103b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ac9061160a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000600154815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461045c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045390611676565b60405180910390fd5b600060015490506001805461047191906116c5565b60018190555061047f611215565b6002600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846002600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550836002600083815260200190815260200160002060020181905550826002600083815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006002600083815260200190815260200160002060040160146101000a81548160ff0219169083151502179055507f2ed70a847e04cd32b671efc1fc252578d1013d9d78730ce21971254f514b4bd8816002600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660026000868152602001908152602001600020600201546002600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516106b695949392919061177a565b60405180910390a1809150509392505050565b6000600154905090565b6000808211610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070e9061183f565b60405180910390fd5b6002600083815260200190815260200160002060040160149054906101000a900460ff161561077b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610772906118ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081790611917565b60405180910390fd5b610828611215565b73ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c2906119a9565b60405180910390fd5b60019050919050565b6000806000806000806002600088815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008a815260200190815260200160002060020154600260008b815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008c815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008d815260200190815260200160002060040160149054906101000a900460ff1695509550955095509550955091939550919395565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160149054906101000a900460ff16905086565b60008060009054906101000a900460ff16905090565b6000808211610b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b239061183f565b60405180910390fd5b60026000838152602001908152602001600020600201546002600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e610b9d611215565b306040518363ffffffff1660e01b8152600401610bbb9291906119c9565b602060405180830381865afa158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611a07565b1015610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490611a80565b60405180910390fd5b6002600083815260200190815260200160002060040160149054906101000a900460ff1615610ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c98906118ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3d90611aec565b60405180910390fd5b60019050919050565b60008060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dff90611b58565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a380600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610ed382610ae8565b610f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0990611bc4565b60405180910390fd5b6002600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd610f6c611215565b6002600086815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660026000878152602001908152602001600020600201546040518463ffffffff1660e01b8152600401610fd893929190611be4565b6020604051808303816000875af1158015610ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101b9190611c47565b50611024611215565b6002600084815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f380208c9c50307ac517427dc743c51a1f8127fe700cf3d78b26a776412c94e87826110a2611215565b6110aa611215565b73ffffffffffffffffffffffffffffffffffffffff166002600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161460405161111d93929190611c74565b60405180910390a160019050919050565b6000611138610ad2565b15611178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116f9061150c565b60405180910390fd5b61118a8383611185611215565b6102b9565b905092915050565b600061119d826106d3565b6111a657600080fd5b60016002600084815260200190815260200160002060040160146101000a81548160ff0219169083151502179055507f2e9842040508f80e6420769a8673529eb3af5b952f53af83d9c9d3432da78046826040516112049190611318565b60405180910390a160019050919050565b600033905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061124d82611222565b9050919050565b61125d81611242565b811461126857600080fd5b50565b60008135905061127a81611254565b92915050565b6000819050919050565b61129381611280565b811461129e57600080fd5b50565b6000813590506112b08161128a565b92915050565b6000806000606084860312156112cf576112ce61121d565b5b60006112dd8682870161126b565b93505060206112ee868287016112a1565b92505060406112ff8682870161126b565b9150509250925092565b61131281611280565b82525050565b600060208201905061132d6000830184611309565b92915050565b6000602082840312156113495761134861121d565b5b6000611357848285016112a1565b91505092915050565b60008115159050919050565b61137581611360565b82525050565b6000602082019050611390600083018461136c565b92915050565b61139f81611242565b82525050565b60006113b082611222565b9050919050565b6113c0816113a5565b82525050565b600060c0820190506113db6000830189611396565b6113e86020830188611396565b6113f56040830187611309565b61140260608301866113b7565b61140f6080830185611396565b61141c60a083018461136c565b979650505050505050565b600060208201905061143c6000830184611396565b92915050565b6000602082840312156114585761145761121d565b5b60006114668482850161126b565b91505092915050565b600080604083850312156114865761148561121d565b5b60006114948582860161126b565b92505060206114a5858286016112a1565b9150509250929050565b600082825260208201905092915050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006114f66010836114af565b9150611501826114c0565b602082019050919050565b60006020820190508181036000830152611525816114e9565b9050919050565b7f546f6b656e20616d6f756e742068617320746f2062652067726561746564207460008201527f68616e207a65726f000000000000000000000000000000000000000000000000602082015250565b60006115886028836114af565b91506115938261152c565b604082019050919050565b600060208201905081810360008301526115b78161157b565b9050919050565b7f546f6b656e20616464726573732063616e6e6f74206265207a65726f00000000600082015250565b60006115f4601c836114af565b91506115ff826115be565b602082019050919050565b60006020820190508181036000830152611623816115e7565b9050919050565b7f496e766f69636520494420616c72656164792075736564000000000000000000600082015250565b60006116606017836114af565b915061166b8261162a565b602082019050919050565b6000602082019050818103600083015261168f81611653565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006116d082611280565b91506116db83611280565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156117105761170f611696565b5b828201905092915050565b6000819050919050565b600061174061173b61173684611222565b61171b565b611222565b9050919050565b600061175282611725565b9050919050565b600061176482611747565b9050919050565b61177481611759565b82525050565b600060a08201905061178f6000830188611309565b61179c6020830187611396565b6117a96040830186611396565b6117b66060830185611309565b6117c3608083018461176b565b9695505050505050565b7f496e766f6963652049442073686f756c64206265206d6f7265207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006118296023836114af565b9150611834826117cd565b604082019050919050565b600060208201905081810360008301526118588161181c565b9050919050565b7f496e766f69636520616c72656164792063616e63656c6c656400000000000000600082015250565b60006118956019836114af565b91506118a08261185f565b602082019050919050565b600060208201905081810360008301526118c481611888565b9050919050565b7f43616e6e6f742063616e63656c2061207061696420696e766f69636500000000600082015250565b6000611901601c836114af565b915061190c826118cb565b602082019050919050565b60006020820190508181036000830152611930816118f4565b9050919050565b7f496e766f6963652063616e206f6e6c792062652063616e63656c6c656420627960008201527f2063726561746572000000000000000000000000000000000000000000000000602082015250565b60006119936028836114af565b915061199e82611937565b604082019050919050565b600060208201905081810360008301526119c281611986565b9050919050565b60006040820190506119de6000830185611396565b6119eb6020830184611396565b9392505050565b600081519050611a018161128a565b92915050565b600060208284031215611a1d57611a1c61121d565b5b6000611a2b848285016119f2565b91505092915050565b7f546f6b656e20617070726f76616c20616d6f756e74206e6f7420656e6f756768600082015250565b6000611a6a6020836114af565b9150611a7582611a34565b602082019050919050565b60006020820190508181036000830152611a9981611a5d565b9050919050565b7f496e766f696365207061696420616c7265616479000000000000000000000000600082015250565b6000611ad66014836114af565b9150611ae182611aa0565b602082019050919050565b60006020820190508181036000830152611b0581611ac9565b9050919050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b6000611b426013836114af565b9150611b4d82611b0c565b602082019050919050565b60006020820190508181036000830152611b7181611b35565b9050919050565b7f596f752063616e6e6f742070617920666f722074686520696e766f6963650000600082015250565b6000611bae601e836114af565b9150611bb982611b78565b602082019050919050565b60006020820190508181036000830152611bdd81611ba1565b9050919050565b6000606082019050611bf96000830186611396565b611c066020830185611396565b611c136040830184611309565b949350505050565b611c2481611360565b8114611c2f57600080fd5b50565b600081519050611c4181611c1b565b92915050565b600060208284031215611c5d57611c5c61121d565b5b6000611c6b84828501611c32565b91505092915050565b6000606082019050611c896000830186611309565b611c966020830185611396565b611ca3604083018461136c565b94935050505056fea26469706673582212200b85c0460be0be7226aefe0e757d0249faf188b5263968322ba7e2e26016b40a64736f6c634300080f0033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80636ed91d0f116100715780636ed91d0f146101bf578063893d20e8146101ef578063a6f9dae11461020d578063ac60a6cd14610229578063b095853214610259578063da9c273d14610289576100b4565b806308553e36146100b95780630be1177d146100e95780631ad6688b146101075780633a23cc0a146101375780634e6d14051461016c5780635c975abb146101a1575b600080fd5b6100d360048036038101906100ce91906112b6565b6102b9565b6040516100e09190611318565b60405180910390f35b6100f16106c9565b6040516100fe9190611318565b60405180910390f35b610121600480360381019061011c9190611333565b6106d3565b60405161012e919061137b565b60405180910390f35b610151600480360381019061014c9190611333565b6108d4565b604051610163969594939291906113c6565b60405180910390f35b61018660048036038101906101819190611333565b610a09565b604051610198969594939291906113c6565b60405180910390f35b6101a9610ad2565b6040516101b6919061137b565b60405180910390f35b6101d960048036038101906101d49190611333565b610ae8565b6040516101e6919061137b565b60405180910390f35b6101f7610d4f565b6040516102049190611427565b60405180910390f35b61022760048036038101906102229190611442565b610d78565b005b610243600480360381019061023e9190611333565b610ec8565b604051610250919061137b565b60405180910390f35b610273600480360381019061026e919061146f565b61112e565b6040516102809190611318565b60405180910390f35b6102a3600480360381019061029e9190611333565b611192565b6040516102b0919061137b565b60405180910390f35b60006102c3610ad2565b15610303576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102fa9061150c565b60405180910390fd5b60008311610346576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161033d9061159e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036103b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ac9061160a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660026000600154815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461045c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045390611676565b60405180910390fd5b600060015490506001805461047191906116c5565b60018190555061047f611215565b6002600083815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550846002600083815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550836002600083815260200190815260200160002060020181905550826002600083815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006002600083815260200190815260200160002060040160146101000a81548160ff0219169083151502179055507f2ed70a847e04cd32b671efc1fc252578d1013d9d78730ce21971254f514b4bd8816002600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600085815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660026000868152602001908152602001600020600201546002600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516106b695949392919061177a565b60405180910390a1809150509392505050565b6000600154905090565b6000808211610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070e9061183f565b60405180910390fd5b6002600083815260200190815260200160002060040160149054906101000a900460ff161561077b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610772906118ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161081790611917565b60405180910390fd5b610828611215565b73ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146108cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c2906119a9565b60405180910390fd5b60019050919050565b6000806000806000806002600088815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008a815260200190815260200160002060020154600260008b815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008c815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600260008d815260200190815260200160002060040160149054906101000a900460ff1695509550955095509550955091939550919395565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060040160149054906101000a900460ff16905086565b60008060009054906101000a900460ff16905090565b6000808211610b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b239061183f565b60405180910390fd5b60026000838152602001908152602001600020600201546002600084815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e610b9d611215565b306040518363ffffffff1660e01b8152600401610bbb9291906119c9565b602060405180830381865afa158015610bd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bfc9190611a07565b1015610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c3490611a80565b60405180910390fd5b6002600083815260200190815260200160002060040160149054906101000a900460ff1615610ca1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c98906118ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d3d90611aec565b60405180910390fd5b60019050919050565b60008060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dff90611b58565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600060019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a380600060016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000610ed382610ae8565b610f12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0990611bc4565b60405180910390fd5b6002600083815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd610f6c611215565b6002600086815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660026000878152602001908152602001600020600201546040518463ffffffff1660e01b8152600401610fd893929190611be4565b6020604051808303816000875af1158015610ff7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061101b9190611c47565b50611024611215565b6002600084815260200190815260200160002060040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f380208c9c50307ac517427dc743c51a1f8127fe700cf3d78b26a776412c94e87826110a2611215565b6110aa611215565b73ffffffffffffffffffffffffffffffffffffffff166002600087815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161460405161111d93929190611c74565b60405180910390a160019050919050565b6000611138610ad2565b15611178576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116f9061150c565b60405180910390fd5b61118a8383611185611215565b6102b9565b905092915050565b600061119d826106d3565b6111a657600080fd5b60016002600084815260200190815260200160002060040160146101000a81548160ff0219169083151502179055507f2e9842040508f80e6420769a8673529eb3af5b952f53af83d9c9d3432da78046826040516112049190611318565b60405180910390a160019050919050565b600033905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061124d82611222565b9050919050565b61125d81611242565b811461126857600080fd5b50565b60008135905061127a81611254565b92915050565b6000819050919050565b61129381611280565b811461129e57600080fd5b50565b6000813590506112b08161128a565b92915050565b6000806000606084860312156112cf576112ce61121d565b5b60006112dd8682870161126b565b93505060206112ee868287016112a1565b92505060406112ff8682870161126b565b9150509250925092565b61131281611280565b82525050565b600060208201905061132d6000830184611309565b92915050565b6000602082840312156113495761134861121d565b5b6000611357848285016112a1565b91505092915050565b60008115159050919050565b61137581611360565b82525050565b6000602082019050611390600083018461136c565b92915050565b61139f81611242565b82525050565b60006113b082611222565b9050919050565b6113c0816113a5565b82525050565b600060c0820190506113db6000830189611396565b6113e86020830188611396565b6113f56040830187611309565b61140260608301866113b7565b61140f6080830185611396565b61141c60a083018461136c565b979650505050505050565b600060208201905061143c6000830184611396565b92915050565b6000602082840312156114585761145761121d565b5b60006114668482850161126b565b91505092915050565b600080604083850312156114865761148561121d565b5b60006114948582860161126b565b92505060206114a5858286016112a1565b9150509250929050565b600082825260208201905092915050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b60006114f66010836114af565b9150611501826114c0565b602082019050919050565b60006020820190508181036000830152611525816114e9565b9050919050565b7f546f6b656e20616d6f756e742068617320746f2062652067726561746564207460008201527f68616e207a65726f000000000000000000000000000000000000000000000000602082015250565b60006115886028836114af565b91506115938261152c565b604082019050919050565b600060208201905081810360008301526115b78161157b565b9050919050565b7f546f6b656e20616464726573732063616e6e6f74206265207a65726f00000000600082015250565b60006115f4601c836114af565b91506115ff826115be565b602082019050919050565b60006020820190508181036000830152611623816115e7565b9050919050565b7f496e766f69636520494420616c72656164792075736564000000000000000000600082015250565b60006116606017836114af565b915061166b8261162a565b602082019050919050565b6000602082019050818103600083015261168f81611653565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006116d082611280565b91506116db83611280565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156117105761170f611696565b5b828201905092915050565b6000819050919050565b600061174061173b61173684611222565b61171b565b611222565b9050919050565b600061175282611725565b9050919050565b600061176482611747565b9050919050565b61177481611759565b82525050565b600060a08201905061178f6000830188611309565b61179c6020830187611396565b6117a96040830186611396565b6117b66060830185611309565b6117c3608083018461176b565b9695505050505050565b7f496e766f6963652049442073686f756c64206265206d6f7265207468616e207a60008201527f65726f0000000000000000000000000000000000000000000000000000000000602082015250565b60006118296023836114af565b9150611834826117cd565b604082019050919050565b600060208201905081810360008301526118588161181c565b9050919050565b7f496e766f69636520616c72656164792063616e63656c6c656400000000000000600082015250565b60006118956019836114af565b91506118a08261185f565b602082019050919050565b600060208201905081810360008301526118c481611888565b9050919050565b7f43616e6e6f742063616e63656c2061207061696420696e766f69636500000000600082015250565b6000611901601c836114af565b915061190c826118cb565b602082019050919050565b60006020820190508181036000830152611930816118f4565b9050919050565b7f496e766f6963652063616e206f6e6c792062652063616e63656c6c656420627960008201527f2063726561746572000000000000000000000000000000000000000000000000602082015250565b60006119936028836114af565b915061199e82611937565b604082019050919050565b600060208201905081810360008301526119c281611986565b9050919050565b60006040820190506119de6000830185611396565b6119eb6020830184611396565b9392505050565b600081519050611a018161128a565b92915050565b600060208284031215611a1d57611a1c61121d565b5b6000611a2b848285016119f2565b91505092915050565b7f546f6b656e20617070726f76616c20616d6f756e74206e6f7420656e6f756768600082015250565b6000611a6a6020836114af565b9150611a7582611a34565b602082019050919050565b60006020820190508181036000830152611a9981611a5d565b9050919050565b7f496e766f696365207061696420616c7265616479000000000000000000000000600082015250565b6000611ad66014836114af565b9150611ae182611aa0565b602082019050919050565b60006020820190508181036000830152611b0581611ac9565b9050919050565b7f43616c6c6572206973206e6f74206f776e657200000000000000000000000000600082015250565b6000611b426013836114af565b9150611b4d82611b0c565b602082019050919050565b60006020820190508181036000830152611b7181611b35565b9050919050565b7f596f752063616e6e6f742070617920666f722074686520696e766f6963650000600082015250565b6000611bae601e836114af565b9150611bb982611b78565b602082019050919050565b60006020820190508181036000830152611bdd81611ba1565b9050919050565b6000606082019050611bf96000830186611396565b611c066020830185611396565b611c136040830184611309565b949350505050565b611c2481611360565b8114611c2f57600080fd5b50565b600081519050611c4181611c1b565b92915050565b600060208284031215611c5d57611c5c61121d565b5b6000611c6b84828501611c32565b91505092915050565b6000606082019050611c896000830186611309565b611c966020830185611396565b611ca3604083018461136c565b94935050505056fea26469706673582212200b85c0460be0be7226aefe0e757d0249faf188b5263968322ba7e2e26016b40a64736f6c634300080f0033