Contract 0x7a8d060709eef87d9075ff7388d06fc365c904ff

 
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x97f9f8169af85a6aa54067001f8c6526a6273db0ff8b06037b5bc750e7491fd1Stake111178752021-09-21 21:00:123 hrs 37 mins ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037673
0x823288c343e18c2f4ae18ca2197e3cd3ec8fb582dab1e305facf1ffecd75ffd8Stake111115782021-09-21 15:42:258 hrs 55 mins ago0xc59af7cea3037180aa98a5d62a79adadb3342868 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037673
0xeb056825baf11166bd2839ee62ae25ada4a7e8358ad6c63a48bed8dcbbe6d8f2Stake109904182021-09-17 10:19:184 days 14 hrs ago0x2123cea46699cd2a900e10840a701db2c32148db IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00045155
0xda3ca8b912c0f4c44464cab29732f4a1474519e2c51fbe67a9d6f1f762473831Stake109888672021-09-17 9:01:424 days 15 hrs ago0xc59af7cea3037180aa98a5d62a79adadb3342868 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037887
0xe6028ef46d46ebff1aa6bce6352b50cfab2648edd680b5bdc5244cb49c4ee111Stake109746542021-09-16 21:10:295 days 3 hrs ago0x9fb84b926b01117d2f5e44f0883b2d1b7f9f300d IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037893
0x9eda85b0cdb1b13fd05189d232882390cf454e4a14b47ec7d0e2edefd155bbcfStake109676802021-09-16 15:21:005 days 9 hrs ago0x2e1ba8a950646f1c02393a99bdf9faa48165f213 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037661
0xc0f68c44070a3b1fb7715962a8db22217d953504254a3f94e88fd07edd31b5baStake109676572021-09-16 15:19:515 days 9 hrs ago0x26eff94c0ad04a5cded83f1621fb9ed6c1dde0a0 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037661
0x3efaa89e22ed15b8e9e8946218b097ee012c48bc67e0d06acd310d60c0345be9Withdraw109672332021-09-16 14:58:175 days 9 hrs ago0x0edb4366827c863ceb15b67d9dd64de483343189 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477585
0x576b24d5291a13ecade3d918a07e48c59dcd7ac415a86a91363fa92b19f74579Stake109649922021-09-16 13:06:135 days 11 hrs ago0x483fb69443da74e03af78e399551f0e53325ef26 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00037673
0x257c02592f5acbcd55f0d733275140a2b4111e03803e3400c5c747101343865cStake109605422021-09-16 9:22:345 days 15 hrs ago0x2123cea46699cd2a900e10840a701db2c32148db IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00045161
0x37240474c9768576c4c107491dbda0622c170fe8244fee13b4f1069bef7877e7Withdraw109462232021-09-15 21:25:446 days 3 hrs ago0x2e1ba8a950646f1c02393a99bdf9faa48165f213 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477645
0xc357ea3a224ac87abb8dfc29a32942aca09b5dca3425190090cbb53f56371ba1Withdraw109461942021-09-15 21:24:176 days 3 hrs ago0x26eff94c0ad04a5cded83f1621fb9ed6c1dde0a0 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477645
0x0c382b08694f6e4b07ad0fcda4dceb95997925bef79a8862d058fd646f599e0eWithdraw109415982021-09-15 17:34:296 days 7 hrs ago0x2123cea46699cd2a900e10840a701db2c32148db IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477645
0x98ba31b84729ec4da4dd8eaad62032ffbee91d1d832a40691e211788eef697f5Withdraw109391242021-09-15 15:30:466 days 9 hrs ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477645
0xcc213ada5e0919752179dab88840e6edf1bae6766c6601107969a86503026740Get Reward109391002021-09-15 15:29:346 days 9 hrs ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000336035
0x3554682e838cebf79f7342ced03fc45e68e7d2fade135df7e463ab90e7de3d32Updating Staking...109390952021-09-15 15:29:196 days 9 hrs ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00024124
0x6b5213dc6613e37d6493dbf7198e791a6ed9f4fcbdb70936ad77838e07e49eecGet Reward LP109390892021-09-15 15:29:016 days 9 hrs ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00041065
0x292f520333e9309ab96b83300c8c9e801982dfbec359bfcdac3ddd5e4e5ee6bfUpdating Staking...109390832021-09-15 15:28:436 days 9 hrs ago0x60612cb928d5f34e47cd6e025b974ecbdd7e70a5 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000315805
0x9f4d20d42db97e161e354713d33ab08d3cdfb2bc60bfa863cf6ba099b6e1057aWithdraw109364112021-09-15 13:15:076 days 11 hrs ago0xc59af7cea3037180aa98a5d62a79adadb3342868 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000402765
0xe4a63b577bdf706910a0f23c935a7380e067a7cd66e45e1c4dbd29209f4bade7Updating Staking...109363902021-09-15 13:14:046 days 11 hrs ago0xc59af7cea3037180aa98a5d62a79adadb3342868 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.00031624
0x8878f4e479b5c67eb4d9a3f803455d42d05f5a55da704ee233102f59f12c06e6Updating Staking...109363842021-09-15 13:13:466 days 11 hrs ago0xc59af7cea3037180aa98a5d62a79adadb3342868 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000240805
0xb8fdad3c42ab181348c54e82b228b4674213223eb25f1433e072d51722834ef7Withdraw109319282021-09-15 9:29:406 days 15 hrs ago0x9fb84b926b01117d2f5e44f0883b2d1b7f9f300d IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000327765
0x92c6037a9f4eb92d20312a351a663049707476c47cc0e8dc262202fdacfb1b5eWithdraw109318832021-09-15 9:27:256 days 15 hrs ago0x8603187daf20e1ccd005b6839b0d3c204bb6e51c IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000402765
0xc00cfd8efdbbfe5be3db72676c7e594b32764df290894ec31b68996657bbf833Withdraw109318702021-09-15 9:26:466 days 15 hrs ago0x483fb69443da74e03af78e399551f0e53325ef26 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000402645
0x0e06e91dd6df45511bd9ecfe30328b98eec5a2cb96a7dccddb005e7149f13fa3Withdraw109318292021-09-15 9:24:436 days 15 hrs ago0x483fb69443da74e03af78e399551f0e53325ef26 IN  0x7a8d060709eef87d9075ff7388d06fc365c904ff0 BNB0.000477645
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HashCatFarming

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-04-19
*/

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

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

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

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

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

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

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

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

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The defaut value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overloaded;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);

        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

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

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

