Contract Address Details

0x53389BFFA22e77E015D60cf2300967A7dd43BDb8

Token
Wrapped WIRE (WWIRE)
Creator
0x2b7837–5651e9 at 0x35937d–7dee14
Balance
6,163,436.787499999999999999 Wire
Tokens
Fetching tokens...
Transactions
48,217 Transactions
Transfers
0 Transfers
Gas Used
2,129,855,375
Last Balance Update
33484877
Contract name:
WWIRE




Optimization enabled
false
Compiler version
v0.8.9+commit.e5eed63a




EVM Version
default




Verified at
2023-01-21T23:13:16.602426Z

contracts/WWIRE.sol

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2015, 2016, 2017 Dapphub
// Adapted by Ethereum Community 2021
pragma solidity 0.8.9;

import "./interfaces/IWETH10.sol";
import "./interfaces/IERC3156FlashBorrower.sol";

interface ITransferReceiver {
    function onTokenTransfer(address, uint, bytes calldata) external returns (bool);
}

interface IApprovalReceiver {
    function onTokenApproval(address, uint, bytes calldata) external returns (bool);
}

/// @dev Wrapped Ether v10 (WWIRE10) is an Ether (ETH) ERC-20 wrapper. You can `deposit` ETH and obtain a WWIRE10 balance which can then be operated as an ERC-20 token. You can
/// `withdraw` ETH from WWIRE10, which will then burn WWIRE10 token in your wallet. The amount of WWIRE10 token in any wallet is always identical to the
/// balance of ETH deposited minus the ETH withdrawn with that specific wallet.
contract WWIRE is IWETH10 {

    string public constant name = "Wrapped WIRE";
    string public constant symbol = "WWIRE";
    uint8  public constant decimals = 18;

    bytes32 public immutable CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan");
    bytes32 public immutable PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    uint256 public immutable deploymentChainId;
    bytes32 private immutable _DOMAIN_SEPARATOR;

    /// @dev Records amount of WWIRE10 token owned by account.
    mapping (address => uint256) public override balanceOf;

    /// @dev Records current ERC2612 nonce for account. This value must be included whenever signature is generated for {permit}.
    /// Every successful call to {permit} increases account's nonce by one. This prevents signature from being used multiple times.
    mapping (address => uint256) public override nonces;

    /// @dev Records number of WWIRE10 token that account (second) will be allowed to spend on behalf of another account (first) through {transferFrom}.
    mapping (address => mapping (address => uint256)) public override allowance;

    /// @dev Current amount of flash-minted WWIRE10 token.
    uint256 public override flashMinted;

    constructor() {
        uint256 chainId;
        assembly {chainId := chainid()}
        deploymentChainId = chainId;
        _DOMAIN_SEPARATOR = _calculateDomainSeparator(chainId);
    }

    /// @dev Calculate the DOMAIN_SEPARATOR.
    function _calculateDomainSeparator(uint256 chainId) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes(name)),
                keccak256(bytes("1")),
                chainId,
                address(this)
            )
        );
    }

    /// @dev Return the DOMAIN_SEPARATOR.
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        uint256 chainId;
        assembly {chainId := chainid()}
        return chainId == deploymentChainId ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(chainId);
    }

    /// @dev Returns the total supply of WWIRE10 token as the ETH held in this contract.
    function totalSupply() external view override returns (uint256) {
        return address(this).balance + flashMinted;
    }

    /// @dev Fallback, `msg.value` of ETH sent to this contract grants caller account a matching increase in WWIRE10 token balance.
    /// Emits {Transfer} event to reflect WWIRE10 token mint of `msg.value` from `address(0)` to caller account.
    receive() external payable {
        // _mintTo(msg.sender, msg.value);
        balanceOf[msg.sender] += msg.value;
        emit Transfer(address(0), msg.sender, msg.value);
    }

    /// @dev `msg.value` of ETH sent to this contract grants caller account a matching increase in WWIRE10 token balance.
    /// Emits {Transfer} event to reflect WWIRE10 token mint of `msg.value` from `address(0)` to caller account.
    function deposit() external override payable {
        // _mintTo(msg.sender, msg.value);
        balanceOf[msg.sender] += msg.value;
        emit Transfer(address(0), msg.sender, msg.value);
    }

    /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WWIRE10 token balance.
    /// Emits {Transfer} event to reflect WWIRE10 token mint of `msg.value` from `address(0)` to `to` account.
    function depositTo(address to) external override payable {
        // _mintTo(to, msg.value);
        balanceOf[to] += msg.value;
        emit Transfer(address(0), to, msg.value);
    }

    /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WWIRE10 token balance,
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// For more information on {transferAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function depositToAndCall(address to, bytes calldata data) external override payable returns (bool success) {
        // _mintTo(to, msg.value);
        balanceOf[to] += msg.value;
        emit Transfer(address(0), to, msg.value);

        return ITransferReceiver(to).onTokenTransfer(msg.sender, msg.value, data);
    }

    /// @dev Return the amount of WWIRE10 token that can be flash-lent.
    function maxFlashLoan(address token) external view override returns (uint256) {
        return token == address(this) ? type(uint112).max - flashMinted : 0; // Can't underflow
    }

    /// @dev Return the fee (zero) for flash lending an amount of WWIRE10 token.
    function flashFee(address token, uint256) external view override returns (uint256) {
        require(token == address(this), "WWIRE: flash mint only WWIRE10");
        return 0;
    }

    /// @dev Flash lends `value` WWIRE10 token to the receiver address.
    /// By the end of the transaction, `value` WWIRE10 token will be burned from the receiver.
    /// The flash-minted WWIRE10 token is not backed by real ETH, but can be withdrawn as such up to the ETH balance of this contract.
    /// Arbitrary data can be passed as a bytes calldata parameter.
    /// Emits {Approval} event to reflect reduced allowance `value` for this contract to spend from receiver account (`receiver`),
    /// unless allowance is set to `type(uint256).max`
    /// Emits two {Transfer} events for minting and burning of the flash-minted amount.
    /// Returns boolean value indicating whether operation succeeded.
    /// Requirements:
    ///   - `value` must be less or equal to type(uint112).max.
    ///   - The total of all flash loans in a tx must be less or equal to type(uint112).max.
    function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 value, bytes calldata data) external override returns (bool) {
        require(token == address(this), "WWIRE: flash mint only WWIRE10");
        require(value <= type(uint112).max, "WWIRE: individual loan limit exceeded");
        flashMinted = flashMinted + value;
        require(flashMinted <= type(uint112).max, "WWIRE: total loan limit exceeded");

        // _mintTo(address(receiver), value);
        balanceOf[address(receiver)] += value;
        emit Transfer(address(0), address(receiver), value);

        require(
            receiver.onFlashLoan(msg.sender, address(this), value, 0, data) == CALLBACK_SUCCESS,
            "WWIRE: flash loan failed"
        );

        // _decreaseAllowance(address(receiver), address(this), value);
        uint256 allowed = allowance[address(receiver)][address(this)];
        if (allowed != type(uint256).max) {
            require(allowed >= value, "WWIRE: request exceeds allowance");
            uint256 reduced = allowed - value;
            allowance[address(receiver)][address(this)] = reduced;
            emit Approval(address(receiver), address(this), reduced);
        }

        // _burnFrom(address(receiver), value);
        uint256 balance = balanceOf[address(receiver)];
        require(balance >= value, "WWIRE: burn amount exceeds balance");
        balanceOf[address(receiver)] = balance - value;
        emit Transfer(address(receiver), address(0), value);

        flashMinted = flashMinted - value;
        return true;
    }

    /// @dev Burn `value` WWIRE10 token from caller account and withdraw matching ETH to the same.
    /// Emits {Transfer} event to reflect WWIRE10 token burn of `value` to `address(0)` from caller account.
    /// Requirements:
    ///   - caller account must have at least `value` balance of WWIRE10 token.
    function withdraw(uint256 value) external override {
        // _burnFrom(msg.sender, value);
        uint256 balance = balanceOf[msg.sender];
        require(balance >= value, "WWIRE: burn amount exceeds balance");
        balanceOf[msg.sender] = balance - value;
        emit Transfer(msg.sender, address(0), value);

        // _transferEther(msg.sender, value);
        (bool success, ) = msg.sender.call{value: value}("");
        require(success, "WWIRE: ETH transfer failed");
    }

    /// @dev Burn `value` WWIRE10 token from caller account and withdraw matching ETH to account (`to`).
    /// Emits {Transfer} event to reflect WWIRE10 token burn of `value` to `address(0)` from caller account.
    /// Requirements:
    ///   - caller account must have at least `value` balance of WWIRE10 token.
    function withdrawTo(address payable to, uint256 value) external override {
        // _burnFrom(msg.sender, value);
        uint256 balance = balanceOf[msg.sender];
        require(balance >= value, "WWIRE: burn amount exceeds balance");
        balanceOf[msg.sender] = balance - value;
        emit Transfer(msg.sender, address(0), value);

        // _transferEther(to, value);
        (bool success, ) = to.call{value: value}("");
        require(success, "WWIRE: ETH transfer failed");
    }

    /// @dev Burn `value` WWIRE10 token from account (`from`) and withdraw matching ETH to account (`to`).
    /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`),
    /// unless allowance is set to `type(uint256).max`
    /// Emits {Transfer} event to reflect WWIRE10 token burn of `value` to `address(0)` from account (`from`).
    /// Requirements:
    ///   - `from` account must have at least `value` balance of WWIRE10 token.
    ///   - `from` account must have approved caller to spend at least `value` of WWIRE10 token, unless `from` and caller are the same account.
    function withdrawFrom(address from, address payable to, uint256 value) external override {
        if (from != msg.sender) {
            // _decreaseAllowance(from, msg.sender, value);
            uint256 allowed = allowance[from][msg.sender];
            if (allowed != type(uint256).max) {
                require(allowed >= value, "WWIRE: request exceeds allowance");
                uint256 reduced = allowed - value;
                allowance[from][msg.sender] = reduced;
                emit Approval(from, msg.sender, reduced);
            }
        }

        // _burnFrom(from, value);
        uint256 balance = balanceOf[from];
        require(balance >= value, "WWIRE: burn amount exceeds balance");
        balanceOf[from] = balance - value;
        emit Transfer(from, address(0), value);

        // _transferEther(to, value);
        (bool success, ) = to.call{value: value}("");
        require(success, "WWIRE: Ether transfer failed");
    }

    /// @dev Sets `value` as allowance of `spender` account over caller account's WWIRE10 token.
    /// Emits {Approval} event.
    /// Returns boolean value indicating whether operation succeeded.
    function approve(address spender, uint256 value) external override returns (bool) {
        // _approve(msg.sender, spender, value);
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);

        return true;
    }

    /// @dev Sets `value` as allowance of `spender` account over caller account's WWIRE10 token,
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// Emits {Approval} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// For more information on {approveAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function approveAndCall(address spender, uint256 value, bytes calldata data) external override returns (bool) {
        // _approve(msg.sender, spender, value);
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);

        return IApprovalReceiver(spender).onTokenApproval(msg.sender, value, data);
    }

    /// @dev Sets `value` as allowance of `spender` account over `owner` account's WWIRE10 token, given `owner` account's signed approval.
    /// Emits {Approval} event.
    /// Requirements:
    ///   - `deadline` must be timestamp in future.
    ///   - `v`, `r` and `s` must be valid `secp256k1` signature from `owner` account over EIP712-formatted function arguments.
    ///   - the signature must use `owner` account's current nonce (see {nonces}).
    ///   - the signer cannot be `address(0)` and must be `owner` account.
    /// For more information on signature format, see https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section].
    /// WWIRE10 token implementation adapted from https://github.com/albertocuestacanada/ERC20Permit/blob/master/contracts/ERC20Permit.sol.
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external override {
        require(block.timestamp <= deadline, "WWIRE: Expired permit");

        uint256 chainId;
        assembly {chainId := chainid()}

        bytes32 hashStruct = keccak256(
            abi.encode(
                PERMIT_TYPEHASH,
                owner,
                spender,
                value,
                nonces[owner]++,
                deadline));

        bytes32 hash = keccak256(
            abi.encodePacked(
                "\x19\x01",
                chainId == deploymentChainId ? _DOMAIN_SEPARATOR : _calculateDomainSeparator(chainId),
                hashStruct));

        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0) && signer == owner, "WWIRE: invalid permit");

        // _approve(owner, spender, value);
        allowance[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /// @dev Moves `value` WWIRE10 token from caller's account to account (`to`).
    /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WWIRE10 token in favor of caller.
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// Requirements:
    ///   - caller account must have at least `value` WWIRE10 token.
    function transfer(address to, uint256 value) external override returns (bool) {
        // _transferFrom(msg.sender, to, value);
        if (to != address(0) && to != address(this)) { // Transfer
            uint256 balance = balanceOf[msg.sender];
            require(balance >= value, "WWIRE: transfer amount exceeds balance");

            balanceOf[msg.sender] = balance - value;
            balanceOf[to] += value;
            emit Transfer(msg.sender, to, value);
        } else { // Withdraw
            uint256 balance = balanceOf[msg.sender];
            require(balance >= value, "WWIRE: burn amount exceeds balance");
            balanceOf[msg.sender] = balance - value;
            emit Transfer(msg.sender, address(0), value);

            (bool success, ) = msg.sender.call{value: value}("");
            require(success, "WWIRE: ETH transfer failed");
        }

        return true;
    }

    /// @dev Moves `value` WWIRE10 token from account (`from`) to account (`to`) using allowance mechanism.
    /// `value` is then deducted from caller account's allowance, unless set to `type(uint256).max`.
    /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WWIRE10 token in favor of caller.
    /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`),
    /// unless allowance is set to `type(uint256).max`
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// Requirements:
    ///   - `from` account must have at least `value` balance of WWIRE10 token.
    ///   - `from` account must have approved caller to spend at least `value` of WWIRE10 token, unless `from` and caller are the same account.
    function transferFrom(address from, address to, uint256 value) external override returns (bool) {
        if (from != msg.sender) {
            // _decreaseAllowance(from, msg.sender, value);
            uint256 allowed = allowance[from][msg.sender];
            if (allowed != type(uint256).max) {
                require(allowed >= value, "WWIRE: request exceeds allowance");
                uint256 reduced = allowed - value;
                allowance[from][msg.sender] = reduced;
                emit Approval(from, msg.sender, reduced);
            }
        }

        // _transferFrom(from, to, value);
        if (to != address(0) && to != address(this)) { // Transfer
            uint256 balance = balanceOf[from];
            require(balance >= value, "WWIRE: transfer amount exceeds balance");

            balanceOf[from] = balance - value;
            balanceOf[to] += value;
            emit Transfer(from, to, value);
        } else { // Withdraw
            uint256 balance = balanceOf[from];
            require(balance >= value, "WWIRE: burn amount exceeds balance");
            balanceOf[from] = balance - value;
            emit Transfer(from, address(0), value);

            (bool success, ) = msg.sender.call{value: value}("");
            require(success, "WWIRE: ETH transfer failed");
        }

        return true;
    }

    /// @dev Moves `value` WWIRE10 token from caller's account to account (`to`),
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WWIRE10 token in favor of caller.
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// Requirements:
    ///   - caller account must have at least `value` WWIRE10 token.
    /// For more information on {transferAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function transferAndCall(address to, uint value, bytes calldata data) external override returns (bool) {
        // _transferFrom(msg.sender, to, value);
        if (to != address(0)) { // Transfer
            uint256 balance = balanceOf[msg.sender];
            require(balance >= value, "WWIRE: transfer amount exceeds balance");

            balanceOf[msg.sender] = balance - value;
            balanceOf[to] += value;
            emit Transfer(msg.sender, to, value);
        } else { // Withdraw
            uint256 balance = balanceOf[msg.sender];
            require(balance >= value, "WWIRE: burn amount exceeds balance");
            balanceOf[msg.sender] = balance - value;
            emit Transfer(msg.sender, address(0), value);

            (bool success, ) = msg.sender.call{value: value}("");
            require(success, "WWIRE: ETH transfer failed");
        }

        return ITransferReceiver(to).onTokenTransfer(msg.sender, value, data);
    }
}
        