library SafeERC20 {
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * Smart contract library of mathematical functions operating with IEEE 754
 * quadruple-precision binary floating-point numbers (quadruple precision
 * numbers).  As long as quadruple precision numbers are 16-bytes long, they are
 * represented by bytes16 type.
 */
library ABDKMathQuad {
  /*
   * 0.
   */
  bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000;

  /*
   * -0.
   */
  bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000;

  /*
   * +Infinity.
   */
  bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000;

  /*
   * -Infinity.
   */
  bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000;

  /*
   * Canonical NaN value.
   */
  bytes16 private constant NaN = 0x7FFF8000000000000000000000000000;

  /**
   * Convert signed 256-bit integer number into quadruple precision number.
   *
   * @param x signed 256-bit integer number
   * @return quadruple precision number
   */
  function fromInt (int256 x) internal pure returns (bytes16) {
    unchecked {
      if (x == 0) return bytes16 (0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint256 (x > 0 ? x : -x);

        uint256 msb = mostSignificantBit (result);
        if (msb < 112) result <<= 112 - msb;
        else if (msb > 112) result >>= msb - 112;

        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;
        if (x < 0) result |= 0x80000000000000000000000000000000;

        return bytes16 (uint128 (result));
      }
    }
  }

  /**
   * Convert quadruple precision number into signed 256-bit integer number
   * rounding towards zero.  Revert on overflow.
   *
   * @param x quadruple precision number
   * @return signed 256-bit integer number
   */
  function toInt (bytes16 x) internal pure returns (int256) {
    unchecked {
      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;

      require (exponent <= 16638); // Overflow
      if (exponent < 16383) return 0; // Underflow

      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
        0x10000000000000000000000000000;

      if (exponent < 16495) result >>= 16495 - exponent;
      else if (exponent > 16495) result <<= exponent - 16495;

      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
        require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);
        return -int256 (result); // We rely on overflow behavior here
      } else {
        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int256 (result);
      }
    }
  }

  /**
   * Convert unsigned 256-bit integer number into quadruple precision number.
   *
   * @param x unsigned 256-bit integer number
   * @return quadruple precision number
   */
  function fromUInt (uint256 x) internal pure returns (bytes16) {
    unchecked {
      if (x == 0) return bytes16 (0);
      else {
        uint256 result = x;

        uint256 msb = mostSignificantBit (result);
        if (msb < 112) result <<= 112 - msb;
        else if (msb > 112) result >>= msb - 112;

        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;

        return bytes16 (uint128 (result));
      }
    }
  }

  /**
   * Convert quadruple precision number into unsigned 256-bit integer number
   * rounding towards zero.  Revert on underflow.  Note, that negative floating
   * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer
   * without error, because they are rounded to zero.
   *
   * @param x quadruple precision number
   * @return unsigned 256-bit integer number
   */
  function toUInt (bytes16 x) internal pure returns (uint256) {
    unchecked {
      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;

      if (exponent < 16383) return 0; // Underflow

      require (uint128 (x) < 0x80000000000000000000000000000000); // Negative

      require (exponent <= 16638); // Overflow
      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
        0x10000000000000000000000000000;

      if (exponent < 16495) result >>= 16495 - exponent;
      else if (exponent > 16495) result <<= exponent - 16495;

      return result;
    }
  }

  /**
   * Convert signed 128.128 bit fixed point number into quadruple precision
   * number.
   *
   * @param x signed 128.128 bit fixed point number
   * @return quadruple precision number
   */
  function from128x128 (int256 x) internal pure returns (bytes16) {
    unchecked {
      if (x == 0) return bytes16 (0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint256 (x > 0 ? x : -x);

        uint256 msb = mostSignificantBit (result);
        if (msb < 112) result <<= 112 - msb;
        else if (msb > 112) result >>= msb - 112;

        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112;
        if (x < 0) result |= 0x80000000000000000000000000000000;

        return bytes16 (uint128 (result));
      }
    }
  }

  /**
   * Convert quadruple precision number into signed 128.128 bit fixed point
   * number.  Revert on overflow.
   *
   * @param x quadruple precision number
   * @return signed 128.128 bit fixed point number
   */
  function to128x128 (bytes16 x) internal pure returns (int256) {
    unchecked {
      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;

      require (exponent <= 16510); // Overflow
      if (exponent < 16255) return 0; // Underflow

      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
        0x10000000000000000000000000000;

      if (exponent < 16367) result >>= 16367 - exponent;
      else if (exponent > 16367) result <<= exponent - 16367;

      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
        require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);
        return -int256 (result); // We rely on overflow behavior here
      } else {
        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int256 (result);
      }
    }
  }

  /**
   * Convert signed 64.64 bit fixed point number into quadruple precision
   * number.
   *
   * @param x signed 64.64 bit fixed point number
   * @return quadruple precision number
   */
  function from64x64 (int128 x) internal pure returns (bytes16) {
    unchecked {
      if (x == 0) return bytes16 (0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint128 (x > 0 ? x : -x);

        uint256 msb = mostSignificantBit (result);
        if (msb < 112) result <<= 112 - msb;
        else if (msb > 112) result >>= msb - 112;

        result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112;
        if (x < 0) result |= 0x80000000000000000000000000000000;

        return bytes16 (uint128 (result));
      }
    }
  }

  /**
   * Convert quadruple precision number into signed 64.64 bit fixed point
   * number.  Revert on overflow.
   *
   * @param x quadruple precision number
   * @return signed 64.64 bit fixed point number
   */
  function to64x64 (bytes16 x) internal pure returns (int128) {
    unchecked {
      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;

      require (exponent <= 16446); // Overflow
      if (exponent < 16319) return 0; // Underflow

      uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
        0x10000000000000000000000000000;

      if (exponent < 16431) result >>= 16431 - exponent;
      else if (exponent > 16431) result <<= exponent - 16431;

      if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
        require (result <= 0x80000000000000000000000000000000);
        return -int128 (int256 (result)); // We rely on overflow behavior here
      } else {
        require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int128 (int256 (result));
      }
    }
  }

  /**
   * Convert octuple precision number into quadruple precision number.
   *
   * @param x octuple precision number
   * @return quadruple precision number
   */
  function fromOctuple (bytes32 x) internal pure returns (bytes16) {
    unchecked {
      bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0;

      uint256 exponent = uint256 (x) >> 236 & 0x7FFFF;
      uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      if (exponent == 0x7FFFF) {
        if (significand > 0) return NaN;
        else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
      }

      if (exponent > 278526)
        return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
      else if (exponent < 245649)
        return negative ? NEGATIVE_ZERO : POSITIVE_ZERO;
      else if (exponent < 245761) {
        significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent;
        exponent = 0;
      } else {
        significand >>= 124;
        exponent -= 245760;
      }

      uint128 result = uint128 (significand | exponent << 112);
      if (negative) result |= 0x80000000000000000000000000000000;

      return bytes16 (result);
    }
  }

  /**
   * Convert quadruple precision number into octuple precision number.
   *
   * @param x quadruple precision number
   * @return octuple precision number
   */
  function toOctuple (bytes16 x) internal pure returns (bytes32) {
    unchecked {
      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;

      uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN
      else if (exponent == 0) {
        if (result > 0) {
          uint256 msb = mostSignificantBit (result);
          result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          exponent = 245649 + msb;
        }
      } else {
        result <<= 124;
        exponent += 245760;
      }

      result |= exponent << 236;
      if (uint128 (x) >= 0x80000000000000000000000000000000)
        result |= 0x8000000000000000000000000000000000000000000000000000000000000000;

      return bytes32 (result);
    }
  }

  /**
   * Convert double precision number into quadruple precision number.
   *
   * @param x double precision number
   * @return quadruple precision number
   */
  function fromDouble (bytes8 x) internal pure returns (bytes16) {
    unchecked {
      uint256 exponent = uint64 (x) >> 52 & 0x7FF;

      uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF;

      if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN
      else if (exponent == 0) {
        if (result > 0) {
          uint256 msb = mostSignificantBit (result);
          result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          exponent = 15309 + msb;
        }
      } else {
        result <<= 60;
        exponent += 15360;
      }

      result |= exponent << 112;
      if (x & 0x8000000000000000 > 0)
        result |= 0x80000000000000000000000000000000;

      return bytes16 (uint128 (result));
    }
  }

  /**
   * Convert quadruple precision number into double precision number.
   *
   * @param x quadruple precision number
   * @return double precision number
   */
  function toDouble (bytes16 x) internal pure returns (bytes8) {
    unchecked {
      bool negative = uint128 (x) >= 0x80000000000000000000000000000000;

      uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
      uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      if (exponent == 0x7FFF) {
        if (significand > 0) return 0x7FF8000000000000; // NaN
        else return negative ?
            bytes8 (0xFFF0000000000000) : // -Infinity
            bytes8 (0x7FF0000000000000); // Infinity
      }

      if (exponent > 17406)
        return negative ?
            bytes8 (0xFFF0000000000000) : // -Infinity
            bytes8 (0x7FF0000000000000); // Infinity
      else if (exponent < 15309)
        return negative ?
            bytes8 (0x8000000000000000) : // -0
            bytes8 (0x0000000000000000); // 0
      else if (exponent < 15361) {
        significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent;
        exponent = 0;
      } else {
        significand >>= 60;
        exponent -= 15360;
      }

      uint64 result = uint64 (significand | exponent << 52);
      if (negative) result |= 0x8000000000000000;

      return bytes8 (result);
    }
  }

  /**
   * Test whether given quadruple precision number is NaN.
   *
   * @param x quadruple precision number
   * @return true if x is NaN, false otherwise
   */
  function isNaN (bytes16 x) internal pure returns (bool) {
    unchecked {
      return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF >
        0x7FFF0000000000000000000000000000;
    }
  }

  /**
   * Test whether given quadruple precision number is positive or negative
   * infinity.
   *
   * @param x quadruple precision number
   * @return true if x is positive or negative infinity, false otherwise
   */
  function isInfinity (bytes16 x) internal pure returns (bool) {
    unchecked {
      return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ==
        0x7FFF0000000000000000000000000000;
    }
  }

  /**
   * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x
   * is positive.  Note that sign (-0) is zero.  Revert if x is NaN. 
   *
   * @param x quadruple precision number
   * @return sign of x
   */
  function sign (bytes16 x) internal pure returns (int8) {
    unchecked {
      uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN

      if (absoluteX == 0) return 0;
      else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1;
      else return 1;
    }
  }

  /**
   * Calculate sign (x - y).  Revert if either argument is NaN, or both
   * arguments are infinities of the same sign. 
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return sign (x - y)
   */
  function cmp (bytes16 x, bytes16 y) internal pure returns (int8) {
    unchecked {
      uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN

      uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN

      // Not infinities of the same sign
      require (x != y || absoluteX < 0x7FFF0000000000000000000000000000);

      if (x == y) return 0;
      else {
        bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000;
        bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000;

        if (negativeX) {
          if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1);
          else return -1; 
        } else {
          if (negativeY) return 1;
          else return absoluteX > absoluteY ? int8 (1) : -1;
        }
      }
    }
  }

  /**
   * Test whether x equals y.  NaN, infinity, and -infinity are not equal to
   * anything. 
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return true if x equals to y, false otherwise
   */
  function eq (bytes16 x, bytes16 y) internal pure returns (bool) {
    unchecked {
      if (x == y) {
        return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF <
          0x7FFF0000000000000000000000000000;
      } else return false;
    }
  }

  /**
   * Calculate x + y.  Special values behave in the following way:
   *
   * NaN + x = NaN for any x.
   * Infinity + x = Infinity for any finite x.
   * -Infinity + x = -Infinity for any finite x.
   * Infinity + Infinity = Infinity.
   * -Infinity + -Infinity = -Infinity.
   * Infinity + -Infinity = -Infinity + Infinity = NaN.
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return quadruple precision number
   */
  function add (bytes16 x, bytes16 y) internal pure returns (bytes16) {
    unchecked {
      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;

      if (xExponent == 0x7FFF) {
        if (yExponent == 0x7FFF) { 
          if (x == y) return x;
          else return NaN;
        } else return x; 
      } else if (yExponent == 0x7FFF) return y;
      else {
        bool xSign = uint128 (x) >= 0x80000000000000000000000000000000;
        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (xExponent == 0) xExponent = 1;
        else xSignifier |= 0x10000000000000000000000000000;

        bool ySign = uint128 (y) >= 0x80000000000000000000000000000000;
        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (yExponent == 0) yExponent = 1;
        else ySignifier |= 0x10000000000000000000000000000;

        if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y;
        else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x;
        else {
          int256 delta = int256 (xExponent) - int256 (yExponent);
  
          if (xSign == ySign) {
            if (delta > 112) return x;
            else if (delta > 0) ySignifier >>= uint256 (delta);
            else if (delta < -112) return y;
            else if (delta < 0) {
              xSignifier >>= uint256 (-delta);
              xExponent = yExponent;
            }
  
            xSignifier += ySignifier;
  
            if (xSignifier >= 0x20000000000000000000000000000) {
              xSignifier >>= 1;
              xExponent += 1;
            }
  
            if (xExponent == 0x7FFF)
              return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
            else {
              if (xSignifier < 0x10000000000000000000000000000) xExponent = 0;
              else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
  
              return bytes16 (uint128 (
                  (xSign ? 0x80000000000000000000000000000000 : 0) |
                  (xExponent << 112) |
                  xSignifier)); 
            }
          } else {
            if (delta > 0) {
              xSignifier <<= 1;
              xExponent -= 1;
            } else if (delta < 0) {
              ySignifier <<= 1;
              xExponent = yExponent - 1;
            }

            if (delta > 112) ySignifier = 1;
            else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1;
            else if (delta < -112) xSignifier = 1;
            else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1;

            if (xSignifier >= ySignifier) xSignifier -= ySignifier;
            else {
              xSignifier = ySignifier - xSignifier;
              xSign = ySign;
            }

            if (xSignifier == 0)
              return POSITIVE_ZERO;

            uint256 msb = mostSignificantBit (xSignifier);

            if (msb == 113) {
              xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
              xExponent += 1;
            } else if (msb < 112) {
              uint256 shift = 112 - msb;
              if (xExponent > shift) {
                xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
                xExponent -= shift;
              } else {
                xSignifier <<= xExponent - 1;
                xExponent = 0;
              }
            } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

            if (xExponent == 0x7FFF)
              return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
            else return bytes16 (uint128 (
                (xSign ? 0x80000000000000000000000000000000 : 0) |
                (xExponent << 112) |
                xSignifier));
          }
        }
      }
    }
  }

  /**
   * Calculate x - y.  Special values behave in the following way:
   *
   * NaN - x = NaN for any x.
   * Infinity - x = Infinity for any finite x.
   * -Infinity - x = -Infinity for any finite x.
   * Infinity - -Infinity = Infinity.
   * -Infinity - Infinity = -Infinity.
   * Infinity - Infinity = -Infinity - -Infinity = NaN.
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return quadruple precision number
   */
  function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) {
    unchecked {
      return add (x, y ^ 0x80000000000000000000000000000000);
    }
  }

  /**
   * Calculate x * y.  Special values behave in the following way:
   *
   * NaN * x = NaN for any x.
   * Infinity * x = Infinity for any finite positive x.
   * Infinity * x = -Infinity for any finite negative x.
   * -Infinity * x = -Infinity for any finite positive x.
   * -Infinity * x = Infinity for any finite negative x.
   * Infinity * 0 = NaN.
   * -Infinity * 0 = NaN.
   * Infinity * Infinity = Infinity.
   * Infinity * -Infinity = -Infinity.
   * -Infinity * Infinity = -Infinity.
   * -Infinity * -Infinity = Infinity.
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return quadruple precision number
   */
  function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) {
    unchecked {
      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;

      if (xExponent == 0x7FFF) {
        if (yExponent == 0x7FFF) {
          if (x == y) return x ^ y & 0x80000000000000000000000000000000;
          else if (x ^ y == 0x80000000000000000000000000000000) return x | y;
          else return NaN;
        } else {
          if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
          else return x ^ y & 0x80000000000000000000000000000000;
        }
      } else if (yExponent == 0x7FFF) {
          if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
          else return y ^ x & 0x80000000000000000000000000000000;
      } else {
        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (xExponent == 0) xExponent = 1;
        else xSignifier |= 0x10000000000000000000000000000;

        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (yExponent == 0) yExponent = 1;
        else ySignifier |= 0x10000000000000000000000000000;

        xSignifier *= ySignifier;
        if (xSignifier == 0)
          return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?
              NEGATIVE_ZERO : POSITIVE_ZERO;

        xExponent += yExponent;

        uint256 msb =
          xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 :
          xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 :
          mostSignificantBit (xSignifier);

        if (xExponent + msb < 16496) { // Underflow
          xExponent = 0;
          xSignifier = 0;
        } else if (xExponent + msb < 16608) { // Subnormal
          if (xExponent < 16496)
            xSignifier >>= 16496 - xExponent;
          else if (xExponent > 16496)
            xSignifier <<= xExponent - 16496;
          xExponent = 0;
        } else if (xExponent + msb > 49373) {
          xExponent = 0x7FFF;
          xSignifier = 0;
        } else {
          if (msb > 112)
            xSignifier >>= msb - 112;
          else if (msb < 112)
            xSignifier <<= 112 - msb;

          xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

          xExponent = xExponent + msb - 16607;
        }

        return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |
            xExponent << 112 | xSignifier));
      }
    }
  }

  /**
   * Calculate x / y.  Special values behave in the following way:
   *
   * NaN / x = NaN for any x.
   * x / NaN = NaN for any x.
   * Infinity / x = Infinity for any finite non-negative x.
   * Infinity / x = -Infinity for any finite negative x including -0.
   * -Infinity / x = -Infinity for any finite non-negative x.
   * -Infinity / x = Infinity for any finite negative x including -0.
   * x / Infinity = 0 for any finite non-negative x.
   * x / -Infinity = -0 for any finite non-negative x.
   * x / Infinity = -0 for any finite non-negative x including -0.
   * x / -Infinity = 0 for any finite non-negative x including -0.
   * 
   * Infinity / Infinity = NaN.
   * Infinity / -Infinity = -NaN.
   * -Infinity / Infinity = -NaN.
   * -Infinity / -Infinity = NaN.
   *
   * Division by zero behaves in the following way:
   *
   * x / 0 = Infinity for any finite positive x.
   * x / -0 = -Infinity for any finite positive x.
   * x / 0 = -Infinity for any finite negative x.
   * x / -0 = Infinity for any finite negative x.
   * 0 / 0 = NaN.
   * 0 / -0 = NaN.
   * -0 / 0 = NaN.
   * -0 / -0 = NaN.
   *
   * @param x quadruple precision number
   * @param y quadruple precision number
   * @return quadruple precision number
   */
  function div (bytes16 x, bytes16 y) internal pure returns (bytes16) {
    unchecked {
      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
      uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;

      if (xExponent == 0x7FFF) {
        if (yExponent == 0x7FFF) return NaN;
        else return x ^ y & 0x80000000000000000000000000000000;
      } else if (yExponent == 0x7FFF) {
        if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN;
        else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000;
      } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) {
        if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
        else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000;
      } else {
        uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (yExponent == 0) yExponent = 1;
        else ySignifier |= 0x10000000000000000000000000000;

        uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (xExponent == 0) {
          if (xSignifier != 0) {
            uint shift = 226 - mostSignificantBit (xSignifier);

            xSignifier <<= shift;

            xExponent = 1;
            yExponent += shift - 114;
          }
        }
        else {
          xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114;
        }

        xSignifier = xSignifier / ySignifier;
        if (xSignifier == 0)
          return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?
              NEGATIVE_ZERO : POSITIVE_ZERO;

        assert (xSignifier >= 0x1000000000000000000000000000);

        uint256 msb =
          xSignifier >= 0x80000000000000000000000000000 ? mostSignificantBit (xSignifier) :
          xSignifier >= 0x40000000000000000000000000000 ? 114 :
          xSignifier >= 0x20000000000000000000000000000 ? 113 : 112;

        if (xExponent + msb > yExponent + 16497) { // Overflow
          xExponent = 0x7FFF;
          xSignifier = 0;
        } else if (xExponent + msb + 16380  < yExponent) { // Underflow
          xExponent = 0;
          xSignifier = 0;
        } else if (xExponent + msb + 16268  < yExponent) { // Subnormal
          if (xExponent + 16380 > yExponent)
            xSignifier <<= xExponent + 16380 - yExponent;
          else if (xExponent + 16380 < yExponent)
            xSignifier >>= yExponent - xExponent - 16380;

          xExponent = 0;
        } else { // Normal
          if (msb > 112)
            xSignifier >>= msb - 112;

          xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

          xExponent = xExponent + msb + 16269 - yExponent;
        }

        return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |
            xExponent << 112 | xSignifier));
      }
    }
  }

  /**
   * Calculate -x.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function neg (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      return x ^ 0x80000000000000000000000000000000;
    }
  }

  /**
   * Calculate |x|.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function abs (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
    }
  }

  /**
   * Calculate square root of x.  Return NaN on negative x excluding -0.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function sqrt (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      if (uint128 (x) >  0x80000000000000000000000000000000) return NaN;
      else {
        uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
        if (xExponent == 0x7FFF) return x;
        else {
          uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          if (xExponent == 0) xExponent = 1;
          else xSignifier |= 0x10000000000000000000000000000;

          if (xSignifier == 0) return POSITIVE_ZERO;

          bool oddExponent = xExponent & 0x1 == 0;
          xExponent = xExponent + 16383 >> 1;

          if (oddExponent) {
            if (xSignifier >= 0x10000000000000000000000000000)
              xSignifier <<= 113;
            else {
              uint256 msb = mostSignificantBit (xSignifier);
              uint256 shift = (226 - msb) & 0xFE;
              xSignifier <<= shift;
              xExponent -= shift - 112 >> 1;
            }
          } else {
            if (xSignifier >= 0x10000000000000000000000000000)
              xSignifier <<= 112;
            else {
              uint256 msb = mostSignificantBit (xSignifier);
              uint256 shift = (225 - msb) & 0xFE;
              xSignifier <<= shift;
              xExponent -= shift - 112 >> 1;
            }
          }

          uint256 r = 0x10000000000000000000000000000;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1;
          r = (r + xSignifier / r) >> 1; // Seven iterations should be enough
          uint256 r1 = xSignifier / r;
          if (r1 < r) r = r1;

          return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
        }
      }
    }
  }

  /**
   * Calculate binary logarithm of x.  Return NaN on negative x excluding -0.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function log_2 (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      if (uint128 (x) > 0x80000000000000000000000000000000) return NaN;
      else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; 
      else {
        uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
        if (xExponent == 0x7FFF) return x;
        else {
          uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          if (xExponent == 0) xExponent = 1;
          else xSignifier |= 0x10000000000000000000000000000;

          if (xSignifier == 0) return NEGATIVE_INFINITY;

          bool resultNegative;
          uint256 resultExponent = 16495;
          uint256 resultSignifier;

          if (xExponent >= 0x3FFF) {
            resultNegative = false;
            resultSignifier = xExponent - 0x3FFF;
            xSignifier <<= 15;
          } else {
            resultNegative = true;
            if (xSignifier >= 0x10000000000000000000000000000) {
              resultSignifier = 0x3FFE - xExponent;
              xSignifier <<= 15;
            } else {
              uint256 msb = mostSignificantBit (xSignifier);
              resultSignifier = 16493 - msb;
              xSignifier <<= 127 - msb;
            }
          }

          if (xSignifier == 0x80000000000000000000000000000000) {
            if (resultNegative) resultSignifier += 1;
            uint256 shift = 112 - mostSignificantBit (resultSignifier);
            resultSignifier <<= shift;
            resultExponent -= shift;
          } else {
            uint256 bb = resultNegative ? 1 : 0;
            while (resultSignifier < 0x10000000000000000000000000000) {
              resultSignifier <<= 1;
              resultExponent -= 1;
  
              xSignifier *= xSignifier;
              uint256 b = xSignifier >> 255;
              resultSignifier += b ^ bb;
              xSignifier >>= 127 + b;
            }
          }

          return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) |
              resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
        }
      }
    }
  }

  /**
   * Calculate natural logarithm of x.  Return NaN on negative x excluding -0.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function ln (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      return mul (log_2 (x), 0x3FFE62E42FEFA39EF35793C7673007E5);
    }
  }

  /**
   * Calculate 2^x.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function pow_2 (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      bool xNegative = uint128 (x) > 0x80000000000000000000000000000000;
      uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
      uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

      if (xExponent == 0x7FFF && xSignifier != 0) return NaN;
      else if (xExponent > 16397)
        return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY;
      else if (xExponent < 16255)
        return 0x3FFF0000000000000000000000000000;
      else {
        if (xExponent == 0) xExponent = 1;
        else xSignifier |= 0x10000000000000000000000000000;

        if (xExponent > 16367)
          xSignifier <<= xExponent - 16367;
        else if (xExponent < 16367)
          xSignifier >>= 16367 - xExponent;

        if (xNegative && xSignifier > 0x406E00000000000000000000000000000000)
          return POSITIVE_ZERO;

        if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
          return POSITIVE_INFINITY;

        uint256 resultExponent = xSignifier >> 128;
        xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        if (xNegative && xSignifier != 0) {
          xSignifier = ~xSignifier;
          resultExponent += 1;
        }

        uint256 resultSignifier = 0x80000000000000000000000000000000;
        if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128;
        if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128;
        if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128;
        if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128;
        if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128;
        if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128;
        if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128;
        if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128;
        if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128;
        if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128;
        if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128;
        if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128;
        if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128;
        if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128;
        if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128;
        if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128;
        if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128;
        if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128;
        if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128;
        if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128;
        if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128;
        if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128;
        if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128;
        if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128;
        if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128;
        if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128;
        if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128;
        if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128;
        if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128;
        if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128;
        if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128;
        if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128;
        if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128;
        if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128;
        if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128;
        if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128;
        if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128;
        if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128;
        if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128;
        if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128;
        if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128;
        if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128;
        if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128;
        if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128;
        if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128;
        if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128;
        if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128;
        if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128;
        if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128;
        if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128;
        if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128;
        if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128;
        if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128;
        if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128;
        if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128;
        if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128;
        if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128;
        if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128;
        if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128;
        if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128;
        if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128;
        if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128;
        if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128;
        if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128;
        if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128;
        if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128;
        if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128;
        if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128;
        if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128;
        if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128;
        if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128;
        if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128;
        if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128;
        if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128;
        if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128;
        if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128;
        if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128;
        if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128;
        if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128;
        if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128;
        if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128;
        if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128;
        if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128;
        if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128;
        if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128;
        if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128;
        if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128;
        if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128;
        if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128;
        if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128;
        if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128;
        if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128;
        if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128;
        if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128;
        if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128;
        if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128;
        if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128;
        if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128;
        if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128;
        if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128;
        if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128;
        if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128;
        if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128;
        if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128;
        if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128;
        if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128;
        if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128;
        if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128;
        if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128;
        if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128;
        if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128;
        if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128;
        if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128;
        if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128;
        if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128;
        if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128;
        if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128;
        if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128;
        if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128;
        if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128;
        if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128;
        if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128;
        if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128;
        if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128;
        if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128;
        if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128;

        if (!xNegative) {
          resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          resultExponent += 0x3FFF;
        } else if (resultExponent <= 0x3FFE) {
          resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
          resultExponent = 0x3FFF - resultExponent;
        } else {
          resultSignifier = resultSignifier >> resultExponent - 16367;
          resultExponent = 0;
        }

        return bytes16 (uint128 (resultExponent << 112 | resultSignifier));
      }
    }
  }

  /**
   * Calculate e^x.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function exp (bytes16 x) internal pure returns (bytes16) {
    unchecked {
      return pow_2 (mul (x, 0x3FFF71547652B82FE1777D0FFDA0D23A));
    }
  }

  /**
   * Get index of the most significant non-zero bit in binary representation of
   * x.  Reverts if x is zero.
   *
   * @return index of the most significant non-zero bit in binary representation
   *         of x
   */
  function mostSignificantBit (uint256 x) private pure returns (uint256) {
    unchecked {
      require (x > 0);

      uint256 result = 0;

      if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; }
      if (x >= 0x10000000000000000) { x >>= 64; result += 64; }
      if (x >= 0x100000000) { x >>= 32; result += 32; }
      if (x >= 0x10000) { x >>= 16; result += 16; }
      if (x >= 0x100) { x >>= 8; result += 8; }
      if (x >= 0x10) { x >>= 4; result += 4; }
      if (x >= 0x4) { x >>= 2; result += 2; }
      if (x >= 0x2) result += 1; // No need to shift x anymore

      return result;
    }
  }
}

contract HashCatFarming is ERC20 {
    
    using SafeERC20 for IERC20;
    using SafeMath for uint256;
    using ABDKMathQuad for uint256;
    using ABDKMathQuad for bytes16;
    
    address private farmManager;
    address private HashCatTokenAddress;
    address private HashCatTokenAddressLP;
    address private HashCatTokenFeesAddress;
    
    IERC20 private HashCatToken;
    IERC20 private HashCatTokenLP;
    IERC20 private HashCatTokenFees;
    
    uint256 private farmingDifficulty;
    uint256 private farmingDifficultyLP;
    uint256 private _HashCatStaked;
    uint256 private _HashCatStakedLP;
    
    uint256 private _AvailableInjectedTokens;
    uint256 private _TotalShares;
    uint256 private _LastInjectionTimeStamp;
    uint256 private _LastInjectionAmount;
    
    struct UserTracker{
        uint256 HashCatStaked;
        uint256 rewards; //shares
        uint256 lastBlockChecked;
        uint256 HashCatStakedLP;
        uint256 rewardsLP; //shares
        uint256 lastBlockCheckedLP;
    }
    
    mapping(address => UserTracker) private _stakedBalances;
    
    constructor() payable ERC20("HashCat.farm", "HASH") {
        farmManager = msg.sender;
        farmingDifficulty = 10000;
        farmingDifficultyLP = 500;
        
        HashCatTokenAddress = 0xca1AA93724be5F7459D76c6DE984D22C9fBcB7Aa;
        HashCatTokenAddressLP = 0x1b8724c8b329D3AB2D11bC1e8Cf41F86bC4Cac97;
        HashCatTokenFeesAddress = 0xAF76FDe958E4FF47fc7b1b9FD116dBDF405930b2;
        
        HashCatToken = IERC20(0xca1AA93724be5F7459D76c6DE984D22C9fBcB7Aa);
        HashCatTokenLP = IERC20(0x1b8724c8b329D3AB2D11bC1e8Cf41F86bC4Cac97);
        HashCatTokenFees = IERC20(0xAF76FDe958E4FF47fc7b1b9FD116dBDF405930b2);
    }
    
    modifier _isFarmManager() {
        require(msg.sender == farmManager, "Only the Farm Manager can interact with this function.");_;
    }
    
    event Staked(address indexed user, uint256 amount, uint256 HashCatStaked);
    event StakedLP(address indexed user, uint256 amount, uint256 HashCatStakedLP);
    event Withdrawn(address indexed user, uint256 amount);
    event WithdrawnLP(address indexed user, uint256 amount);
    event Rewards(address indexed user, uint256 reward);
    event RewardsLP(address indexed user, uint256 reward);
    event Inject(address indexed user, uint256 amount);
    
    modifier bfUpdateStakingReward(address account) {
        updatingStakingReward(account);
        _;
    }

    modifier bfUpdateStakingRewardLP(address account) {
        updatingStakingRewardLP(account);
        _;
    }
    
    function updatingStakingReward(address account) public returns(uint256) {
        if (block.number > _stakedBalances[account].lastBlockChecked) {
            uint256 rewardBlocks = block.number.sub(_stakedBalances[account].lastBlockChecked);
            if (_stakedBalances[account].HashCatStaked > 0) {
                uint256 shares = _stakedBalances[account].HashCatStaked.mul(rewardBlocks).div(farmingDifficulty);
                _stakedBalances[account].rewards = _stakedBalances[account].rewards.add(shares);
                _TotalShares = _TotalShares.add(shares);
            }
            _stakedBalances[account].lastBlockChecked = block.number;
            emit Rewards(account, _stakedBalances[account].rewards);                                                     
        }
        return(_stakedBalances[account].rewards);
    }
    
    function updatingStakingRewardLP(address account) public returns(uint256) {
        if (block.number > _stakedBalances[account].lastBlockCheckedLP) {
            uint256 rewardBlocksLP = block.number.sub(_stakedBalances[account].lastBlockCheckedLP);
            if (_stakedBalances[account].HashCatStakedLP > 0) {
                uint256 sharesLP = _stakedBalances[account].HashCatStakedLP.mul(rewardBlocksLP).div(farmingDifficultyLP);
                _stakedBalances[account].rewardsLP = _stakedBalances[account].rewardsLP.add(sharesLP);
                _TotalShares = _TotalShares.add(sharesLP);
            }
            _stakedBalances[account].lastBlockCheckedLP = block.number;
            emit RewardsLP(account, _stakedBalances[account].rewardsLP);                                                     
        }
        return(_stakedBalances[account].rewardsLP);
    }
    
    //Below GET Functions listed
    
    function getBlockHeight() public view returns(uint256){
        return block.number;
    }
    
    function getLastBlockCheckedForAccount(address _account) public view returns (uint256) {
        return _stakedBalances[_account].lastBlockChecked;
    }
    
    function getLastBlockCheckedForAccountLP(address _account) public view returns (uint256) {
        return _stakedBalances[_account].lastBlockCheckedLP;
    }

    function getAccountStakeAmount(address _account) public view returns (uint256) {
        return _stakedBalances[_account].HashCatStaked;
    }
    
    function getAccountStakeAmountLP(address _account) public view returns (uint256) {
        return _stakedBalances[_account].HashCatStakedLP;
    }
    
    function getStakedTokens() public view returns (uint256) {
        return _HashCatStaked;
    }
    
    function getStakedTokensLP() public view returns (uint256) {
        return _HashCatStakedLP;
    }
    
    function getFarmingDifficulty() public view returns(uint256){
        return farmingDifficulty;
    }
    
    function getFarmingDifficultyLP() public view returns(uint256){
        return farmingDifficultyLP;
    }
    
    function getAvailableInjectedTokens() public view returns(uint256){
        return _AvailableInjectedTokens;
    }
    
    function getTotalShares() public view returns(uint256){
        return _TotalShares;
    }
    
    function getLastInjectionTimeStamp() public view returns(uint256){
        return _LastInjectionTimeStamp;
    }
    
    function getLastInjectionAmount() public view returns(uint256){
        return _LastInjectionAmount;
    }
    
    function getAccountRewards(address account) public view returns (uint256) {
        if (block.number > _stakedBalances[account].lastBlockChecked) {
            uint256 rewardBlocks = block.number.sub(_stakedBalances[account].lastBlockChecked);
            if (_stakedBalances[account].HashCatStaked > 0) {
                return _stakedBalances[account].rewards.add(_stakedBalances[account].HashCatStaked.mul(rewardBlocks).div(farmingDifficulty));
            }
        }
        return 0;
    }
    
    function getAccountRewardsLP(address account) public view returns (uint256) {
        if (block.number > _stakedBalances[account].lastBlockCheckedLP) {
            uint256 rewardBlocksLP = block.number.sub(_stakedBalances[account].lastBlockCheckedLP);
            if (_stakedBalances[account].HashCatStakedLP > 0) {
                return _stakedBalances[account].rewardsLP.add(_stakedBalances[account].HashCatStakedLP.mul(rewardBlocksLP).div(farmingDifficultyLP));
            }
        }
        return 0;
    }
    
    function stake(uint256 amount) public bfUpdateStakingReward(msg.sender) {
        _HashCatStaked = _HashCatStaked.add(amount);
        _stakedBalances[msg.sender].HashCatStaked = _stakedBalances[msg.sender].HashCatStaked.add(amount);
        HashCatToken.safeTransferFrom(msg.sender, address(this), amount);
        emit Staked(msg.sender, amount, _HashCatStaked);
    }
    
    function stakeLP(uint256 amount) public bfUpdateStakingRewardLP(msg.sender) {
        _HashCatStakedLP = _HashCatStakedLP.add(amount);
        _stakedBalances[msg.sender].HashCatStakedLP = _stakedBalances[msg.sender].HashCatStakedLP.add(amount);
        HashCatTokenLP.safeTransferFrom(msg.sender, address(this), amount);
        emit StakedLP(msg.sender, amount, _HashCatStakedLP);
    }
    
    function inject(uint256 amount) public _isFarmManager {
        uint256 toCurrentContract = amount.mul(8).div(10);
        uint256 toFeesContract = amount.mul(2).div(10);
        _AvailableInjectedTokens = _AvailableInjectedTokens.add(toCurrentContract);
        _LastInjectionAmount = toCurrentContract;
        _LastInjectionTimeStamp = block.timestamp;
        HashCatToken.safeTransferFrom(msg.sender, address(this), toCurrentContract);
        HashCatToken.safeTransferFrom(msg.sender, HashCatTokenFeesAddress, toFeesContract);
        emit Inject(msg.sender, amount);
    }
    
    function withdraw(uint256 amount) public bfUpdateStakingReward(msg.sender) {
        _HashCatStaked = _HashCatStaked.sub(amount);
        _stakedBalances[msg.sender].HashCatStaked = _stakedBalances[msg.sender].HashCatStaked.sub(amount);
        HashCatToken.safeTransfer(msg.sender, amount);
        emit Withdrawn(msg.sender, amount);
    }
    
    function withdrawLP(uint256 amount) public bfUpdateStakingRewardLP(msg.sender) {
        _HashCatStakedLP = _HashCatStakedLP.sub(amount);
        _stakedBalances[msg.sender].HashCatStakedLP = _stakedBalances[msg.sender].HashCatStakedLP.sub(amount);
        HashCatTokenLP.safeTransfer(msg.sender, amount);
        emit WithdrawnLP(msg.sender, amount);
    }
    

    function getEligibilityNumber() public view returns(uint256){
        bytes16 shares = _getEligibilityNumberMultiplier();
        return shares.mul(_AvailableInjectedTokens.fromUInt()).toUInt();
    }
    
    function getEligibilityPercentage() public view returns(uint256){
        return _getEligibilityNumberMultiplier().mul(ABDKMathQuad.fromUInt(100)).toUInt();
    }
    
    function _getEligibilityNumberMultiplier() public view returns(bytes16) {
        bytes16 shares = _TotalShares.fromUInt();
        bytes16 rewards = _stakedBalances[msg.sender].rewards.fromUInt();
        return rewards.div(shares);
    }

    function getEligibilityNumberLP() public view returns(uint256){
        bytes16 shares = _getEligibilityNumberMultiplierLP();
        return shares.mul(_AvailableInjectedTokens.fromUInt()).toUInt();
    }
    
    function getEligibilityPercentageLP() public view returns(uint256){
        return _getEligibilityNumberMultiplierLP().mul(ABDKMathQuad.fromUInt(100)).toUInt();
    }

    function _getEligibilityNumberMultiplierLP() public view returns(bytes16) {
        bytes16 shares = _TotalShares.fromUInt();
        bytes16 rewards = _stakedBalances[msg.sender].rewardsLP.fromUInt();
        return rewards.div(shares);
    }
    
    function getReward() public bfUpdateStakingReward(msg.sender) {
        uint256 number = getEligibilityNumber();
        _TotalShares = _TotalShares.sub(_stakedBalances[msg.sender].rewards);
        _AvailableInjectedTokens = _AvailableInjectedTokens.sub(number);
        _stakedBalances[msg.sender].rewards = 0;
        HashCatToken.safeTransfer(msg.sender, number);
    }
    
    function getRewardLP() public bfUpdateStakingRewardLP(msg.sender) {
        uint256 numberLP = getEligibilityNumberLP();
        _TotalShares = _TotalShares.sub(_stakedBalances[msg.sender].rewardsLP);
        _AvailableInjectedTokens = _AvailableInjectedTokens.sub(numberLP);
        _stakedBalances[msg.sender].rewardsLP = 0;
        HashCatToken.safeTransfer(msg.sender, numberLP);
    }
    
    //Below SET Functions listed
    
    function setFarmingDifficulty(uint256 _amount) public _isFarmManager{
        farmingDifficulty = _amount;
    }
    
    function setFarmingDifficultyLP(uint256 _amount) public _isFarmManager {
        farmingDifficultyLP = _amount;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Inject","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Rewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardsLP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"HashCatStaked","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"HashCatStakedLP","type":"uint256"}],"name":"StakedLP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawnLP","type":"event"},{"inputs":[],"name":"_getEligibilityNumberMultiplier","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_getEligibilityNumberMultiplierLP","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountRewardsLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getAccountStakeAmountLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAvailableInjectedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEligibilityNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEligibilityNumberLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEligibilityPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEligibilityPercentageLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFarmingDifficulty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFarmingDifficultyLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getLastBlockCheckedForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getLastBlockCheckedForAccountLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastInjectionAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastInjectionTimeStamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getStakedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakedTokensLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"inject","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setFarmingDifficulty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setFarmingDifficultyLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakeLP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"updatingStakingReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"updatingStakingRewardLP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLP","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526040518060400160405280600c81526020017f486173684361742e6661726d00000000000000000000000000000000000000008152506040518060400160405280600481526020017f4841534800000000000000000000000000000000000000000000000000000000815250816003908051906020019062000088929190620002fb565b508060049080519060200190620000a1929190620002fb565b50505033600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612710600c819055506101f4600d8190555073ca1aa93724be5f7459d76c6de984d22c9fbcb7aa600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550731b8724c8b329d3ab2d11bc1e8cf41f86bc4cac97600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073af76fde958e4ff47fc7b1b9fd116dbdf405930b2600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073ca1aa93724be5f7459d76c6de984d22c9fbcb7aa600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550731b8724c8b329d3ab2d11bc1e8cf41f86bc4cac97600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073af76fde958e4ff47fc7b1b9fd116dbdf405930b2600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000410565b8280546200030990620003ab565b90600052602060002090601f0160209004810192826200032d576000855562000379565b82601f106200034857805160ff191683800117855562000379565b8280016001018555821562000379579182015b82811115620003785782518255916020019190600101906200035b565b5b5090506200038891906200038c565b5090565b5b80821115620003a75760008160009055506001016200038d565b5090565b60006002820490506001821680620003c457607f821691505b60208210811415620003db57620003da620003e1565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6146db80620004206000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80635ea074da11610151578063b5d5406e116100c3578063dd62ed3e11610087578063dd62ed3e14610792578063ddf2f99a146107c2578063e295501a146107f2578063e4456ecb146107fc578063e5da2cb214610818578063f68f163f1461083457610269565b8063b5d5406e146106ec578063b773bdc51461071c578063b872a0d01461073a578063bdd1292014610758578063d5002f2e1461077457610269565b80639ee7bfec116101155780639ee7bfec14610604578063a457c2d714610622578063a694fc3a14610652578063a853bc861461066e578063a9059cbb1461069e578063aa5d25e5146106ce57610269565b80635ea074da1461054a57806370a08231146105685780637bb96acb14610598578063806041bd146105b657806395d89b41146105e657610269565b806323b872dd116101ea5780633e131322116101ae5780633e131322146104725780633fe77b4d14610490578063440d39a0146104c0578063489050fd146104de5780634aa12ec7146104fc5780635914bd1b1461052c57610269565b806323b872dd146103ce5780632e1a7d4d146103fe578063313ce5671461041a57806339509351146104385780633d18b9121461046857610269565b806313c0a8e21161023157806313c0a8e21461031657806318160ddd146103465780631820433f1461036457806319c838ee1461038057806322d3dd5e146103b057610269565b806301bd24b11461026e57806306fdde031461028c578063095ea7b3146102aa5780630e469a7c146102da5780630f0c1545146102f8575b600080fd5b610276610850565b6040516102839190614336565b60405180910390f35b61029461085a565b6040516102a191906141b4565b60405180910390f35b6102c460048036038101906102bf9190613b88565b6108ec565b6040516102d1919061417e565b60405180910390f35b6102e261090a565b6040516102ef9190614336565b60405180910390f35b610300610914565b60405161030d9190614336565b60405180910390f35b610330600480360381019061032b9190613ad4565b61091e565b60405161033d9190614336565b60405180910390f35b61034e610c56565b60405161035b9190614336565b60405180910390f35b61037e60048036038101906103799190613bed565b610c60565b005b61039a60048036038101906103959190613ad4565b610e82565b6040516103a79190614336565b60405180910390f35b6103b8611043565b6040516103c59190614336565b60405180910390f35b6103e860048036038101906103e39190613b39565b61104d565b6040516103f5919061417e565b60405180910390f35b61041860048036038101906104139190613bed565b61114e565b005b6104226112ae565b60405161042f919061437a565b60405180910390f35b610452600480360381019061044d9190613b88565b6112b7565b60405161045f919061417e565b60405180910390f35b610470611363565b005b61047a61148b565b6040516104879190614336565b60405180910390f35b6104aa60048036038101906104a59190613ad4565b6114e9565b6040516104b79190614336565b60405180910390f35b6104c8611535565b6040516104d59190614336565b60405180910390f35b6104e661158d565b6040516104f39190614336565b60405180910390f35b61051660048036038101906105119190613ad4565b611597565b6040516105239190614336565b60405180910390f35b6105346118cf565b6040516105419190614336565b60405180910390f35b6105526118d9565b60405161055f9190614199565b60405180910390f35b610582600480360381019061057d9190613ad4565b611965565b60405161058f9190614336565b60405180910390f35b6105a06119ad565b6040516105ad9190614336565b60405180910390f35b6105d060048036038101906105cb9190613ad4565b6119b5565b6040516105dd9190614336565b60405180910390f35b6105ee611a01565b6040516105fb91906141b4565b60405180910390f35b61060c611a93565b6040516106199190614336565b60405180910390f35b61063c60048036038101906106379190613b88565b611aeb565b604051610649919061417e565b60405180910390f35b61066c60048036038101906106679190613bed565b611bdf565b005b61068860048036038101906106839190613ad4565b611d45565b6040516106959190614336565b60405180910390f35b6106b860048036038101906106b39190613b88565b611d91565b6040516106c5919061417e565b60405180910390f35b6106d6611daf565b6040516106e39190614336565b60405180910390f35b61070660048036038101906107019190613ad4565b611e0d565b6040516107139190614336565b60405180910390f35b610724611e59565b6040516107319190614336565b60405180910390f35b610742611e63565b60405161074f9190614199565b60405180910390f35b610772600480360381019061076d9190613bed565b611eef565b005b61077c611f89565b6040516107899190614336565b60405180910390f35b6107ac60048036038101906107a79190613afd565b611f93565b6040516107b99190614336565b60405180910390f35b6107dc60048036038101906107d79190613ad4565b61201a565b6040516107e99190614336565b60405180910390f35b6107fa6121db565b005b61081660048036038101906108119190613bed565b612303565b005b610832600480360381019061082d9190613bed565b612463565b005b61084e60048036038101906108499190613bed565b6125c9565b005b6000601054905090565b60606003805461086990614590565b80601f016020809104026020016040519081016040528092919081815260200182805461089590614590565b80156108e25780601f106108b7576101008083540402835291602001916108e2565b820191906000526020600020905b8154815290600101906020018083116108c557829003601f168201915b5050505050905090565b60006109006108f9612663565b848461266b565b6001905092915050565b6000600e54905090565b6000600f54905090565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050154431115610c0c5760006109c1601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600501544361283690919063ffffffff16565b90506000601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301541115610b33576000610a79600d54610a6b84601460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015461284c90919063ffffffff16565b61286290919063ffffffff16565b9050610ad081601460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015461287890919063ffffffff16565b601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040181905550610b2b8160115461287890919063ffffffff16565b601181905550505b43601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600501819055508273ffffffffffffffffffffffffffffffffffffffff167f995f5ace624567098ab4d5095755db78dba750bef7f45680431477dad9dadec7601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040154604051610c029190614336565b60405180910390a2505b601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600401549050919050565b6000600254905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce790614256565b60405180910390fd5b6000610d19600a610d0b60088561284c90919063ffffffff16565b61286290919063ffffffff16565b90506000610d44600a610d3660028661284c90919063ffffffff16565b61286290919063ffffffff16565b9050610d5b8260105461287890919063ffffffff16565b6010819055508160138190555042601281905550610dbe333084600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661288e909392919063ffffffff16565b610e2f33600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661288e909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f97f6b41fdc62f291faeeff2e152ee0015951049df0909f4e503bfd02be66a6f584604051610e759190614336565b60405180910390a2505050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020154431115611039576000610f25601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201544361283690919063ffffffff16565b90506000601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015411156110375761102f610fde600c54610fd084601460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461284c90919063ffffffff16565b61286290919063ffffffff16565b601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015461287890919063ffffffff16565b91505061103e565b505b600090505b919050565b6000600c54905090565b600061105a848484612917565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006110a5612663565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611125576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111c90614276565b60405180910390fd5b61114285611131612663565b858461113d91906144a8565b61266b565b60019150509392505050565b3361115881611597565b5061116e82600e5461283690919063ffffffff16565b600e819055506111c982601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461283690919063ffffffff16565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555061125c3383600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612b969092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5836040516112a29190614336565b60405180910390a25050565b60006012905090565b60006113596112c4612663565b8484600160006112d2612663565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461135491906143c7565b61266b565b6001905092915050565b3361136d81611597565b506000611378611daf565b90506113d1601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015460115461283690919063ffffffff16565b6011819055506113ec8160105461283690919063ffffffff16565b6010819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506114873382600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612b969092919063ffffffff16565b5050565b6000806114966118d9565b90506114e36114cb6114a9601054612c1c565b836fffffffffffffffffffffffffffffffff1916612c9a90919063ffffffff16565b6fffffffffffffffffffffffffffffffff191661312f565b91505090565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600501549050919050565b60006115886115706115476064612c1c565b61154f6118d9565b6fffffffffffffffffffffffffffffffff1916612c9a90919063ffffffff16565b6fffffffffffffffffffffffffffffffff191661312f565b905090565b6000601254905090565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002015443111561188557600061163a601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201544361283690919063ffffffff16565b90506000601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015411156117ac5760006116f2600c546116e484601460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461284c90919063ffffffff16565b61286290919063ffffffff16565b905061174981601460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015461287890919063ffffffff16565b601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506117a48160115461287890919063ffffffff16565b601181905550505b43601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201819055508273ffffffffffffffffffffffffffffffffffffffff167fc083a1647e3ee591bf42b82564ffb4d16fdbb26068f0080da911c8d8300fd84a601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015460405161187b9190614336565b60405180910390a2505b601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b6000600d54905090565b6000806118e7601154612c1c565b90506000611936601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040154612c1c565b905061195e82826fffffffffffffffffffffffffffffffff191661322d90919063ffffffff16565b9250505090565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600043905090565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050919050565b606060048054611a1090614590565b80601f0160208091040260200160405190810160405280929190818152602001828054611a3c90614590565b8015611a895780601f10611a5e57610100808354040283529160200191611a89565b820191906000526020600020905b815481529060010190602001808311611a6c57829003601f168201915b5050505050905090565b6000611ae6611ace611aa56064612c1c565b611aad611e63565b6fffffffffffffffffffffffffffffffff1916612c9a90919063ffffffff16565b6fffffffffffffffffffffffffffffffff191661312f565b905090565b60008060016000611afa612663565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611bb7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bae90614316565b60405180910390fd5b611bd4611bc2612663565b858584611bcf91906144a8565b61266b565b600191505092915050565b33611be981611597565b50611bff82600e5461287890919063ffffffff16565b600e81905550611c5a82601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461287890919063ffffffff16565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550611cef333084600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661288e909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f1449c6dd7851abc30abf37f57715f492010519147cc2652fbc38202c18a6ee9083600e54604051611d39929190614351565b60405180910390a25050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600201549050919050565b6000611da5611d9e612663565b8484612917565b6001905092915050565b600080611dba611e63565b9050611e07611def611dcd601054612c1c565b836fffffffffffffffffffffffffffffffff1916612c9a90919063ffffffff16565b6fffffffffffffffffffffffffffffffff191661312f565b91505090565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301549050919050565b6000601354905090565b600080611e71601154612c1c565b90506000611ec0601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154612c1c565b9050611ee882826fffffffffffffffffffffffffffffffff191661322d90919063ffffffff16565b9250505090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7690614256565b60405180910390fd5b80600c8190555050565b6000601154905090565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600501544311156121d15760006120bd601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600501544361283690919063ffffffff16565b90506000601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015411156121cf576121c7612176600d5461216884601460008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015461284c90919063ffffffff16565b61286290919063ffffffff16565b601460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015461287890919063ffffffff16565b9150506121d6565b505b600090505b919050565b336121e58161091e565b5060006121f061148b565b9050612249601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015460115461283690919063ffffffff16565b6011819055506122648160105461283690919063ffffffff16565b6010819055506000601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600401819055506122ff3382600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612b969092919063ffffffff16565b5050565b3361230d8161091e565b5061232382600f5461283690919063ffffffff16565b600f8190555061237e82601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015461283690919063ffffffff16565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301819055506124113383600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16612b969092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fb9242cc3bd25e29580e62b0ff5fd134d37aaeaa59556787cb5a8dda08852e176836040516124579190614336565b60405180910390a25050565b3361246d8161091e565b5061248382600f5461287890919063ffffffff16565b600f819055506124de82601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206003015461287890919063ffffffff16565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030181905550612573333084600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661288e909392919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fb7b233b6521c7f0372a87c02ad816107c5cbe56f7a82c3607d13bb14579fa05d83600f546040516125bd929190614351565b60405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612659576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265090614256565b60405180910390fd5b80600d8190555050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d2906142b6565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561274b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612742906141f6565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516128299190614336565b60405180910390a3505050565b6000818361284491906144a8565b905092915050565b6000818361285a919061444e565b905092915050565b60008183612870919061441d565b905092915050565b6000818361288691906143c7565b905092915050565b612911846323b872dd60e01b8585856040516024016128af9392919061411e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613742565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612987576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297e90614296565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156129f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ee906141d6565b60405180910390fd5b612a02838383613809565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015612a88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a7f90614216565b60405180910390fd5b8181612a9491906144a8565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612b2491906143c7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612b889190614336565b60405180910390a350505050565b612c178363a9059cbb60e01b8484604051602401612bb5929190614155565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613742565b505050565b600080821415612c3257600060801b9050612c95565b60008290506000612c428261380e565b90506070811015612c5b578060700382901b9150612c6f565b6070811115612c6e576070810382901c91505b5b607081613fff01901b6dffffffffffffffffffffffffffff83161791508160801b925050505b919050565b600080617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff1690506000617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050617fff821415612e3157617fff811415612dbf57836fffffffffffffffffffffffffffffffff1916856fffffffffffffffffffffffffffffffff19161415612d66576f8000000000000000000000000000000060801b8416851892505050613129565b6f8000000000000000000000000000000060801b8486186fffffffffffffffffffffffffffffffff19161415612da25783851792505050613129565b6f7fff800000000000000000000000000060801b92505050613129565b600060801b6f7fffffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff19161415612e10576f7fff800000000000000000000000000060801b92505050613129565b6f8000000000000000000000000000000060801b8416851892505050613129565b617fff811415612ead57600060801b6f7fffffffffffffffffffffffffffffff60801b86166fffffffffffffffffffffffffffffffff19161415612e8c576f7fff800000000000000000000000000060801b92505050613129565b6f8000000000000000000000000000000060801b8516841892505050613129565b60006dffffffffffffffffffffffffffff8660801c166fffffffffffffffffffffffffffffffff1690506000831415612ee95760019250612efe565b6e010000000000000000000000000000811790505b60006dffffffffffffffffffffffffffff8660801c166fffffffffffffffffffffffffffffffff1690506000831415612f3a5760019250612f4f565b6e010000000000000000000000000000811790505b80820291506000821415612fbc57600060801b6f8000000000000000000000000000000060801b878918166fffffffffffffffffffffffffffffffff191611612f9c57600060801b612fb1565b6f8000000000000000000000000000000060801b5b945050505050613129565b828401935060007c0200000000000000000000000000000000000000000000000000000000831015613023577c010000000000000000000000000000000000000000000000000000000083101561301b576130168361380e565b61301e565b60e05b613026565b60e15b905061407081860110156130415760009450600092506130e9565b6140e081860110156130855761407085101561306657846140700383901c925061307c565b61407085111561307b57614070850383901b92505b5b600094506130e8565b61c0dd818601111561309f57617fff9450600092506130e7565b60708111156130b6576070810383901c92506130ca565b60708110156130c9578060700383901b92505b5b6dffffffffffffffffffffffffffff831692506140df8186010394505b5b5b82607086901b6f8000000000000000000000000000000060801b898b181660801c6fffffffffffffffffffffffffffffffff16171760801b955050505050505b92915050565b600080617fff60708460801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050613fff811015613178576000915050613228565b6f800000000000000000000000000000008360801c6fffffffffffffffffffffffffffffffff16106131a957600080fd5b6140fe8111156131b857600080fd5b60006e0100000000000000000000000000006dffffffffffffffffffffffffffff8560801c6fffffffffffffffffffffffffffffffff161617905061406f82101561320c578161406f0381901c9050613222565b61406f8211156132215761406f820381901b90505b5b80925050505b919050565b600080617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff1690506000617fff60708560801c6fffffffffffffffffffffffffffffffff16901c166fffffffffffffffffffffffffffffffff169050617fff8214156132e857617fff8114156132c7576f7fff800000000000000000000000000060801b9250505061373c565b6f8000000000000000000000000000000060801b841685189250505061373c565b617fff81141561336757600060801b6dffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff191614613340576f7fff800000000000000000000000000060801b9250505061373c565b6f8000000000000000000000000000000060801b84861816600060801b179250505061373c565b600060801b6f7fffffffffffffffffffffffffffffff60801b85166fffffffffffffffffffffffffffffffff1916141561342257600060801b6f7fffffffffffffffffffffffffffffff60801b86166fffffffffffffffffffffffffffffffff191614156133ec576f7fff800000000000000000000000000060801b9250505061373c565b6f8000000000000000000000000000000060801b848618166f7fff000000000000000000000000000060801b179250505061373c565b60006dffffffffffffffffffffffffffff8560801c166fffffffffffffffffffffffffffffffff169050600082141561345e5760019150613473565b6e010000000000000000000000000000811790505b60006dffffffffffffffffffffffffffff8760801c166fffffffffffffffffffffffffffffffff16905060008414156134d757600081146134d25760006134b98261380e565b60e20390508082901b9150600194506072810384019350505b6134f0565b60726e0100000000000000000000000000008217901b90505b818181613526577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b049050600081141561359157600060801b6f8000000000000000000000000000000060801b878918166fffffffffffffffffffffffffffffffff19161161357157600060801b613586565b6f8000000000000000000000000000000060801b5b94505050505061373c565b6d10000000000000000000000000008110156135d6577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60006e080000000000000000000000000000821015613637576e04000000000000000000000000000082101561362c576e020000000000000000000000000000821015613624576070613627565b60715b61362f565b60725b60ff16613641565b6136408261380e565b5b90506140718401818601111561365f57617fff9450600091506136fc565b83613ffc82870101101561367a5760009450600091506136fb565b83613f8c8287010110156136c85783613ffc860111156136a55783613ffc86010382901b91506136bf565b83613ffc860110156136be57613ffc8585030382901c91505b5b600094506136fa565b60708111156136db576070810382901c91505b6dffffffffffffffffffffffffffff8216915083613f8d828701010394505b5b5b81607086901b6f8000000000000000000000000000000060801b898b181660801c6fffffffffffffffffffffffffffffffff16171760801b955050505050505b92915050565b60006137a4826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138ef9092919063ffffffff16565b905060008151111561380457808060200190518101906137c49190613bc4565b613803576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137fa906142f6565b60405180910390fd5b5b505050565b505050565b600080821161381c57600080fd5b6000700100000000000000000000000000000000831061384457608083901c92506080810190505b68010000000000000000831061386257604083901c92506040810190505b640100000000831061387c57602083901c92506020810190505b62010000831061389457601083901c92506010810190505b61010083106138ab57600883901c92506008810190505b601083106138c157600483901c92506004810190505b600483106138d757600283901c92506002810190505b600283106138e6576001810190505b80915050919050565b60606138fe8484600085613907565b90509392505050565b60608247101561394c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161394390614236565b60405180910390fd5b61395585613a1b565b613994576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398b906142d6565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516139bd9190614107565b60006040518083038185875af1925050503d80600081146139fa576040519150601f19603f3d011682016040523d82523d6000602084013e6139ff565b606091505b5091509150613a0f828286613a2e565b92505050949350505050565b600080823b905060008111915050919050565b60608315613a3e57829050613a8e565b600083511115613a515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a8591906141b4565b60405180910390fd5b9392505050565b600081359050613aa481614660565b92915050565b600081519050613ab981614677565b92915050565b600081359050613ace8161468e565b92915050565b600060208284031215613ae657600080fd5b6000613af484828501613a95565b91505092915050565b60008060408385031215613b1057600080fd5b6000613b1e85828601613a95565b9250506020613b2f85828601613a95565b9150509250929050565b600080600060608486031215613b4e57600080fd5b6000613b5c86828701613a95565b9350506020613b6d86828701613a95565b9250506040613b7e86828701613abf565b9150509250925092565b60008060408385031215613b9b57600080fd5b6000613ba985828601613a95565b9250506020613bba85828601613abf565b9150509250929050565b600060208284031215613bd657600080fd5b6000613be484828501613aaa565b91505092915050565b600060208284031215613bff57600080fd5b6000613c0d84828501613abf565b91505092915050565b613c1f816144dc565b82525050565b613c2e816144ee565b82525050565b613c3d816144fa565b82525050565b6000613c4e82614395565b613c5881856143ab565b9350613c6881856020860161455d565b80840191505092915050565b6000613c7f826143a0565b613c8981856143b6565b9350613c9981856020860161455d565b613ca28161464f565b840191505092915050565b6000613cba6023836143b6565b91507f45524332303a207472616e7366657220746f20746865207a65726f206164647260008301527f65737300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d206022836143b6565b91507f45524332303a20617070726f766520746f20746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613d866026836143b6565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206260008301527f616c616e636500000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613dec6026836143b6565b91507f416464726573733a20696e73756666696369656e742062616c616e636520666f60008301527f722063616c6c00000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613e526036836143b6565b91507f4f6e6c7920746865204661726d204d616e616765722063616e20696e7465726160008301527f6374207769746820746869732066756e6374696f6e2e000000000000000000006020830152604082019050919050565b6000613eb86028836143b6565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206160008301527f6c6c6f77616e63650000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f1e6025836143b6565b91507f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008301527f64726573730000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613f846024836143b6565b91507f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613fea601d836143b6565b91507f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006000830152602082019050919050565b600061402a602a836143b6565b91507f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008301527f6f742073756363656564000000000000000000000000000000000000000000006020830152604082019050919050565b60006140906025836143b6565b91507f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008301527f207a65726f0000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6140f281614546565b82525050565b61410181614550565b82525050565b60006141138284613c43565b915081905092915050565b60006060820190506141336000830186613c16565b6141406020830185613c16565b61414d60408301846140e9565b949350505050565b600060408201905061416a6000830185613c16565b61417760208301846140e9565b9392505050565b60006020820190506141936000830184613c25565b92915050565b60006020820190506141ae6000830184613c34565b92915050565b600060208201905081810360008301526141ce8184613c74565b905092915050565b600060208201905081810360008301526141ef81613cad565b9050919050565b6000602082019050818103600083015261420f81613d13565b9050919050565b6000602082019050818103600083015261422f81613d79565b9050919050565b6000602082019050818103600083015261424f81613ddf565b9050919050565b6000602082019050818103600083015261426f81613e45565b9050919050565b6000602082019050818103600083015261428f81613eab565b9050919050565b600060208201905081810360008301526142af81613f11565b9050919050565b600060208201905081810360008301526142cf81613f77565b9050919050565b600060208201905081810360008301526142ef81613fdd565b9050919050565b6000602082019050818103600083015261430f8161401d565b9050919050565b6000602082019050818103600083015261432f81614083565b9050919050565b600060208201905061434b60008301846140e9565b92915050565b600060408201905061436660008301856140e9565b61437360208301846140e9565b9392505050565b600060208201905061438f60008301846140f8565b92915050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b60006143d282614546565b91506143dd83614546565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614412576144116145c2565b5b828201905092915050565b600061442882614546565b915061443383614546565b925082614443576144426145f1565b5b828204905092915050565b600061445982614546565b915061446483614546565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561449d5761449c6145c2565b5b828202905092915050565b60006144b382614546565b91506144be83614546565b9250828210156144d1576144d06145c2565b5b828203905092915050565b60006144e782614526565b9050919050565b60008115159050919050565b60007fffffffffffffffffffffffffffffffff0000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561457b578082015181840152602081019050614560565b8381111561458a576000848401525b50505050565b600060028204905060018216806145a857607f821691505b602082108114156145bc576145bb614620565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b614669816144dc565b811461467457600080fd5b50565b614680816144ee565b811461468b57600080fd5b50565b61469781614546565b81146146a257600080fd5b5056fea26469706673582212207ef03349b54f566865a69f3476cf8148e8cf08bf58835059c36cab8c7203077e64736f6c63430008000033

Deployed ByteCode Sourcemap

86298:11711:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91975:116;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6040:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8180:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91519:97;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91628:101;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;89824:889;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7133:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94293:588;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;92453:503;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91741:103;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8831:422;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94893:346;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6984:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9662:215;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96923:379;;;:::i;:::-;;96269:207;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91036:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96488:168;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92207:114;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;88957:855;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91856:107;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96664:247;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7304:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90765:92;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91203:144;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6250:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95842:164;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10380:377;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93501:375;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90869:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7644:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95627:203;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91359:148;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92333:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96018:243;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97761:114;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;92103:92;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7882:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92968:521;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97314:395;;;:::i;:::-;;95251:362;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;93888:393;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;97887:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;91975:116;92033:7;92059:24;;92052:31;;91975:116;:::o;6040:91::-;6085:13;6118:5;6111:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6040:91;:::o;8180:169::-;8263:4;8280:39;8289:12;:10;:12::i;:::-;8303:7;8312:6;8280:8;:39::i;:::-;8337:4;8330:11;;8180:169;;;;:::o;91519:97::-;91567:7;91594:14;;91587:21;;91519:97;:::o;91628:101::-;91678:7;91705:16;;91698:23;;91628:101;:::o;89824:889::-;89889:7;89928:15;:24;89944:7;89928:24;;;;;;;;;;;;;;;:43;;;89913:12;:58;89909:744;;;89988:22;90013:61;90030:15;:24;90046:7;90030:24;;;;;;;;;;;;;;;:43;;;90013:12;:16;;:61;;;;:::i;:::-;89988:86;;90136:1;90093:15;:24;90109:7;90093:24;;;;;;;;;;;;;;;:40;;;:44;90089:353;;;90158:16;90177:85;90242:19;;90177:60;90222:14;90177:15;:24;90193:7;90177:24;;;;;;;;;;;;;;;:40;;;:44;;:60;;;;:::i;:::-;:64;;:85;;;;:::i;:::-;90158:104;;90318:48;90357:8;90318:15;:24;90334:7;90318:24;;;;;;;;;;;;;;;:34;;;:38;;:48;;;;:::i;:::-;90281:15;:24;90297:7;90281:24;;;;;;;;;;;;;;;:34;;:85;;;;90400:26;90417:8;90400:12;;:16;;:26;;;;:::i;:::-;90385:12;:41;;;;90089:353;;90502:12;90456:15;:24;90472:7;90456:24;;;;;;;;;;;;;;;:43;;:58;;;;90544:7;90534:54;;;90553:15;:24;90569:7;90553:24;;;;;;;;;;;;;;;:34;;;90534:54;;;;;;:::i;:::-;;;;;;;;89909:744;;90670:15;:24;90686:7;90670:24;;;;;;;;;;;;;;;:34;;;90663:42;;89824:889;;;:::o;7133:108::-;7194:7;7221:12;;7214:19;;7133:108;:::o;94293:588::-;88156:11;;;;;;;;;;;88142:25;;:10;:25;;;88134:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;94358:25:::1;94386:21;94404:2;94386:13;94397:1;94386:6;:10;;:13;;;;:::i;:::-;:17;;:21;;;;:::i;:::-;94358:49;;94418:22;94443:21;94461:2;94443:13;94454:1;94443:6;:10;;:13;;;;:::i;:::-;:17;;:21;;;;:::i;:::-;94418:46;;94502:47;94531:17;94502:24;;:28;;:47;;;;:::i;:::-;94475:24;:74;;;;94583:17;94560:20;:40;;;;94637:15;94611:23;:41;;;;94663:75;94693:10;94713:4;94720:17;94663:12;;;;;;;;;;;:29;;;;:75;;;;;;:::i;:::-;94749:82;94779:10;94791:23;;;;;;;;;;;94816:14;94749:12;;;;;;;;;;;:29;;;;:82;;;;;;:::i;:::-;94854:10;94847:26;;;94866:6;94847:26;;;;;;:::i;:::-;;;;;;;;88227:1;;94293:588:::0;:::o;92453:503::-;92518:7;92557:15;:24;92573:7;92557:24;;;;;;;;;;;;;;;:41;;;92542:12;:56;92538:392;;;92615:20;92638:59;92655:15;:24;92671:7;92655:24;;;;;;;;;;;;;;;:41;;;92638:12;:16;;:59;;;;:::i;:::-;92615:82;;92757:1;92716:15;:24;92732:7;92716:24;;;;;;;;;;;;;;;:38;;;:42;92712:207;;;92786:117;92823:79;92884:17;;92823:56;92866:12;92823:15;:24;92839:7;92823:24;;;;;;;;;;;;;;;:38;;;:42;;:56;;;;:::i;:::-;:60;;:79;;;;:::i;:::-;92786:15;:24;92802:7;92786:24;;;;;;;;;;;;;;;:32;;;:36;;:117;;;;:::i;:::-;92779:124;;;;;92712:207;92538:392;;92947:1;92940:8;;92453:503;;;;:::o;91741:103::-;91793:7;91819:17;;91812:24;;91741:103;:::o;8831:422::-;8937:4;8954:36;8964:6;8972:9;8983:6;8954:9;:36::i;:::-;9003:24;9030:11;:19;9042:6;9030:19;;;;;;;;;;;;;;;:33;9050:12;:10;:12::i;:::-;9030:33;;;;;;;;;;;;;;;;9003:60;;9102:6;9082:16;:26;;9074:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;9164:57;9173:6;9181:12;:10;:12::i;:::-;9214:6;9195:16;:25;;;;:::i;:::-;9164:8;:57::i;:::-;9241:4;9234:11;;;8831:422;;;;;:::o;94893:346::-;94956:10;88774:30;88796:7;88774:21;:30::i;:::-;;94996:26:::1;95015:6;94996:14;;:18;;:26;;;;:::i;:::-;94979:14;:43;;;;95077:53;95123:6;95077:15;:27;95093:10;95077:27;;;;;;;;;;;;;;;:41;;;:45;;:53;;;;:::i;:::-;95033:15;:27;95049:10;95033:27;;;;;;;;;;;;;;;:41;;:97;;;;95141:45;95167:10;95179:6;95141:12;;;;;;;;;;;:25;;;;:45;;;;;:::i;:::-;95212:10;95202:29;;;95224:6;95202:29;;;;;;:::i;:::-;;;;;;;;94893:346:::0;;:::o;6984:84::-;7033:5;7058:2;7051:9;;6984:84;:::o;9662:215::-;9750:4;9767:80;9776:12;:10;:12::i;:::-;9790:7;9836:10;9799:11;:25;9811:12;:10;:12::i;:::-;9799:25;;;;;;;;;;;;;;;:34;9825:7;9799:34;;;;;;;;;;;;;;;;:47;;;;:::i;:::-;9767:8;:80::i;:::-;9865:4;9858:11;;9662:215;;;;:::o;96923:379::-;96973:10;88774:30;88796:7;88774:21;:30::i;:::-;;96996:14:::1;97013:22;:20;:22::i;:::-;96996:39;;97061:53;97078:15;:27;97094:10;97078:27;;;;;;;;;;;;;;;:35;;;97061:12;;:16;;:53;;;;:::i;:::-;97046:12;:68;;;;97152:36;97181:6;97152:24;;:28;;:36;;;;:::i;:::-;97125:24;:63;;;;97237:1;97199:15;:27;97215:10;97199:27;;;;;;;;;;;;;;;:35;;:39;;;;97249:45;97275:10;97287:6;97249:12;;;;;;;;;;;:25;;;;:45;;;;;:::i;:::-;88815:1;96923:379:::0;:::o;96269:207::-;96323:7;96342:14;96359:35;:33;:35::i;:::-;96342:52;;96412:56;:47;96423:35;:24;;:33;:35::i;:::-;96412:6;:10;;;;;:47;;;;:::i;:::-;:54;;;;:56::i;:::-;96405:63;;;96269:207;:::o;91036:159::-;91116:7;91143:15;:25;91159:8;91143:25;;;;;;;;;;;;;;;:44;;;91136:51;;91036:159;;;:::o;96488:168::-;96546:7;96572:76;:67;96612:26;96634:3;96612:21;:26::i;:::-;96572:35;:33;:35::i;:::-;:39;;;;;:67;;;;:::i;:::-;:74;;;;:76::i;:::-;96565:83;;96488:168;:::o;92207:114::-;92264:7;92290:23;;92283:30;;92207:114;:::o;88957:855::-;89020:7;89059:15;:24;89075:7;89059:24;;;;;;;;;;;;;;;:41;;;89044:12;:56;89040:714;;;89117:20;89140:59;89157:15;:24;89173:7;89157:24;;;;;;;;;;;;;;;:41;;;89140:12;:16;;:59;;;;:::i;:::-;89117:82;;89259:1;89218:15;:24;89234:7;89218:24;;;;;;;;;;;;;;;:38;;;:42;89214:335;;;89281:14;89298:79;89359:17;;89298:56;89341:12;89298:15;:24;89314:7;89298:24;;;;;;;;;;;;;;;:38;;;:42;;:56;;;;:::i;:::-;:60;;:79;;;;:::i;:::-;89281:96;;89431:44;89468:6;89431:15;:24;89447:7;89431:24;;;;;;;;;;;;;;;:32;;;:36;;:44;;;;:::i;:::-;89396:15;:24;89412:7;89396:24;;;;;;;;;;;;;;;:32;;:79;;;;89509:24;89526:6;89509:12;;:16;;:24;;;;:::i;:::-;89494:12;:39;;;;89214:335;;89607:12;89563:15;:24;89579:7;89563:24;;;;;;;;;;;;;;;:41;;:56;;;;89647:7;89639:50;;;89656:15;:24;89672:7;89656:24;;;;;;;;;;;;;;;:32;;;89639:50;;;;;;:::i;:::-;;;;;;;;89040:714;;89771:15;:24;89787:7;89771:24;;;;;;;;;;;;;;;:32;;;89764:40;;88957:855;;;:::o;91856:107::-;91910:7;91936:19;;91929:26;;91856:107;:::o;96664:247::-;96729:7;96749:14;96766:23;:12;;:21;:23::i;:::-;96749:40;;96800:15;96818:48;:15;:27;96834:10;96818:27;;;;;;;;;;;;;;;:37;;;:46;:48::i;:::-;96800:66;;96884:19;96896:6;96884:7;:11;;;;;:19;;;;:::i;:::-;96877:26;;;;96664:247;:::o;7304:127::-;7378:7;7405:9;:18;7415:7;7405:18;;;;;;;;;;;;;;;;7398:25;;7304:127;;;:::o;90765:92::-;90811:7;90837:12;90830:19;;90765:92;:::o;91203:144::-;91273:7;91300:15;:25;91316:8;91300:25;;;;;;;;;;;;;;;:39;;;91293:46;;91203:144;;;:::o;6250:95::-;6297:13;6330:7;6323:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6250:95;:::o;95842:164::-;95898:7;95924:74;:65;95962:26;95984:3;95962:21;:26::i;:::-;95924:33;:31;:33::i;:::-;:37;;;;;:65;;;;:::i;:::-;:72;;;;:74::i;:::-;95917:81;;95842:164;:::o;10380:377::-;10473:4;10490:24;10517:11;:25;10529:12;:10;:12::i;:::-;10517:25;;;;;;;;;;;;;;;:34;10543:7;10517:34;;;;;;;;;;;;;;;;10490:61;;10590:15;10570:16;:35;;10562:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;10658:67;10667:12;:10;:12::i;:::-;10681:7;10709:15;10690:16;:34;;;;:::i;:::-;10658:8;:67::i;:::-;10745:4;10738:11;;;10380:377;;;;:::o;93501:375::-;93561:10;88774:30;88796:7;88774:21;:30::i;:::-;;93601:26:::1;93620:6;93601:14;;:18;;:26;;;;:::i;:::-;93584:14;:43;;;;93682:53;93728:6;93682:15;:27;93698:10;93682:27;;;;;;;;;;;;;;;:41;;;:45;;:53;;;;:::i;:::-;93638:15;:27;93654:10;93638:27;;;;;;;;;;;;;;;:41;;:97;;;;93746:64;93776:10;93796:4;93803:6;93746:12;;;;;;;;;;;:29;;;;:64;;;;;;:::i;:::-;93833:10;93826:42;;;93845:6;93853:14;;93826:42;;;;;;;:::i;:::-;;;;;;;;93501:375:::0;;:::o;90869:155::-;90947:7;90974:15;:25;90990:8;90974:25;;;;;;;;;;;;;;;:42;;;90967:49;;90869:155;;;:::o;7644:175::-;7730:4;7747:42;7757:12;:10;:12::i;:::-;7771:9;7782:6;7747:9;:42::i;:::-;7807:4;7800:11;;7644:175;;;;:::o;95627:203::-;95679:7;95698:14;95715:33;:31;:33::i;:::-;95698:50;;95766:56;:47;95777:35;:24;;:33;:35::i;:::-;95766:6;:10;;;;;:47;;;;:::i;:::-;:54;;;;:56::i;:::-;95759:63;;;95627:203;:::o;91359:148::-;91431:7;91458:15;:25;91474:8;91458:25;;;;;;;;;;;;;;;:41;;;91451:48;;91359:148;;;:::o;92333:108::-;92387:7;92413:20;;92406:27;;92333:108;:::o;96018:243::-;96081:7;96101:14;96118:23;:12;;:21;:23::i;:::-;96101:40;;96152:15;96170:46;:15;:27;96186:10;96170:27;;;;;;;;;;;;;;;:35;;;:44;:46::i;:::-;96152:64;;96234:19;96246:6;96234:7;:11;;;;;:19;;;;:::i;:::-;96227:26;;;;96018:243;:::o;97761:114::-;88156:11;;;;;;;;;;;88142:25;;:10;:25;;;88134:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;97860:7:::1;97840:17;:27;;;;97761:114:::0;:::o;92103:92::-;92149:7;92175:12;;92168:19;;92103:92;:::o;7882:151::-;7971:7;7998:11;:18;8010:5;7998:18;;;;;;;;;;;;;;;:27;8017:7;7998:27;;;;;;;;;;;;;;;;7991:34;;7882:151;;;;:::o;92968:521::-;93035:7;93074:15;:24;93090:7;93074:24;;;;;;;;;;;;;;;:43;;;93059:12;:58;93055:408;;;93134:22;93159:61;93176:15;:24;93192:7;93176:24;;;;;;;;;;;;;;;:43;;;93159:12;:16;;:61;;;;:::i;:::-;93134:86;;93282:1;93239:15;:24;93255:7;93239:24;;;;;;;;;;;;;;;:40;;;:44;93235:217;;;93311:125;93350:85;93415:19;;93350:60;93395:14;93350:15;:24;93366:7;93350:24;;;;;;;;;;;;;;;:40;;;:44;;:60;;;;:::i;:::-;:64;;:85;;;;:::i;:::-;93311:15;:24;93327:7;93311:24;;;;;;;;;;;;;;;:34;;;:38;;:125;;;;:::i;:::-;93304:132;;;;;93235:217;93055:408;;93480:1;93473:8;;92968:521;;;;:::o;97314:395::-;97368:10;88893:32;88917:7;88893:23;:32::i;:::-;;97391:16:::1;97410:24;:22;:24::i;:::-;97391:43;;97460:55;97477:15;:27;97493:10;97477:27;;;;;;;;;;;;;;;:37;;;97460:12;;:16;;:55;;;;:::i;:::-;97445:12;:70;;;;97553:38;97582:8;97553:24;;:28;;:38;;;;:::i;:::-;97526:24;:65;;;;97642:1;97602:15;:27;97618:10;97602:27;;;;;;;;;;;;;;;:37;;:41;;;;97654:47;97680:10;97692:8;97654:12;;;;;;;;;;;:25;;;;:47;;;;;:::i;:::-;88936:1;97314:395:::0;:::o;95251:362::-;95318:10;88893:32;88917:7;88893:23;:32::i;:::-;;95360:28:::1;95381:6;95360:16;;:20;;:28;;;;:::i;:::-;95341:16;:47;;;;95445:55;95493:6;95445:15;:27;95461:10;95445:27;;;;;;;;;;;;;;;:43;;;:47;;:55;;;;:::i;:::-;95399:15;:27;95415:10;95399:27;;;;;;;;;;;;;;;:43;;:101;;;;95511:47;95539:10;95551:6;95511:14;;;;;;;;;;;:27;;;;:47;;;;;:::i;:::-;95586:10;95574:31;;;95598:6;95574:31;;;;;;:::i;:::-;;;;;;;;95251:362:::0;;:::o;93888:393::-;93952:10;88893:32;88917:7;88893:23;:32::i;:::-;;93994:28:::1;94015:6;93994:16;;:20;;:28;;;;:::i;:::-;93975:16;:47;;;;94079:55;94127:6;94079:15;:27;94095:10;94079:27;;;;;;;;;;;;;;;:43;;;:47;;:55;;;;:::i;:::-;94033:15;:27;94049:10;94033:27;;;;;;;;;;;;;;;:43;;:101;;;;94145:66;94177:10;94197:4;94204:6;94145:14;;;;;;;;;;;:31;;;;:66;;;;;;:::i;:::-;94236:10;94227:46;;;94248:6;94256:16;;94227:46;;;;;;;:::i;:::-;;;;;;;;93888:393:::0;;:::o;97887:119::-;88156:11;;;;;;;;;;;88142:25;;:10;:25;;;88134:92;;;;;;;;;;;;:::i;:::-;;;;;;;;;97991:7:::1;97969:19;:29;;;;97887:119:::0;:::o;1023:98::-;1076:7;1103:10;1096:17;;1023:98;:::o;13736:346::-;13855:1;13838:19;;:5;:19;;;;13830:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;13936:1;13917:21;;:7;:21;;;;13909:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;14020:6;13990:11;:18;14002:5;13990:18;;;;;;;;;;;;;;;:27;14009:7;13990:27;;;;;;;;;;;;;;;:36;;;;14058:7;14042:32;;14051:5;14042:32;;;14067:6;14042:32;;;;;;:::i;:::-;;;;;;;;13736:346;;;:::o;28646:98::-;28704:7;28735:1;28731;:5;;;;:::i;:::-;28724:12;;28646:98;;;;:::o;29003:::-;29061:7;29092:1;29088;:5;;;;:::i;:::-;29081:12;;29003:98;;;;:::o;29402:::-;29460:7;29491:1;29487;:5;;;;:::i;:::-;29480:12;;29402:98;;;;:::o;28265:::-;28323:7;28354:1;28350;:5;;;;:::i;:::-;28343:12;;28265:98;;;;:::o;22897:205::-;22998:96;23018:5;23048:27;;;23077:4;23083:2;23087:5;23025:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22998:19;:96::i;:::-;22897:205;;;;:::o;11247:604::-;11371:1;11353:20;;:6;:20;;;;11345:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;11455:1;11434:23;;:9;:23;;;;11426:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;11510:47;11531:6;11539:9;11550:6;11510:20;:47::i;:::-;11570:21;11594:9;:17;11604:6;11594:17;;;;;;;;;;;;;;;;11570:41;;11647:6;11630:13;:23;;11622:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;11743:6;11727:13;:22;;;;:::i;:::-;11707:9;:17;11717:6;11707:17;;;;;;;;;;;;;;;:42;;;;11784:6;11760:9;:20;11770:9;11760:20;;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;11825:9;11808:35;;11817:6;11808:35;;;11836:6;11808:35;;;;;;:::i;:::-;;;;;;;;11247:604;;;;:::o;22712:177::-;22795:86;22815:5;22845:23;;;22870:2;22874:5;22822:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22795:19;:86::i;:::-;22712:177;;;:::o;35514:462::-;35567:7;35611:1;35606;:6;35602:362;;;35630:1;35621:11;;35614:18;;;;35602:362;35657:14;35674:1;35657:18;;35688:11;35702:27;35722:6;35702:18;:27::i;:::-;35688:41;;35750:3;35744;:9;35740:86;;;35772:3;35766;:9;35755:20;;;;;35740:86;;;35801:3;35795;:9;35791:35;;;35823:3;35817;:9;35806:20;;;;;35791:35;35740:86;35905:3;35898;35890:5;:11;:18;;35857:30;35848:6;:39;:60;35839:69;;35946:6;35928:26;;35921:33;;;;35514:462;;;;:::o;54488:2550::-;54547:7;54582:17;54623:6;54617:3;54611:1;54602:11;;:18;;;;:27;54582:47;;;;54638:17;54679:6;54673:3;54667:1;54658:11;;:18;;;;:27;54638:47;;;;54713:6;54700:9;:19;54696:2330;;;54749:6;54736:9;:19;54732:375;;;54779:1;54774:6;;;:1;:6;;;;54770:168;;;54797:34;54793:38;;:1;:38;54789:1;:42;54782:49;;;;;;54770:168;54862:34;54853:43;;54857:1;54853;:5;:43;;;;54849:89;;;54909:1;54905;:5;54898:12;;;;;;54849:89;33370:34;54935:3;;54928:10;;;;;;54732:375;55015:1;54973:43;;54977:34;54973:38;;:1;:38;:43;;;;54969:126;;;33370:34;55025:3;;55018:10;;;;;;54969:126;55061:34;55057:38;;:1;:38;55053:1;:42;55046:49;;;;;;54696:2330;55139:6;55126:9;:19;55122:1904;;;55206:1;55164:43;;55168:34;55164:38;;:1;:38;:43;;;;55160:126;;;33370:34;55216:3;;55209:10;;;;;;55160:126;55252:34;55248:38;;:1;:38;55244:1;:42;55237:49;;;;;;55122:1904;55313:18;55348:30;55343:1;55334:11;;:44;55313:65;;;;55406:1;55393:9;:14;55389:94;;;55421:1;55409:13;;55389:94;;;55452:31;55438:45;;;;55389:94;55496:18;55531:30;55526:1;55517:11;;:44;55496:65;;;;55589:1;55576:9;:14;55572:94;;;55604:1;55592:13;;55572:94;;;55635:31;55621:45;;;;55572:94;55693:10;55679:24;;;;55732:1;55718:10;:15;55714:134;;;55800:1;55753:48;;55763:34;55753:44;;55758:1;55754;:5;55753:44;:48;;;;:95;;32921:34;55835:13;;55753:95;;;33026:34;55819:13;;55753:95;55746:102;;;;;;;;55714:134;55874:9;55861:22;;;;55896:11;55935:59;55921:10;:73;;:217;;56028:59;56014:10;:73;;:124;;56107:31;56127:10;56107:18;:31::i;:::-;56014:124;;;56090:3;56014:124;55921:217;;;55997:3;55921:217;55896:242;;56173:5;56167:3;56155:9;:15;:23;56151:727;;;56218:1;56206:13;;56245:1;56232:14;;56151:727;;;56286:5;56280:3;56268:9;:15;:23;56264:614;;;56335:5;56323:9;:17;56319:154;;;56378:9;56370:5;:17;56355:32;;;;;56319:154;;;56421:5;56409:9;:17;56405:68;;;56468:5;56456:9;:17;56441:32;;;;;56405:68;56319:154;56498:1;56486:13;;56264:614;;;56539:5;56533:3;56521:9;:15;:23;56517:361;;;56571:6;56559:18;;56603:1;56590:14;;56517:361;;;56645:3;56639;:9;56635:122;;;56684:3;56678;:9;56663:24;;;;;56635:122;;;56715:3;56709;:9;56705:52;;;56754:3;56748;:9;56733:24;;;;;56705:52;56635:122;56786:30;56772:44;;;;56861:5;56855:3;56843:9;:15;:23;56831:35;;56517:361;56264:614;56151:727;57004:10;56998:3;56985:9;:16;;56934:34;56924:44;;56929:1;56925;:5;56924:44;56915:54;;:86;;;:99;56897:119;;56890:126;;;;;;;54488:2550;;;;;:::o;36384:600::-;36435:7;36470:16;36510:6;36504:3;36498:1;36489:11;;:18;;;;:27;36470:46;;;;36542:5;36531:8;:16;36527:30;;;36556:1;36549:8;;;;;36527:30;36604:34;36599:1;36590:11;;:48;;;36581:58;;;;;;36683:5;36671:8;:17;;36662:27;;;;;;36710:14;36793:31;36751:30;36745:1;36736:11;;36727:21;;:54;:97;36710:114;;36850:5;36839:8;:16;36835:112;;;36876:8;36868:5;:16;36857:27;;;;;36835:112;;;36913:5;36902:8;:16;36898:49;;;36942:5;36931:8;:16;36920:27;;;;;36898:49;36835:112;36965:6;36958:13;;;;36384:600;;;;:::o;58331:2866::-;58390:7;58425:17;58466:6;58460:3;58454:1;58445:11;;:18;;;;:27;58425:47;;;;58481:17;58522:6;58516:3;58510:1;58501:11;;:18;;;;:27;58481:47;;;;58556:6;58543:9;:19;58539:2646;;;58592:6;58579:9;:19;58575:100;;;33370:34;58607:3;;58600:10;;;;;;58575:100;58641:34;58637:38;;:1;:38;58633:1;:42;58626:49;;;;;;58539:2646;58708:6;58695:9;:19;58691:2494;;;58773:1;58731:43;;58735:34;58731:38;;:1;:38;:43;;;;58727:142;;33370:34;58783:3;;58776:10;;;;;;58727:142;58835:34;58825:44;;58830:1;58826;:5;58825:44;32921:34;58809:13;;:60;58802:67;;;;;;58691:2494;58931:1;58889:43;;58893:34;58889:38;;:1;:38;:43;;;;58885:2300;;;58991:1;58949:43;;58953:34;58949:38;;:1;:38;:43;;;;58945:146;;;33370:34;59001:3;;58994:10;;;;;;58945:146;59057:34;59047:44;;59052:1;59048;:5;59047:44;33142:34;59027:17;;:64;59020:71;;;;;;58885:2300;59118:18;59153:30;59148:1;59139:11;;:44;59118:65;;;;59211:1;59198:9;:14;59194:94;;;59226:1;59214:13;;59194:94;;;59257:31;59243:45;;;;59194:94;59301:18;59336:30;59331:1;59322:11;;:44;59301:65;;;;59394:1;59381:9;:14;59377:356;;;59428:1;59414:10;:15;59410:206;;59446:10;59465:31;59485:10;59465:18;:31::i;:::-;59459:3;:37;59446:50;;59528:5;59513:20;;;;;59562:1;59550:13;;59599:3;59591:5;:11;59578:24;;;;59410:206;;59377:356;;;59718:3;59682:31;59669:10;:44;59668:53;;59655:66;;59377:356;59771:10;59758;:23;;;;;;;;;;;;;;59745:36;;59810:1;59796:10;:15;59792:134;;;59878:1;59831:48;;59841:34;59831:44;;59836:1;59832;:5;59831:44;:48;;;;:95;;32921:34;59913:13;;59831:95;;;33026:34;59897:13;;59831:95;59824:102;;;;;;;;59792:134;59961:30;59947:10;:44;;59939:53;;;;;;;;;;;;60005:11;60044:31;60030:10;:45;;:215;;60137:31;60123:10;:45;;:122;;60202:31;60188:10;:45;;:57;;60242:3;60188:57;;;60236:3;60188:57;60123:122;;;60171:3;60123:122;60030:215;;;;;60078:31;60098:10;60078:18;:31::i;:::-;60030:215;60005:240;;60292:5;60280:9;:17;60274:3;60262:9;:15;:35;60258:779;;;60336:6;60324:18;;60368:1;60355:14;;60258:779;;;60418:9;60409:5;60403:3;60391:9;:15;:23;:36;60387:650;;;60467:1;60455:13;;60494:1;60481:14;;60387:650;;;60544:9;60535:5;60529:3;60517:9;:15;:23;:36;60513:524;;;60605:9;60597:5;60585:9;:17;:29;60581:202;;;60664:9;60656:5;60644:9;:17;:29;60629:44;;;;;60581:202;;;60715:9;60707:5;60695:9;:17;:29;60691:92;;;60778:5;60766:9;60754;:21;:29;60739:44;;;;;60691:92;60581:202;60810:1;60798:13;;60513:524;;;60862:3;60856;:9;60852:52;;;60901:3;60895;:9;60880:24;;;;;60852:52;60933:30;60919:44;;;;61016:9;61008:5;61002:3;60990:9;:15;:23;:35;60978:47;;60513:524;60387:650;60258:779;61163:10;61157:3;61144:9;:16;;61093:34;61083:44;;61088:1;61084;:5;61083:44;61074:54;;:86;;;:99;61056:119;;61049:126;;;;;;;58331:2866;;;;;:::o;25146:761::-;25570:23;25596:69;25624:4;25596:69;;;;;;;;;;;;;;;;;25604:5;25596:27;;;;:69;;;;;:::i;:::-;25570:95;;25700:1;25680:10;:17;:21;25676:224;;;25822:10;25811:30;;;;;;;;;;;;:::i;:::-;25803:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;25676:224;25146:761;;;:::o;14685:92::-;;;;:::o;85645:646::-;85707:7;85755:1;85751;:5;85742:15;;;;;;85768:14;85806:35;85801:1;:40;85797:75;;85851:3;85845:9;;;;;85866:3;85856:13;;;;85797:75;85889:19;85884:1;:24;85880:57;;85918:2;85912:8;;;;;85932:2;85922:12;;;;85880:57;85954:11;85949:1;:16;85945:49;;85975:2;85969:8;;;;;85989:2;85979:12;;;;85945:49;86011:7;86006:1;:12;86002:45;;86028:2;86022:8;;;;;86042:2;86032:12;;;;86002:45;86064:5;86059:1;:10;86055:41;;86079:1;86073:7;;;;;86092:1;86082:11;;;;86055:41;86113:4;86108:1;:9;86104:40;;86127:1;86121:7;;;;;86140:1;86130:11;;;;86104:40;86161:3;86156:1;:8;86152:39;;86174:1;86168:7;;;;;86187:1;86177:11;;;;86152:39;86208:3;86203:1;:8;86199:25;;86223:1;86213:11;;;;86199:25;86272:6;86265:13;;;85645:646;;;:::o;18312:195::-;18415:12;18447:52;18469:6;18477:4;18483:1;18486:12;18447:21;:52::i;:::-;18440:59;;18312:195;;;;;:::o;19364:530::-;19491:12;19549:5;19524:21;:30;;19516:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;19616:18;19627:6;19616:10;:18::i;:::-;19608:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;19742:12;19756:23;19783:6;:11;;19803:5;19811:4;19783:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19741:75;;;;19834:52;19852:7;19861:10;19873:12;19834:17;:52::i;:::-;19827:59;;;;19364:530;;;;;;:::o;15394:422::-;15454:4;15662:12;15773:7;15761:20;15753:28;;15807:1;15800:4;:8;15793:15;;;15394:422;;;:::o;21904:742::-;22019:12;22048:7;22044:595;;;22079:10;22072:17;;;;22044:595;22213:1;22193:10;:17;:21;22189:439;;;22456:10;22450:17;22517:15;22504:10;22500:2;22496:19;22489:44;22404:148;22599:12;22592:20;;;;;;;;;;;:::i;:::-;;;;;;;;21904:742;;;;;;:::o;7:139:1:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:137::-;;237:6;231:13;222:22;;253:30;277:5;253:30;:::i;:::-;212:77;;;;:::o;295:139::-;;379:6;366:20;357:29;;395:33;422:5;395:33;:::i;:::-;347:87;;;;:::o;440:262::-;;548:2;536:9;527:7;523:23;519:32;516:2;;;564:1;561;554:12;516:2;607:1;632:53;677:7;668:6;657:9;653:22;632:53;:::i;:::-;622:63;;578:117;506:196;;;;:::o;708:407::-;;;833:2;821:9;812:7;808:23;804:32;801:2;;;849:1;846;839:12;801:2;892:1;917:53;962:7;953:6;942:9;938:22;917:53;:::i;:::-;907:63;;863:117;1019:2;1045:53;1090:7;1081:6;1070:9;1066:22;1045:53;:::i;:::-;1035:63;;990:118;791:324;;;;;:::o;1121:552::-;;;;1263:2;1251:9;1242:7;1238:23;1234:32;1231:2;;;1279:1;1276;1269:12;1231:2;1322:1;1347:53;1392:7;1383:6;1372:9;1368:22;1347:53;:::i;:::-;1337:63;;1293:117;1449:2;1475:53;1520:7;1511:6;1500:9;1496:22;1475:53;:::i;:::-;1465:63;;1420:118;1577:2;1603:53;1648:7;1639:6;1628:9;1624:22;1603:53;:::i;:::-;1593:63;;1548:118;1221:452;;;;;:::o;1679:407::-;;;1804:2;1792:9;1783:7;1779:23;1775:32;1772:2;;;1820:1;1817;1810:12;1772:2;1863:1;1888:53;1933:7;1924:6;1913:9;1909:22;1888:53;:::i;:::-;1878:63;;1834:117;1990:2;2016:53;2061:7;2052:6;2041:9;2037:22;2016:53;:::i;:::-;2006:63;;1961:118;1762:324;;;;;:::o;2092:278::-;;2208:2;2196:9;2187:7;2183:23;2179:32;2176:2;;;2224:1;2221;2214:12;2176:2;2267:1;2292:61;2345:7;2336:6;2325:9;2321:22;2292:61;:::i;:::-;2282:71;;2238:125;2166:204;;;;:::o;2376:262::-;;2484:2;2472:9;2463:7;2459:23;2455:32;2452:2;;;2500:1;2497;2490:12;2452:2;2543:1;2568:53;2613:7;2604:6;2593:9;2589:22;2568:53;:::i;:::-;2558:63;;2514:117;2442:196;;;;:::o;2644:118::-;2731:24;2749:5;2731:24;:::i;:::-;2726:3;2719:37;2709:53;;:::o;2768:109::-;2849:21;2864:5;2849:21;:::i;:::-;2844:3;2837:34;2827:50;;:::o;2883:118::-;2970:24;2988:5;2970:24;:::i;:::-;2965:3;2958:37;2948:53;;:::o;3007:373::-;;3139:38;3171:5;3139:38;:::i;:::-;3193:88;3274:6;3269:3;3193:88;:::i;:::-;3186:95;;3290:52;3335:6;3330:3;3323:4;3316:5;3312:16;3290:52;:::i;:::-;3367:6;3362:3;3358:16;3351:23;;3115:265;;;;;:::o;3386:364::-;;3502:39;3535:5;3502:39;:::i;:::-;3557:71;3621:6;3616:3;3557:71;:::i;:::-;3550:78;;3637:52;3682:6;3677:3;3670:4;3663:5;3659:16;3637:52;:::i;:::-;3714:29;3736:6;3714:29;:::i;:::-;3709:3;3705:39;3698:46;;3478:272;;;;;:::o;3756:367::-;;3919:67;3983:2;3978:3;3919:67;:::i;:::-;3912:74;;4016:34;4012:1;4007:3;4003:11;3996:55;4082:5;4077:2;4072:3;4068:12;4061:27;4114:2;4109:3;4105:12;4098:19;;3902:221;;;:::o;4129:366::-;;4292:67;4356:2;4351:3;4292:67;:::i;:::-;4285:74;;4389:34;4385:1;4380:3;4376:11;4369:55;4455:4;4450:2;4445:3;4441:12;4434:26;4486:2;4481:3;4477:12;4470:19;;4275:220;;;:::o;4501:370::-;;4664:67;4728:2;4723:3;4664:67;:::i;:::-;4657:74;;4761:34;4757:1;4752:3;4748:11;4741:55;4827:8;4822:2;4817:3;4813:12;4806:30;4862:2;4857:3;4853:12;4846:19;;4647:224;;;:::o;4877:370::-;;5040:67;5104:2;5099:3;5040:67;:::i;:::-;5033:74;;5137:34;5133:1;5128:3;5124:11;5117:55;5203:8;5198:2;5193:3;5189:12;5182:30;5238:2;5233:3;5229:12;5222:19;;5023:224;;;:::o;5253:386::-;;5416:67;5480:2;5475:3;5416:67;:::i;:::-;5409:74;;5513:34;5509:1;5504:3;5500:11;5493:55;5579:24;5574:2;5569:3;5565:12;5558:46;5630:2;5625:3;5621:12;5614:19;;5399:240;;;:::o;5645:372::-;;5808:67;5872:2;5867:3;5808:67;:::i;:::-;5801:74;;5905:34;5901:1;5896:3;5892:11;5885:55;5971:10;5966:2;5961:3;5957:12;5950:32;6008:2;6003:3;5999:12;5992:19;;5791:226;;;:::o;6023:369::-;;6186:67;6250:2;6245:3;6186:67;:::i;:::-;6179:74;;6283:34;6279:1;6274:3;6270:11;6263:55;6349:7;6344:2;6339:3;6335:12;6328:29;6383:2;6378:3;6374:12;6367:19;;6169:223;;;:::o;6398:368::-;;6561:67;6625:2;6620:3;6561:67;:::i;:::-;6554:74;;6658:34;6654:1;6649:3;6645:11;6638:55;6724:6;6719:2;6714:3;6710:12;6703:28;6757:2;6752:3;6748:12;6741:19;;6544:222;;;:::o;6772:327::-;;6935:67;6999:2;6994:3;6935:67;:::i;:::-;6928:74;;7032:31;7028:1;7023:3;7019:11;7012:52;7090:2;7085:3;7081:12;7074:19;;6918:181;;;:::o;7105:374::-;;7268:67;7332:2;7327:3;7268:67;:::i;:::-;7261:74;;7365:34;7361:1;7356:3;7352:11;7345:55;7431:12;7426:2;7421:3;7417:12;7410:34;7470:2;7465:3;7461:12;7454:19;;7251:228;;;:::o;7485:369::-;;7648:67;7712:2;7707:3;7648:67;:::i;:::-;7641:74;;7745:34;7741:1;7736:3;7732:11;7725:55;7811:7;7806:2;7801:3;7797:12;7790:29;7845:2;7840:3;7836:12;7829:19;;7631:223;;;:::o;7860:118::-;7947:24;7965:5;7947:24;:::i;:::-;7942:3;7935:37;7925:53;;:::o;7984:112::-;8067:22;8083:5;8067:22;:::i;:::-;8062:3;8055:35;8045:51;;:::o;8102:271::-;;8254:93;8343:3;8334:6;8254:93;:::i;:::-;8247:100;;8364:3;8357:10;;8236:137;;;;:::o;8379:442::-;;8566:2;8555:9;8551:18;8543:26;;8579:71;8647:1;8636:9;8632:17;8623:6;8579:71;:::i;:::-;8660:72;8728:2;8717:9;8713:18;8704:6;8660:72;:::i;:::-;8742;8810:2;8799:9;8795:18;8786:6;8742:72;:::i;:::-;8533:288;;;;;;:::o;8827:332::-;;8986:2;8975:9;8971:18;8963:26;;8999:71;9067:1;9056:9;9052:17;9043:6;8999:71;:::i;:::-;9080:72;9148:2;9137:9;9133:18;9124:6;9080:72;:::i;:::-;8953:206;;;;;:::o;9165:210::-;;9290:2;9279:9;9275:18;9267:26;;9303:65;9365:1;9354:9;9350:17;9341:6;9303:65;:::i;:::-;9257:118;;;;:::o;9381:222::-;;9512:2;9501:9;9497:18;9489:26;;9525:71;9593:1;9582:9;9578:17;9569:6;9525:71;:::i;:::-;9479:124;;;;:::o;9609:313::-;;9760:2;9749:9;9745:18;9737:26;;9809:9;9803:4;9799:20;9795:1;9784:9;9780:17;9773:47;9837:78;9910:4;9901:6;9837:78;:::i;:::-;9829:86;;9727:195;;;;:::o;9928:419::-;;10132:2;10121:9;10117:18;10109:26;;10181:9;10175:4;10171:20;10167:1;10156:9;10152:17;10145:47;10209:131;10335:4;10209:131;:::i;:::-;10201:139;;10099:248;;;:::o;10353:419::-;;10557:2;10546:9;10542:18;10534:26;;10606:9;10600:4;10596:20;10592:1;10581:9;10577:17;10570:47;10634:131;10760:4;10634:131;:::i;:::-;10626:139;;10524:248;;;:::o;10778:419::-;;10982:2;10971:9;10967:18;10959:26;;11031:9;11025:4;11021:20;11017:1;11006:9;11002:17;10995:47;11059:131;11185:4;11059:131;:::i;:::-;11051:139;;10949:248;;;:::o;11203:419::-;;11407:2;11396:9;11392:18;11384:26;;11456:9;11450:4;11446:20;11442:1;11431:9;11427:17;11420:47;11484:131;11610:4;11484:131;:::i;:::-;11476:139;;11374:248;;;:::o;11628:419::-;;11832:2;11821:9;11817:18;11809:26;;11881:9;11875:4;11871:20;11867:1;11856:9;11852:17;11845:47;11909:131;12035:4;11909:131;:::i;:::-;11901:139;;11799:248;;;:::o;12053:419::-;;12257:2;12246:9;12242:18;12234:26;;12306:9;12300:4;12296:20;12292:1;12281:9;12277:17;12270:47;12334:131;12460:4;12334:131;:::i;:::-;12326:139;;12224:248;;;:::o;12478:419::-;;12682:2;12671:9;12667:18;12659:26;;12731:9;12725:4;12721:20;12717:1;12706:9;12702:17;12695:47;12759:131;12885:4;12759:131;:::i;:::-;12751:139;;12649:248;;;:::o;12903:419::-;;13107:2;13096:9;13092:18;13084:26;;13156:9;13150:4;13146:20;13142:1;13131:9;13127:17;13120:47;13184:131;13310:4;13184:131;:::i;:::-;13176:139;;13074:248;;;:::o;13328:419::-;;13532:2;13521:9;13517:18;13509:26;;13581:9;13575:4;13571:20;13567:1;13556:9;13552:17;13545:47;13609:131;13735:4;13609:131;:::i;:::-;13601:139;;13499:248;;;:::o;13753:419::-;;13957:2;13946:9;13942:18;13934:26;;14006:9;14000:4;13996:20;13992:1;13981:9;13977:17;13970:47;14034:131;14160:4;14034:131;:::i;:::-;14026:139;;13924:248;;;:::o;14178:419::-;;14382:2;14371:9;14367:18;14359:26;;14431:9;14425:4;14421:20;14417:1;14406:9;14402:17;14395:47;14459:131;14585:4;14459:131;:::i;:::-;14451:139;;14349:248;;;:::o;14603:222::-;;14734:2;14723:9;14719:18;14711:26;;14747:71;14815:1;14804:9;14800:17;14791:6;14747:71;:::i;:::-;14701:124;;;;:::o;14831:332::-;;14990:2;14979:9;14975:18;14967:26;;15003:71;15071:1;15060:9;15056:17;15047:6;15003:71;:::i;:::-;15084:72;15152:2;15141:9;15137:18;15128:6;15084:72;:::i;:::-;14957:206;;;;;:::o;15169:214::-;;15296:2;15285:9;15281:18;15273:26;;15309:67;15373:1;15362:9;15358:17;15349:6;15309:67;:::i;:::-;15263:120;;;;:::o;15389:98::-;;15474:5;15468:12;15458:22;;15447:40;;;:::o;15493:99::-;;15579:5;15573:12;15563:22;;15552:40;;;:::o;15598:147::-;;15736:3;15721:18;;15711:34;;;;:::o;15751:169::-;;15869:6;15864:3;15857:19;15909:4;15904:3;15900:14;15885:29;;15847:73;;;;:::o;15926:305::-;;15985:20;16003:1;15985:20;:::i;:::-;15980:25;;16019:20;16037:1;16019:20;:::i;:::-;16014:25;;16173:1;16105:66;16101:74;16098:1;16095:81;16092:2;;;16179:18;;:::i;:::-;16092:2;16223:1;16220;16216:9;16209:16;;15970:261;;;;:::o;16237:185::-;;16294:20;16312:1;16294:20;:::i;:::-;16289:25;;16328:20;16346:1;16328:20;:::i;:::-;16323:25;;16367:1;16357:2;;16372:18;;:::i;:::-;16357:2;16414:1;16411;16407:9;16402:14;;16279:143;;;;:::o;16428:348::-;;16491:20;16509:1;16491:20;:::i;:::-;16486:25;;16525:20;16543:1;16525:20;:::i;:::-;16520:25;;16713:1;16645:66;16641:74;16638:1;16635:81;16630:1;16623:9;16616:17;16612:105;16609:2;;;16720:18;;:::i;:::-;16609:2;16768:1;16765;16761:9;16750:20;;16476:300;;;;:::o;16782:191::-;;16842:20;16860:1;16842:20;:::i;:::-;16837:25;;16876:20;16894:1;16876:20;:::i;:::-;16871:25;;16915:1;16912;16909:8;16906:2;;;16920:18;;:::i;:::-;16906:2;16965:1;16962;16958:9;16950:17;;16827:146;;;;:::o;16979:96::-;;17045:24;17063:5;17045:24;:::i;:::-;17034:35;;17024:51;;;:::o;17081:90::-;;17158:5;17151:13;17144:21;17133:32;;17123:48;;;:::o;17177:150::-;;17254:66;17247:5;17243:78;17232:89;;17222:105;;;:::o;17333:126::-;;17410:42;17403:5;17399:54;17388:65;;17378:81;;;:::o;17465:77::-;;17531:5;17520:16;;17510:32;;;:::o;17548:86::-;;17623:4;17616:5;17612:16;17601:27;;17591:43;;;:::o;17640:307::-;17708:1;17718:113;17732:6;17729:1;17726:13;17718:113;;;17817:1;17812:3;17808:11;17802:18;17798:1;17793:3;17789:11;17782:39;17754:2;17751:1;17747:10;17742:15;;17718:113;;;17849:6;17846:1;17843:13;17840:2;;;17929:1;17920:6;17915:3;17911:16;17904:27;17840:2;17689:258;;;;:::o;17953:320::-;;18034:1;18028:4;18024:12;18014:22;;18081:1;18075:4;18071:12;18102:18;18092:2;;18158:4;18150:6;18146:17;18136:27;;18092:2;18220;18212:6;18209:14;18189:18;18186:38;18183:2;;;18239:18;;:::i;:::-;18183:2;18004:269;;;;:::o;18279:180::-;18327:77;18324:1;18317:88;18424:4;18421:1;18414:15;18448:4;18445:1;18438:15;18465:180;18513:77;18510:1;18503:88;18610:4;18607:1;18600:15;18634:4;18631:1;18624:15;18651:180;18699:77;18696:1;18689:88;18796:4;18793:1;18786:15;18820:4;18817:1;18810:15;18837:102;;18929:2;18925:7;18920:2;18913:5;18909:14;18905:28;18895:38;;18885:54;;;:::o;18945:122::-;19018:24;19036:5;19018:24;:::i;:::-;19011:5;19008:35;18998:2;;19057:1;19054;19047:12;18998:2;18988:79;:::o;19073:116::-;19143:21;19158:5;19143:21;:::i;:::-;19136:5;19133:32;19123:2;;19179:1;19176;19169:12;19123:2;19113:76;:::o;19195:122::-;19268:24;19286:5;19268:24;:::i;:::-;19261:5;19258:35;19248:2;;19307:1;19304;19297:12;19248:2;19238:79;:::o

Swarm Source

ipfs://7ef03349b54f566865a69f3476cf8148e8cf08bf58835059c36cab8c7203077e
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.