contracts/interfaces/IERC20.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <=0.8.9;

/**
 * @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);
}
          

contracts/interfaces/IERC2612.sol

// SPDX-License-Identifier: GPL-3.0-or-later
// Code adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/pull/2237/
pragma solidity >=0.6.0 <=0.8.9;

/**
 * @dev Interface of the ERC2612 standard as defined in the EIP.
 *
 * Adds the {permit} method, which can be used to change one's
 * {IERC20-allowance} without having to send a transaction, by signing a
 * message. This allows users to spend tokens without having to hold Ether.
 *
 * See https://eips.ethereum.org/EIPS/eip-2612.
 */
interface IERC2612 {
    /**
     * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens,
     * given `owner`'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be `address(0)`.
     * - `spender` cannot be `address(0)`.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use `owner`'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;

    /**
     * @dev Returns the current ERC2612 nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases `owner`'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);
    
    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by EIP712.
     */
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
          

contracts/interfaces/IERC3156FlashBorrower.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <=0.8.9;


interface IERC3156FlashBorrower {

    /**
     * @dev Receive a flash loan.
     * @param initiator The initiator of the loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param fee The additional amount of tokens to repay.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     * @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
     */
    function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32);
}
          

contracts/interfaces/IERC3156FlashLender.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <=0.8.9;
import "./IERC3156FlashBorrower.sol";


interface IERC3156FlashLender {

    /**
     * @dev The amount of currency available to be lended.
     * @param token The loan currency.
     * @return The amount of `token` that can be borrowed.
     */
    function maxFlashLoan(
        address token
    ) external view returns (uint256);

    /**
     * @dev The fee to be charged for a given loan.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @return The amount of `token` to be charged for the loan, on top of the returned principal.
     */
    function flashFee(
        address token,
        uint256 amount
    ) external view returns (uint256);

    /**
     * @dev Initiate a flash loan.
     * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
     * @param token The loan currency.
     * @param amount The amount of tokens lent.
     * @param data Arbitrary data structure, intended to contain user-defined parameters.
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}
          

contracts/interfaces/IWETH10.sol

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2015, 2016, 2017 Dapphub
// Adapted by Ethereum Community 2021
pragma solidity >=0.6.0 <=0.8.9;

import "./IERC20.sol";
import "./IERC2612.sol";
import "./IERC3156FlashLender.sol";

/// @dev Wrapped Ether v10 (WETH10) is an Ether (ETH) ERC-20 wrapper. You can `deposit` ETH and obtain a WETH10 balance which can then be operated as an ERC-20 token. You can
/// `withdraw` ETH from WETH10, which will then burn WETH10 token in your wallet. The amount of WETH10 token in any wallet is always identical to the
/// balance of ETH deposited minus the ETH withdrawn with that specific wallet.
interface IWETH10 is IERC20, IERC2612, IERC3156FlashLender {

    /// @dev Returns current amount of flash-minted WETH10 token.
    function flashMinted() external view returns(uint256);

    /// @dev `msg.value` of ETH sent to this contract grants caller account a matching increase in WETH10 token balance.
    /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from `address(0)` to caller account.
    function deposit() external payable;

    /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance.
    /// Emits {Transfer} event to reflect WETH10 token mint of `msg.value` from `address(0)` to `to` account.
    function depositTo(address to) external payable;

    /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to the same.
    /// Emits {Transfer} event to reflect WETH10 token burn of `value` to `address(0)` from caller account. 
    /// Requirements:
    ///   - caller account must have at least `value` balance of WETH10 token.
    function withdraw(uint256 value) external;

    /// @dev Burn `value` WETH10 token from caller account and withdraw matching ETH to account (`to`).
    /// Emits {Transfer} event to reflect WETH10 token burn of `value` to `address(0)` from caller account.
    /// Requirements:
    ///   - caller account must have at least `value` balance of WETH10 token.
    function withdrawTo(address payable to, uint256 value) external;

    /// @dev Burn `value` WETH10 token from account (`from`) and withdraw matching ETH to account (`to`).
    /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`),
    /// unless allowance is set to `type(uint256).max`
    /// Emits {Transfer} event to reflect WETH10 token burn of `value` to `address(0)` from account (`from`).
    /// Requirements:
    ///   - `from` account must have at least `value` balance of WETH10 token.
    ///   - `from` account must have approved caller to spend at least `value` of WETH10 token, unless `from` and caller are the same account.
    function withdrawFrom(address from, address payable to, uint256 value) external;

    /// @dev `msg.value` of ETH sent to this contract grants `to` account a matching increase in WETH10 token balance,
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// For more information on {transferAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function depositToAndCall(address to, bytes calldata data) external payable returns (bool);

    /// @dev Sets `value` as allowance of `spender` account over caller account's WETH10 token,
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// Emits {Approval} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// For more information on {approveAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);

    /// @dev Moves `value` WETH10 token from caller's account to account (`to`), 
    /// after which a call is executed to an ERC677-compliant contract with the `data` parameter.
    /// A transfer to `address(0)` triggers an ETH withdraw matching the sent WETH10 token in favor of caller.
    /// Emits {Transfer} event.
    /// Returns boolean value indicating whether operation succeeded.
    /// Requirements:
    ///   - caller account must have at least `value` WETH10 token.
    /// For more information on {transferAndCall} format, see https://github.com/ethereum/EIPs/issues/677.
    function transferAndCall(address to, uint value, bytes calldata data) external returns (bool);
}
          

Contract ABI

[{"type":"constructor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"CALLBACK_SUCCESS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DOMAIN_SEPARATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"PERMIT_TYPEHASH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approveAndCall","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"deploymentChainId","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"depositTo","inputs":[{"type":"address","name":"to","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"depositToAndCall","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"flashFee","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"flashLoan","inputs":[{"type":"address","name":"receiver","internalType":"contract IERC3156FlashBorrower"},{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"flashMinted","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxFlashLoan","inputs":[{"type":"address","name":"token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"permit","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferAndCall","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFrom","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address payable"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawTo","inputs":[{"type":"address","name":"to","internalType":"address payable"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","indexed":true},{"type":"address","name":"spender","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","indexed":true},{"type":"address","name":"to","indexed":true},{"type":"uint256","name":"value","indexed":false}],"anonymous":false},{"type":"receive"}]
            

Contract Creation Code

0x6101006040527f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd96080908152507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c960a0908152503480156200006057600080fd5b5060004690508060c081815250506200007f816200008d60201b60201c565b60e081815250505062000237565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6040518060400160405280600c81526020017f5772617070656420574952450000000000000000000000000000000000000000815250805190602001206040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525080519060200120843060405160200162000142959493929190620001da565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b62000174816200015f565b82525050565b6000819050919050565b6200018f816200017a565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620001c28262000195565b9050919050565b620001d481620001b5565b82525050565b600060a082019050620001f1600083018862000169565b62000200602083018762000169565b6200020f604083018662000169565b6200021e606083018562000184565b6200022d6080830184620001c9565b9695505050505050565b60805160a05160c05160e05161410762000294600039600081816113100152612c320152600081816112db01528181612a2a0152612bfd0152600081816112ac0152612b5501526000818161196c0152611f8c01526141076000f3fe6080604052600436106101a05760003560e01c806370a08231116100ec578063b760faf91161008a578063d0e30db011610064578063d0e30db0146106d6578063d505accf146106e0578063d9d98ce414610709578063dd62ed3e1461074657610262565b8063b760faf914610652578063cae9ca511461066e578063cd0d0096146106ab57610262565b80638b28d32f116100c65780638b28d32f146105965780639555a942146105c157806395d89b41146105ea578063a9059cbb1461061557610262565b806370a08231146104f15780637ecebe001461052e5780638237e5381461056b57610262565b806330adf81f116101595780634000aea0116101335780634000aea01461040a5780635cffe9de146104475780635ddb7d7e14610484578063613255ab146104b457610262565b806330adf81f14610389578063313ce567146103b45780633644e515146103df57610262565b806306fdde0314610267578063095ea7b31461029257806318160ddd146102cf578063205c2878146102fa57806323b872dd146103235780632e1a7d4d1461036057610262565b3661026257346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101f39190613011565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef346040516102589190613076565b60405180910390a3005b600080fd5b34801561027357600080fd5b5061027c610783565b604051610289919061312a565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b491906131e0565b6107bc565b6040516102c6919061323b565b60405180910390f35b3480156102db57600080fd5b506102e46108ae565b6040516102f19190613076565b60405180910390f35b34801561030657600080fd5b50610321600480360381019061031c9190613294565b6108c3565b005b34801561032f57600080fd5b5061034a600480360381019061034591906132d4565b610aaf565b604051610357919061323b565b60405180910390f35b34801561036c57600080fd5b5061038760048036038101906103829190613327565b6110bf565b005b34801561039557600080fd5b5061039e6112aa565b6040516103ab919061336d565b60405180910390f35b3480156103c057600080fd5b506103c96112ce565b6040516103d691906133a4565b60405180910390f35b3480156103eb57600080fd5b506103f46112d3565b604051610401919061336d565b60405180910390f35b34801561041657600080fd5b50610431600480360381019061042c9190613424565b611336565b60405161043e919061323b565b60405180910390f35b34801561045357600080fd5b5061046e600480360381019061046991906134d6565b611783565b60405161047b919061323b565b60405180910390f35b61049e6004803603810190610499919061355e565b611da1565b6040516104ab919061323b565b60405180910390f35b3480156104c057600080fd5b506104db60048036038101906104d691906135be565b611ef8565b6040516104e89190613076565b60405180910390f35b3480156104fd57600080fd5b50610518600480360381019061051391906135be565b611f5a565b6040516105259190613076565b60405180910390f35b34801561053a57600080fd5b50610555600480360381019061055091906135be565b611f72565b6040516105629190613076565b60405180910390f35b34801561057757600080fd5b50610580611f8a565b60405161058d919061336d565b60405180910390f35b3480156105a257600080fd5b506105ab611fae565b6040516105b89190613076565b60405180910390f35b3480156105cd57600080fd5b506105e860048036038101906105e391906135eb565b611fb4565b005b3480156105f657600080fd5b506105ff6123b9565b60405161060c919061312a565b60405180910390f35b34801561062157600080fd5b5061063c600480360381019061063791906131e0565b6123f2565b604051610649919061323b565b60405180910390f35b61066c600480360381019061066791906135be565b6127e8565b005b34801561067a57600080fd5b5061069560048036038101906106909190613424565b6128a6565b6040516106a2919061323b565b60405180910390f35b3480156106b757600080fd5b506106c0612a28565b6040516106cd9190613076565b60405180910390f35b6106de612a4c565b005b3480156106ec57600080fd5b5061070760048036038101906107029190613696565b612b09565b005b34801561071557600080fd5b50610730600480360381019061072b91906131e0565b612e69565b60405161073d9190613076565b60405180910390f35b34801561075257600080fd5b5061076d60048036038101906107689190613738565b612ee3565b60405161077a9190613076565b60405180910390f35b6040518060400160405280600c81526020017f577261707065642057495245000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161089c9190613076565b60405180910390a36001905092915050565b6000600354476108be9190613011565b905090565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610949576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610940906137ea565b60405180910390fd5b8181610955919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109f59190613076565b60405180910390a360008373ffffffffffffffffffffffffffffffffffffffff1683604051610a239061386f565b60006040518083038185875af1925050503d8060008114610a60576040519150601f19603f3d011682016040523d82523d6000602084013e610a65565b606091505b5050905080610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa0906138d0565b60405180910390fd5b50505050565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610cc9576000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cc75782811015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc69061393c565b60405180910390fd5b60008382610bdd919061380a565b905080600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610cbd9190613076565b60405180910390a3505b505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610d3257503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b15610ecb5760008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db4906139ce565b60405180910390fd5b8281610dc9919061380a565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610e599190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ebd9190613076565b60405180910390a3506110b4565b60008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906137ea565b60405180910390fd5b8281610f5d919061380a565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffd9190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168460405161102b9061386f565b60006040518083038185875af1925050503d8060008114611068576040519150601f19603f3d011682016040523d82523d6000602084013e61106d565b606091505b50509050806110b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a8906138d0565b60405180910390fd5b50505b600190509392505050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113c906137ea565b60405180910390fd5b8181611151919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111f19190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168360405161121f9061386f565b60006040518083038185875af1925050503d806000811461125c576040519150601f19603f3d011682016040523d82523d6000602084013e611261565b606091505b50509050806112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c906138d0565b60405180910390fd5b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b601281565b6000804690507f0000000000000000000000000000000000000000000000000000000000000000811461130e5761130981612f08565b611330565b7f00000000000000000000000000000000000000000000000000000000000000005b91505090565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146114ff5760008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050848110156113f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e8906139ce565b60405180910390fd5b84816113fd919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461148d9190613011565b925050819055508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516114f19190613076565b60405180910390a3506116e8565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611585576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157c906137ea565b60405180910390fd5b8481611591919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516116319190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168660405161165f9061386f565b60006040518083038185875af1925050503d806000811461169c576040519150601f19603f3d011682016040523d82523d6000602084013e6116a1565b606091505b50509050806116e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dc906138d0565b60405180910390fd5b50505b8473ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36338686866040518563ffffffff1660e01b81526004016117279493929190613a4a565b602060405180830381600087803b15801561174157600080fd5b505af1158015611755573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117799190613ab6565b9050949350505050565b60003073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146117f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ea90613b2f565b60405180910390fd5b6dffffffffffffffffffffffffffff8016841115611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90613bc1565b60405180910390fd5b836003546118549190613011565b6003819055506dffffffffffffffffffffffffffff801660035411156118af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a690613c2d565b60405180910390fd5b836000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118fd9190613011565b925050819055508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040516119629190613076565b60405180910390a37f00000000000000000000000000000000000000000000000000000000000000008673ffffffffffffffffffffffffffffffffffffffff166323e30c8b333088600089896040518763ffffffff1660e01b81526004016119cf96959493929190613c92565b602060405180830381600087803b1580156119e957600080fd5b505af11580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613d03565b14611a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5890613d7c565b60405180910390fd5b6000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c445784811015611b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b439061393c565b60405180910390fd5b60008582611b5a919061380a565b905080600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611c3a9190613076565b60405180910390a3505b60008060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611cca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc1906137ea565b60405180910390fd5b8581611cd6919061380a565b6000808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611d769190613076565b60405180910390a385600354611d8c919061380a565b60038190555060019250505095945050505050565b6000346000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611df19190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef34604051611e569190613076565b60405180910390a38373ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36333486866040518563ffffffff1660e01b8152600401611e9d9493929190613a4a565b602060405180830381600087803b158015611eb757600080fd5b505af1158015611ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eef9190613ab6565b90509392505050565b60003073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611f34576000611f53565b6003546dffffffffffffffffffffffffffff8016611f52919061380a565b5b9050919050565b60006020528060005260406000206000915090505481565b60016020528060005260406000206000915090505481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60035481565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146121cc576000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146121ca57818110156120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c99061393c565b60405180910390fd5b600082826120e0919061380a565b905080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121c09190613076565b60405180910390a3505b505b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612252576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612249906137ea565b60405180910390fd5b818161225e919061380a565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516122fe9190613076565b60405180910390a360008373ffffffffffffffffffffffffffffffffffffffff168360405161232c9061386f565b60006040518083038185875af1925050503d8060008114612369576040519150601f19603f3d011682016040523d82523d6000602084013e61236e565b606091505b50509050806123b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a990613de8565b60405180910390fd5b5050505050565b6040518060400160405280600581526020017f575749524500000000000000000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561245c57503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b156125f55760008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de906139ce565b60405180910390fd5b82816124f3919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125839190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516125e79190613076565b60405180910390a3506127de565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508281101561267b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612672906137ea565b60405180910390fd5b8281612687919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516127279190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff16846040516127559061386f565b60006040518083038185875af1925050503d8060008114612792576040519150601f19603f3d011682016040523d82523d6000602084013e612797565b606091505b50509050806127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d2906138d0565b60405180910390fd5b50505b6001905092915050565b346000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128369190613011565b925050819055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3460405161289b9190613076565b60405180910390a350565b600083600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866040516129869190613076565b60405180910390a38473ffffffffffffffffffffffffffffffffffffffff1662ba451f338686866040518563ffffffff1660e01b81526004016129cc9493929190613a4a565b602060405180830381600087803b1580156129e657600080fd5b505af11580156129fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1e9190613ab6565b9050949350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a9a9190613011565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef34604051612aff9190613076565b60405180910390a3565b83421115612b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4390613e54565b60405180910390fd5b600046905060007f0000000000000000000000000000000000000000000000000000000000000000898989600160008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190612bc790613e74565b919050558a604051602001612be196959493929190613ebd565b60405160208183030381529060405280519060200120905060007f00000000000000000000000000000000000000000000000000000000000000008314612c3057612c2b83612f08565b612c52565b7f00000000000000000000000000000000000000000000000000000000000000005b82604051602001612c64929190613f96565b604051602081830303815290604052805190602001209050600060018288888860405160008152602001604052604051612ca19493929190613fcd565b6020604051602081039080840390855afa158015612cc3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612d3757508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b612d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6d9061405e565b60405180910390fd5b88600260008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258b604051612e549190613076565b60405180910390a35050505050505050505050565b60003073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612ed9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ed090613b2f565b60405180910390fd5b6000905092915050565b6002602052816000526040600020602052806000526040600020600091509150505481565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6040518060400160405280600c81526020017f5772617070656420574952450000000000000000000000000000000000000000815250805190602001206040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250805190602001208430604051602001612fbb95949392919061407e565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061301c82612fd8565b915061302783612fd8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561305c5761305b612fe2565b5b828201905092915050565b61307081612fd8565b82525050565b600060208201905061308b6000830184613067565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156130cb5780820151818401526020810190506130b0565b838111156130da576000848401525b50505050565b6000601f19601f8301169050919050565b60006130fc82613091565b613106818561309c565b93506131168185602086016130ad565b61311f816130e0565b840191505092915050565b6000602082019050818103600083015261314481846130f1565b905092915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318182613156565b9050919050565b61319181613176565b811461319c57600080fd5b50565b6000813590506131ae81613188565b92915050565b6131bd81612fd8565b81146131c857600080fd5b50565b6000813590506131da816131b4565b92915050565b600080604083850312156131f7576131f661314c565b5b60006132058582860161319f565b9250506020613216858286016131cb565b9150509250929050565b60008115159050919050565b61323581613220565b82525050565b6000602082019050613250600083018461322c565b92915050565b600061326182613156565b9050919050565b61327181613256565b811461327c57600080fd5b50565b60008135905061328e81613268565b92915050565b600080604083850312156132ab576132aa61314c565b5b60006132b98582860161327f565b92505060206132ca858286016131cb565b9150509250929050565b6000806000606084860312156132ed576132ec61314c565b5b60006132fb8682870161319f565b935050602061330c8682870161319f565b925050604061331d868287016131cb565b9150509250925092565b60006020828403121561333d5761333c61314c565b5b600061334b848285016131cb565b91505092915050565b6000819050919050565b61336781613354565b82525050565b6000602082019050613382600083018461335e565b92915050565b600060ff82169050919050565b61339e81613388565b82525050565b60006020820190506133b96000830184613395565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133e4576133e36133bf565b5b8235905067ffffffffffffffff811115613401576134006133c4565b5b60208301915083600182028301111561341d5761341c6133c9565b5b9250929050565b6000806000806060858703121561343e5761343d61314c565b5b600061344c8782880161319f565b945050602061345d878288016131cb565b935050604085013567ffffffffffffffff81111561347e5761347d613151565b5b61348a878288016133ce565b925092505092959194509250565b60006134a382613176565b9050919050565b6134b381613498565b81146134be57600080fd5b50565b6000813590506134d0816134aa565b92915050565b6000806000806000608086880312156134f2576134f161314c565b5b6000613500888289016134c1565b95505060206135118882890161319f565b9450506040613522888289016131cb565b935050606086013567ffffffffffffffff81111561354357613542613151565b5b61354f888289016133ce565b92509250509295509295909350565b6000806000604084860312156135775761357661314c565b5b60006135858682870161319f565b935050602084013567ffffffffffffffff8111156135a6576135a5613151565b5b6135b2868287016133ce565b92509250509250925092565b6000602082840312156135d4576135d361314c565b5b60006135e28482850161319f565b91505092915050565b6000806000606084860312156136045761360361314c565b5b60006136128682870161319f565b93505060206136238682870161327f565b9250506040613634868287016131cb565b9150509250925092565b61364781613388565b811461365257600080fd5b50565b6000813590506136648161363e565b92915050565b61367381613354565b811461367e57600080fd5b50565b6000813590506136908161366a565b92915050565b600080600080600080600060e0888a0312156136b5576136b461314c565b5b60006136c38a828b0161319f565b97505060206136d48a828b0161319f565b96505060406136e58a828b016131cb565b95505060606136f68a828b016131cb565b94505060806137078a828b01613655565b93505060a06137188a828b01613681565b92505060c06137298a828b01613681565b91505092959891949750929550565b6000806040838503121561374f5761374e61314c565b5b600061375d8582860161319f565b925050602061376e8582860161319f565b9150509250929050565b7f57574952453a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b60006137d460228361309c565b91506137df82613778565b604082019050919050565b60006020820190508181036000830152613803816137c7565b9050919050565b600061381582612fd8565b915061382083612fd8565b92508282101561383357613832612fe2565b5b828203905092915050565b600081905092915050565b50565b600061385960008361383e565b915061386482613849565b600082019050919050565b600061387a8261384c565b9150819050919050565b7f57574952453a20455448207472616e73666572206661696c6564000000000000600082015250565b60006138ba601a8361309c565b91506138c582613884565b602082019050919050565b600060208201905081810360008301526138e9816138ad565b9050919050565b7f57574952453a2072657175657374206578636565647320616c6c6f77616e6365600082015250565b600061392660208361309c565b9150613931826138f0565b602082019050919050565b6000602082019050818103600083015261395581613919565b9050919050565b7f57574952453a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006139b860268361309c565b91506139c38261395c565b604082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b6139f781613176565b82525050565b600082825260208201905092915050565b82818337600083830152505050565b6000613a2983856139fd565b9350613a36838584613a0e565b613a3f836130e0565b840190509392505050565b6000606082019050613a5f60008301876139ee565b613a6c6020830186613067565b8181036040830152613a7f818486613a1d565b905095945050505050565b613a9381613220565b8114613a9e57600080fd5b50565b600081519050613ab081613a8a565b92915050565b600060208284031215613acc57613acb61314c565b5b6000613ada84828501613aa1565b91505092915050565b7f57574952453a20666c617368206d696e74206f6e6c7920575749524531300000600082015250565b6000613b19601e8361309c565b9150613b2482613ae3565b602082019050919050565b60006020820190508181036000830152613b4881613b0c565b9050919050565b7f57574952453a20696e646976696475616c206c6f616e206c696d69742065786360008201527f6565646564000000000000000000000000000000000000000000000000000000602082015250565b6000613bab60258361309c565b9150613bb682613b4f565b604082019050919050565b60006020820190508181036000830152613bda81613b9e565b9050919050565b7f57574952453a20746f74616c206c6f616e206c696d6974206578636565646564600082015250565b6000613c1760208361309c565b9150613c2282613be1565b602082019050919050565b60006020820190508181036000830152613c4681613c0a565b9050919050565b6000819050919050565b6000819050919050565b6000613c7c613c77613c7284613c4d565b613c57565b612fd8565b9050919050565b613c8c81613c61565b82525050565b600060a082019050613ca760008301896139ee565b613cb460208301886139ee565b613cc16040830187613067565b613cce6060830186613c83565b8181036080830152613ce1818486613a1d565b9050979650505050505050565b600081519050613cfd8161366a565b92915050565b600060208284031215613d1957613d1861314c565b5b6000613d2784828501613cee565b91505092915050565b7f57574952453a20666c617368206c6f616e206661696c65640000000000000000600082015250565b6000613d6660188361309c565b9150613d7182613d30565b602082019050919050565b60006020820190508181036000830152613d9581613d59565b9050919050565b7f57574952453a204574686572207472616e73666572206661696c656400000000600082015250565b6000613dd2601c8361309c565b9150613ddd82613d9c565b602082019050919050565b60006020820190508181036000830152613e0181613dc5565b9050919050565b7f57574952453a2045787069726564207065726d69740000000000000000000000600082015250565b6000613e3e60158361309c565b9150613e4982613e08565b602082019050919050565b60006020820190508181036000830152613e6d81613e31565b9050919050565b6000613e7f82612fd8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613eb257613eb1612fe2565b5b600182019050919050565b600060c082019050613ed2600083018961335e565b613edf60208301886139ee565b613eec60408301876139ee565b613ef96060830186613067565b613f066080830185613067565b613f1360a0830184613067565b979650505050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f5f600283613f1e565b9150613f6a82613f29565b600282019050919050565b6000819050919050565b613f90613f8b82613354565b613f75565b82525050565b6000613fa182613f52565b9150613fad8285613f7f565b602082019150613fbd8284613f7f565b6020820191508190509392505050565b6000608082019050613fe2600083018761335e565b613fef6020830186613395565b613ffc604083018561335e565b614009606083018461335e565b95945050505050565b7f57574952453a20696e76616c6964207065726d69740000000000000000000000600082015250565b600061404860158361309c565b915061405382614012565b602082019050919050565b600060208201905081810360008301526140778161403b565b9050919050565b600060a082019050614093600083018861335e565b6140a0602083018761335e565b6140ad604083018661335e565b6140ba6060830185613067565b6140c760808301846139ee565b969550505050505056fea26469706673582212203ad082a4dd55b89f7773cbaf58b6a7eb5fe3384feb2ae1108a089e070b39980264736f6c63430008090033

Deployed ByteCode

0x6080604052600436106101a05760003560e01c806370a08231116100ec578063b760faf91161008a578063d0e30db011610064578063d0e30db0146106d6578063d505accf146106e0578063d9d98ce414610709578063dd62ed3e1461074657610262565b8063b760faf914610652578063cae9ca511461066e578063cd0d0096146106ab57610262565b80638b28d32f116100c65780638b28d32f146105965780639555a942146105c157806395d89b41146105ea578063a9059cbb1461061557610262565b806370a08231146104f15780637ecebe001461052e5780638237e5381461056b57610262565b806330adf81f116101595780634000aea0116101335780634000aea01461040a5780635cffe9de146104475780635ddb7d7e14610484578063613255ab146104b457610262565b806330adf81f14610389578063313ce567146103b45780633644e515146103df57610262565b806306fdde0314610267578063095ea7b31461029257806318160ddd146102cf578063205c2878146102fa57806323b872dd146103235780632e1a7d4d1461036057610262565b3661026257346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101f39190613011565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef346040516102589190613076565b60405180910390a3005b600080fd5b34801561027357600080fd5b5061027c610783565b604051610289919061312a565b60405180910390f35b34801561029e57600080fd5b506102b960048036038101906102b491906131e0565b6107bc565b6040516102c6919061323b565b60405180910390f35b3480156102db57600080fd5b506102e46108ae565b6040516102f19190613076565b60405180910390f35b34801561030657600080fd5b50610321600480360381019061031c9190613294565b6108c3565b005b34801561032f57600080fd5b5061034a600480360381019061034591906132d4565b610aaf565b604051610357919061323b565b60405180910390f35b34801561036c57600080fd5b5061038760048036038101906103829190613327565b6110bf565b005b34801561039557600080fd5b5061039e6112aa565b6040516103ab919061336d565b60405180910390f35b3480156103c057600080fd5b506103c96112ce565b6040516103d691906133a4565b60405180910390f35b3480156103eb57600080fd5b506103f46112d3565b604051610401919061336d565b60405180910390f35b34801561041657600080fd5b50610431600480360381019061042c9190613424565b611336565b60405161043e919061323b565b60405180910390f35b34801561045357600080fd5b5061046e600480360381019061046991906134d6565b611783565b60405161047b919061323b565b60405180910390f35b61049e6004803603810190610499919061355e565b611da1565b6040516104ab919061323b565b60405180910390f35b3480156104c057600080fd5b506104db60048036038101906104d691906135be565b611ef8565b6040516104e89190613076565b60405180910390f35b3480156104fd57600080fd5b50610518600480360381019061051391906135be565b611f5a565b6040516105259190613076565b60405180910390f35b34801561053a57600080fd5b50610555600480360381019061055091906135be565b611f72565b6040516105629190613076565b60405180910390f35b34801561057757600080fd5b50610580611f8a565b60405161058d919061336d565b60405180910390f35b3480156105a257600080fd5b506105ab611fae565b6040516105b89190613076565b60405180910390f35b3480156105cd57600080fd5b506105e860048036038101906105e391906135eb565b611fb4565b005b3480156105f657600080fd5b506105ff6123b9565b60405161060c919061312a565b60405180910390f35b34801561062157600080fd5b5061063c600480360381019061063791906131e0565b6123f2565b604051610649919061323b565b60405180910390f35b61066c600480360381019061066791906135be565b6127e8565b005b34801561067a57600080fd5b5061069560048036038101906106909190613424565b6128a6565b6040516106a2919061323b565b60405180910390f35b3480156106b757600080fd5b506106c0612a28565b6040516106cd9190613076565b60405180910390f35b6106de612a4c565b005b3480156106ec57600080fd5b5061070760048036038101906107029190613696565b612b09565b005b34801561071557600080fd5b50610730600480360381019061072b91906131e0565b612e69565b60405161073d9190613076565b60405180910390f35b34801561075257600080fd5b5061076d60048036038101906107689190613738565b612ee3565b60405161077a9190613076565b60405180910390f35b6040518060400160405280600c81526020017f577261707065642057495245000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161089c9190613076565b60405180910390a36001905092915050565b6000600354476108be9190613011565b905090565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015610949576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610940906137ea565b60405180910390fd5b8181610955919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109f59190613076565b60405180910390a360008373ffffffffffffffffffffffffffffffffffffffff1683604051610a239061386f565b60006040518083038185875af1925050503d8060008114610a60576040519150601f19603f3d011682016040523d82523d6000602084013e610a65565b606091505b5050905080610aa9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa0906138d0565b60405180910390fd5b50505050565b60003373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614610cc9576000600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cc75782811015610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc69061393c565b60405180910390fd5b60008382610bdd919061380a565b905080600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051610cbd9190613076565b60405180910390a3505b505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015610d3257503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b15610ecb5760008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610dbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db4906139ce565b60405180910390fd5b8281610dc9919061380a565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610e599190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ebd9190613076565b60405180910390a3506110b4565b60008060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906137ea565b60405180910390fd5b8281610f5d919061380a565b6000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffd9190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168460405161102b9061386f565b60006040518083038185875af1925050503d8060008114611068576040519150601f19603f3d011682016040523d82523d6000602084013e61106d565b606091505b50509050806110b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110a8906138d0565b60405180910390fd5b50505b600190509392505050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611145576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113c906137ea565b60405180910390fd5b8181611151919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111f19190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168360405161121f9061386f565b60006040518083038185875af1925050503d806000811461125c576040519150601f19603f3d011682016040523d82523d6000602084013e611261565b606091505b50509050806112a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129c906138d0565b60405180910390fd5b505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b601281565b6000804690507f000000000000000000000000000000000000000000000000000000000000bf99811461130e5761130981612f08565b611330565b7f9fc1a9e41ff67346d062d65668f9a83d368e756cd6e4e0d734aef72d3683440d5b91505090565b60008073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146114ff5760008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050848110156113f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113e8906139ce565b60405180910390fd5b84816113fd919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550846000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461148d9190613011565b925050819055508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516114f19190613076565b60405180910390a3506116e8565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015611585576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157c906137ea565b60405180910390fd5b8481611591919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef876040516116319190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff168660405161165f9061386f565b60006040518083038185875af1925050503d806000811461169c576040519150601f19603f3d011682016040523d82523d6000602084013e6116a1565b606091505b50509050806116e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116dc906138d0565b60405180910390fd5b50505b8473ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36338686866040518563ffffffff1660e01b81526004016117279493929190613a4a565b602060405180830381600087803b15801561174157600080fd5b505af1158015611755573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117799190613ab6565b9050949350505050565b60003073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16146117f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117ea90613b2f565b60405180910390fd5b6dffffffffffffffffffffffffffff8016841115611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90613bc1565b60405180910390fd5b836003546118549190613011565b6003819055506dffffffffffffffffffffffffffff801660035411156118af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118a690613c2d565b60405180910390fd5b836000808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546118fd9190613011565b925050819055508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040516119629190613076565b60405180910390a37f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd98673ffffffffffffffffffffffffffffffffffffffff166323e30c8b333088600089896040518763ffffffff1660e01b81526004016119cf96959493929190613c92565b602060405180830381600087803b1580156119e957600080fd5b505af11580156119fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a219190613d03565b14611a61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5890613d7c565b60405180910390fd5b6000600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611c445784811015611b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b439061393c565b60405180910390fd5b60008582611b5a919061380a565b905080600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611c3a9190613076565b60405180910390a3505b60008060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905085811015611cca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc1906137ea565b60405180910390fd5b8581611cd6919061380a565b6000808a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef88604051611d769190613076565b60405180910390a385600354611d8c919061380a565b60038190555060019250505095945050505050565b6000346000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611df19190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef34604051611e569190613076565b60405180910390a38373ffffffffffffffffffffffffffffffffffffffff1663a4c0ed36333486866040518563ffffffff1660e01b8152600401611e9d9493929190613a4a565b602060405180830381600087803b158015611eb757600080fd5b505af1158015611ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611eef9190613ab6565b90509392505050565b60003073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611f34576000611f53565b6003546dffffffffffffffffffffffffffff8016611f52919061380a565b5b9050919050565b60006020528060005260406000206000915090505481565b60016020528060005260406000206000915090505481565b7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b60035481565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146121cc576000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146121ca57818110156120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c99061393c565b60405180910390fd5b600082826120e0919061380a565b905080600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121c09190613076565b60405180910390a3505b505b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612252576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612249906137ea565b60405180910390fd5b818161225e919061380a565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516122fe9190613076565b60405180910390a360008373ffffffffffffffffffffffffffffffffffffffff168360405161232c9061386f565b60006040518083038185875af1925050503d8060008114612369576040519150601f19603f3d011682016040523d82523d6000602084013e61236e565b606091505b50509050806123b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123a990613de8565b60405180910390fd5b5050505050565b6040518060400160405280600581526020017f575749524500000000000000000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561245c57503073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614155b156125f55760008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de906139ce565b60405180910390fd5b82816124f3919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125839190613011565b925050819055508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516125e79190613076565b60405180910390a3506127de565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508281101561267b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612672906137ea565b60405180910390fd5b8281612687919061380a565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516127279190613076565b60405180910390a360003373ffffffffffffffffffffffffffffffffffffffff16846040516127559061386f565b60006040518083038185875af1925050503d8060008114612792576040519150601f19603f3d011682016040523d82523d6000602084013e612797565b606091505b50509050806127db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127d2906138d0565b60405180910390fd5b50505b6001905092915050565b346000808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546128369190613011565b925050819055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3460405161289b9190613076565b60405180910390a350565b600083600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925866040516129869190613076565b60405180910390a38473ffffffffffffffffffffffffffffffffffffffff1662ba451f338686866040518563ffffffff1660e01b81526004016129cc9493929190613a4a565b602060405180830381600087803b1580156129e657600080fd5b505af11580156129fa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1e9190613ab6565b9050949350505050565b7f000000000000000000000000000000000000000000000000000000000000bf9981565b346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612a9a9190613011565b925050819055503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef34604051612aff9190613076565b60405180910390a3565b83421115612b4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4390613e54565b60405180910390fd5b600046905060007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9898989600160008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190612bc790613e74565b919050558a604051602001612be196959493929190613ebd565b60405160208183030381529060405280519060200120905060007f000000000000000000000000000000000000000000000000000000000000bf998314612c3057612c2b83612f08565b612c52565b7f9fc1a9e41ff67346d062d65668f9a83d368e756cd6e4e0d734aef72d3683440d5b82604051602001612c64929190613f96565b604051602081830303815290604052805190602001209050600060018288888860405160008152602001604052604051612ca19493929190613fcd565b6020604051602081039080840390855afa158015612cc3573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614158015612d3757508a73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b612d76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d6d9061405e565b60405180910390fd5b88600260008d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508973ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258b604051612e549190613076565b60405180910390a35050505050505050505050565b60003073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612ed9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ed090613b2f565b60405180910390fd5b6000905092915050565b6002602052816000526040600020602052806000526040600020600091509150505481565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6040518060400160405280600c81526020017f5772617070656420574952450000000000000000000000000000000000000000815250805190602001206040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250805190602001208430604051602001612fbb95949392919061407e565b604051602081830303815290604052805190602001209050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061301c82612fd8565b915061302783612fd8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561305c5761305b612fe2565b5b828201905092915050565b61307081612fd8565b82525050565b600060208201905061308b6000830184613067565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156130cb5780820151818401526020810190506130b0565b838111156130da576000848401525b50505050565b6000601f19601f8301169050919050565b60006130fc82613091565b613106818561309c565b93506131168185602086016130ad565b61311f816130e0565b840191505092915050565b6000602082019050818103600083015261314481846130f1565b905092915050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061318182613156565b9050919050565b61319181613176565b811461319c57600080fd5b50565b6000813590506131ae81613188565b92915050565b6131bd81612fd8565b81146131c857600080fd5b50565b6000813590506131da816131b4565b92915050565b600080604083850312156131f7576131f661314c565b5b60006132058582860161319f565b9250506020613216858286016131cb565b9150509250929050565b60008115159050919050565b61323581613220565b82525050565b6000602082019050613250600083018461322c565b92915050565b600061326182613156565b9050919050565b61327181613256565b811461327c57600080fd5b50565b60008135905061328e81613268565b92915050565b600080604083850312156132ab576132aa61314c565b5b60006132b98582860161327f565b92505060206132ca858286016131cb565b9150509250929050565b6000806000606084860312156132ed576132ec61314c565b5b60006132fb8682870161319f565b935050602061330c8682870161319f565b925050604061331d868287016131cb565b9150509250925092565b60006020828403121561333d5761333c61314c565b5b600061334b848285016131cb565b91505092915050565b6000819050919050565b61336781613354565b82525050565b6000602082019050613382600083018461335e565b92915050565b600060ff82169050919050565b61339e81613388565b82525050565b60006020820190506133b96000830184613395565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126133e4576133e36133bf565b5b8235905067ffffffffffffffff811115613401576134006133c4565b5b60208301915083600182028301111561341d5761341c6133c9565b5b9250929050565b6000806000806060858703121561343e5761343d61314c565b5b600061344c8782880161319f565b945050602061345d878288016131cb565b935050604085013567ffffffffffffffff81111561347e5761347d613151565b5b61348a878288016133ce565b925092505092959194509250565b60006134a382613176565b9050919050565b6134b381613498565b81146134be57600080fd5b50565b6000813590506134d0816134aa565b92915050565b6000806000806000608086880312156134f2576134f161314c565b5b6000613500888289016134c1565b95505060206135118882890161319f565b9450506040613522888289016131cb565b935050606086013567ffffffffffffffff81111561354357613542613151565b5b61354f888289016133ce565b92509250509295509295909350565b6000806000604084860312156135775761357661314c565b5b60006135858682870161319f565b935050602084013567ffffffffffffffff8111156135a6576135a5613151565b5b6135b2868287016133ce565b92509250509250925092565b6000602082840312156135d4576135d361314c565b5b60006135e28482850161319f565b91505092915050565b6000806000606084860312156136045761360361314c565b5b60006136128682870161319f565b93505060206136238682870161327f565b9250506040613634868287016131cb565b9150509250925092565b61364781613388565b811461365257600080fd5b50565b6000813590506136648161363e565b92915050565b61367381613354565b811461367e57600080fd5b50565b6000813590506136908161366a565b92915050565b600080600080600080600060e0888a0312156136b5576136b461314c565b5b60006136c38a828b0161319f565b97505060206136d48a828b0161319f565b96505060406136e58a828b016131cb565b95505060606136f68a828b016131cb565b94505060806137078a828b01613655565b93505060a06137188a828b01613681565b92505060c06137298a828b01613681565b91505092959891949750929550565b6000806040838503121561374f5761374e61314c565b5b600061375d8582860161319f565b925050602061376e8582860161319f565b9150509250929050565b7f57574952453a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b60006137d460228361309c565b91506137df82613778565b604082019050919050565b60006020820190508181036000830152613803816137c7565b9050919050565b600061381582612fd8565b915061382083612fd8565b92508282101561383357613832612fe2565b5b828203905092915050565b600081905092915050565b50565b600061385960008361383e565b915061386482613849565b600082019050919050565b600061387a8261384c565b9150819050919050565b7f57574952453a20455448207472616e73666572206661696c6564000000000000600082015250565b60006138ba601a8361309c565b91506138c582613884565b602082019050919050565b600060208201905081810360008301526138e9816138ad565b9050919050565b7f57574952453a2072657175657374206578636565647320616c6c6f77616e6365600082015250565b600061392660208361309c565b9150613931826138f0565b602082019050919050565b6000602082019050818103600083015261395581613919565b9050919050565b7f57574952453a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b60006139b860268361309c565b91506139c38261395c565b604082019050919050565b600060208201905081810360008301526139e7816139ab565b9050919050565b6139f781613176565b82525050565b600082825260208201905092915050565b82818337600083830152505050565b6000613a2983856139fd565b9350613a36838584613a0e565b613a3f836130e0565b840190509392505050565b6000606082019050613a5f60008301876139ee565b613a6c6020830186613067565b8181036040830152613a7f818486613a1d565b905095945050505050565b613a9381613220565b8114613a9e57600080fd5b50565b600081519050613ab081613a8a565b92915050565b600060208284031215613acc57613acb61314c565b5b6000613ada84828501613aa1565b91505092915050565b7f57574952453a20666c617368206d696e74206f6e6c7920575749524531300000600082015250565b6000613b19601e8361309c565b9150613b2482613ae3565b602082019050919050565b60006020820190508181036000830152613b4881613b0c565b9050919050565b7f57574952453a20696e646976696475616c206c6f616e206c696d69742065786360008201527f6565646564000000000000000000000000000000000000000000000000000000602082015250565b6000613bab60258361309c565b9150613bb682613b4f565b604082019050919050565b60006020820190508181036000830152613bda81613b9e565b9050919050565b7f57574952453a20746f74616c206c6f616e206c696d6974206578636565646564600082015250565b6000613c1760208361309c565b9150613c2282613be1565b602082019050919050565b60006020820190508181036000830152613c4681613c0a565b9050919050565b6000819050919050565b6000819050919050565b6000613c7c613c77613c7284613c4d565b613c57565b612fd8565b9050919050565b613c8c81613c61565b82525050565b600060a082019050613ca760008301896139ee565b613cb460208301886139ee565b613cc16040830187613067565b613cce6060830186613c83565b8181036080830152613ce1818486613a1d565b9050979650505050505050565b600081519050613cfd8161366a565b92915050565b600060208284031215613d1957613d1861314c565b5b6000613d2784828501613cee565b91505092915050565b7f57574952453a20666c617368206c6f616e206661696c65640000000000000000600082015250565b6000613d6660188361309c565b9150613d7182613d30565b602082019050919050565b60006020820190508181036000830152613d9581613d59565b9050919050565b7f57574952453a204574686572207472616e73666572206661696c656400000000600082015250565b6000613dd2601c8361309c565b9150613ddd82613d9c565b602082019050919050565b60006020820190508181036000830152613e0181613dc5565b9050919050565b7f57574952453a2045787069726564207065726d69740000000000000000000000600082015250565b6000613e3e60158361309c565b9150613e4982613e08565b602082019050919050565b60006020820190508181036000830152613e6d81613e31565b9050919050565b6000613e7f82612fd8565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613eb257613eb1612fe2565b5b600182019050919050565b600060c082019050613ed2600083018961335e565b613edf60208301886139ee565b613eec60408301876139ee565b613ef96060830186613067565b613f066080830185613067565b613f1360a0830184613067565b979650505050505050565b600081905092915050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b6000613f5f600283613f1e565b9150613f6a82613f29565b600282019050919050565b6000819050919050565b613f90613f8b82613354565b613f75565b82525050565b6000613fa182613f52565b9150613fad8285613f7f565b602082019150613fbd8284613f7f565b6020820191508190509392505050565b6000608082019050613fe2600083018761335e565b613fef6020830186613395565b613ffc604083018561335e565b614009606083018461335e565b95945050505050565b7f57574952453a20696e76616c6964207065726d69740000000000000000000000600082015250565b600061404860158361309c565b915061405382614012565b602082019050919050565b600060208201905081810360008301526140778161403b565b9050919050565b600060a082019050614093600083018861335e565b6140a0602083018761335e565b6140ad604083018661335e565b6140ba6060830185613067565b6140c760808301846139ee565b969550505050505056fea26469706673582212203ad082a4dd55b89f7773cbaf58b6a7eb5fe3384feb2ae1108a089e070b39980264736f6c63430008090033