ETH Price: $3,587.58 (+2.13%)
Gas: 48 Gwei

Contract

0x444444444444C1a66F394025Ac839A535246FCc8
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
0x493e8940cf6f9b7bc82e129abc9bf24ea92c46de76d9cb01e14f0f947707a52aRelease Shares(pending)2024-03-24 1:39:454 days ago1711244385IN
Genius: GENI Token
0 ETH(Pending)(Pending)
Approve195312922024-03-28 8:02:357 hrs ago1711612955IN
Genius: GENI Token
0 ETH0.0010819423.21915432
End Miner195286102024-03-27 22:53:1116 hrs ago1711579991IN
Genius: GENI Token
0 ETH0.0086309835.58010825
End Miner195285912024-03-27 22:48:5916 hrs ago1711579739IN
Genius: GENI Token
0 ETH0.0102573334.04100664
Approve195228822024-03-27 2:58:5936 hrs ago1711508339IN
Genius: GENI Token
0 ETH0.0009332620.00275966
Approve195222942024-03-27 0:59:3538 hrs ago1711501175IN
Genius: GENI Token
0 ETH0.0012112726.13602307
End Miner195220852024-03-27 0:16:3539 hrs ago1711498595IN
Genius: GENI Token
0 ETH0.0125062126.42847087
Transfer195155322024-03-26 2:05:472 days ago1711418747IN
Genius: GENI Token
0 ETH0.0006839319.84881743
End Miner195136962024-03-25 19:55:592 days ago1711396559IN
Genius: GENI Token
0 ETH0.0114317933.88173473
Approve195129792024-03-25 17:31:112 days ago1711387871IN
Genius: GENI Token
0 ETH0.0014138930.30395721
Transfer195115092024-03-25 12:31:233 days ago1711369883IN
Genius: GENI Token
0 ETH0.000706520.50404963
End Miner195088652024-03-25 3:33:593 days ago1711337639IN
Genius: GENI Token
0 ETH0.005325312.73896262
Release Shares195088602024-03-25 3:32:593 days ago1711337579IN
Genius: GENI Token
0 ETH0.00110612
Release Shares195088602024-03-25 3:32:593 days ago1711337579IN
Genius: GENI Token
0 ETH0.0011058612
Release Shares195086632024-03-25 2:52:593 days ago1711335179IN
Genius: GENI Token
0 ETH0.0010754612
Release Shares195086632024-03-25 2:52:593 days ago1711335179IN
Genius: GENI Token
0 ETH0.0010754612
End Miner195085742024-03-25 2:34:353 days ago1711334075IN
Genius: GENI Token
0 ETH0.005657614.03737328
End Miner195084782024-03-25 2:14:473 days ago1711332887IN
Genius: GENI Token
0 ETH0.0117844318.75266311
End Miner195080692024-03-25 0:51:473 days ago1711327907IN
Genius: GENI Token
0 ETH0.0035540214.06798666
Release Shares195068492024-03-24 20:44:353 days ago1711313075IN
Genius: GENI Token
0 ETH0.0021286323.75124296
End Miner195040482024-03-24 11:16:234 days ago1711278983IN
Genius: GENI Token
0 ETH0.0050903616.65860296
Transfer195034202024-03-24 9:08:474 days ago1711271327IN
Genius: GENI Token
0 ETH0.0005666616.4456022
End Miner195032692024-03-24 8:38:114 days ago1711269491IN
Genius: GENI Token
0 ETH0.0042928416.39047604
End Miner195025002024-03-24 6:01:594 days ago1711260119IN
Genius: GENI Token
0 ETH0.0053086515.09008008
Release Shares194997542024-03-23 20:44:474 days ago1711226687IN
Genius: GENI Token
0 ETH0.0020626223.01476247
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Genius

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-31
*/

// SPDX-License-Identifier: UNLICENSED
// Genius is NOT LICENSED FOR COPYING.
// Genius (C) 2022. All Rights Reserved.
//
// Telegram: https://t.me/genicrypto
// Twitter: https://twitter.com/genicrypto
// White Paper: https://geni.to/smartcontract
//
// First DAPP: https://start.geni.app
// Community Website: https://thegeniustoken.com
// Development Telegram: https://t.me/genicryptodev
//
// Buy $GENI here:
// * Ethereum: https://geni.to/ethereum
// * Binance: https://geni.to/binance
// * Polygon: https://geni.to/polygon
// * Avalanche: https://geni.to/avalanche
//
// Third-Party Security Reviews:
// * Gleipnir: https://www.gleipnirsecurity.com/_files/ugd/a4dd88_02edf4a4aeef4e6d950db85175488ebb.pdf
// * CertiK: https://www.certik.com/projects/genius

// Sources flattened with hardhat v2.9.9 https://hardhat.org

// File @openzeppelin/contracts/token/ERC20/[email protected]

// License: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the 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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}


// File @openzeppelin/contracts/utils/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}


// File @openzeppelin/contracts/security/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}


// File @openzeppelin/contracts/utils/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/token/ERC20/[email protected]

// License: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;



/**
 * @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 Contracts guidelines: functions revert
 * instead 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, IERC20Metadata {
    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 default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two 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 override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override 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
     * overridden;
     *
     * 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 override 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:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, 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}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, 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}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, 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) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, 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) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This 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:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
        }
        _balances[to] += amount;

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, 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:
     *
     * - `account` 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);

        _afterTokenTransfer(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");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

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

        _afterTokenTransfer(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 Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - 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 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 {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

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

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}


// File @openzeppelin/contracts/utils/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]

// License: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]

// License: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}


// File @openzeppelin/contracts/token/ERC20/extensions/[email protected]

// License: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)

pragma solidity ^0.8.0;





/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private constant _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
    /**
     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
     * However, to ensure consistency with the upgradeable transpiler, we will continue
     * to reserve a slot.
     * @custom:oz-renamed-from _PERMIT_TYPEHASH
     */
    // solhint-disable-next-line var-name-mixedcase
    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}


// File @openzeppelin/contracts/utils/cryptography/[email protected]

// License: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}


// File contracts/Utilities.sol

// License: UNLICENSED
// Genius is NOT LICENSED FOR COPYING.
// Genius (C) 2022. All Rights Reserved.
pragma solidity 0.8.4;

interface IPenalty {
    function setMinersContract(address _minersAddress) external;
    function increasePenaltyCounter(uint256 principal) external;
    function redistribution(bool minerPolicy, uint256 principalPenalties, uint256 rewardPenalties) external
        returns (uint256 oaReceivingAmount, uint256 redistributedPenalties);
    function decMinerPopulation(uint256 genitos) external;
    function incMinerPopulation(uint256 genitos) external;
    function getMaxOrder() external view returns (uint256 maxOrder);
    function counter() external view returns (uint256);
    function calcLemClaimed(Utilities.MinerCache memory miner) external view returns(uint256);
    function endMinerPenalties(Utilities.MinerCache calldata miner, uint256 servedDays,
        uint256 currentGeniusDay, uint256 rewards) external
        returns (Utilities.PenaltyData memory ptData);
    function minerWeight(uint256 weight) external view returns (uint256);
}

interface IGeniusAuction {
    struct AuctionCache {
        uint256 totalBids;
        uint256 firstBid;
        address highestBidder;
        uint256 minerIndex;
        uint256 highestBid;
        address owner;
        bool active;
        uint256 end;
    }

    function getGeniusAuctionState(address owner, uint256 minerIndex)
        external
        returns (AuctionCache memory);

    function cancelAuction(address owner, uint256 minerIndex) external;

    function verifyAuctionNoBid(address owner, uint256 minerIndex)
        external
        returns (bool);

    function setPenaltyAddress(address panlty) external;

    function setMinersContract(address _minersAddress) external;

    function setCalendarContract(address _calendarAddress) external;

    function setGnftContract(address _gnftAddress) external;

}

interface IStabilityPool {

    struct CollateralMiner {
        address collateralToken;
    }

    function getMinerColAddress(address owner, uint256 minerIndex) external returns (address);

    function clearGeniusDebt(
        Utilities.MinerCache calldata miner,
        address minerOwner,
        uint256 minerIndex,
        address beneficiary,
        uint256 currentGeniusDay,
        bool benevolent
    ) external returns (uint256);

    function settleGeniusDebt(address beneficiary, address token,
        uint256 amount, uint256 settlementFeeDays, bool mintNft) external returns (uint256);

    function setOaGrantor(address grantor) external;

    function setOaBeneficiary(address beneficiary) external;

    function genitosRequiredToClear(address collateralAddress, uint256 principal) external returns (uint256);

    function setPenaltyContract(address penaltyContract) external;

    function setMinersContract(address minersContract) external;

    function setGnftContract(address _gnftAddress) external;

    function setAuctionContract(address auctionAddress) external;
}

interface IGeniusCalendar {
    struct GeniusDaySummaryStore {
        uint256 newInflation;
        uint256 redistribution;
        uint256 basicShares;
        uint256 advShares;
    }

    function getDaySummary(uint256 localGeniusDay)
        external
        view
        returns (GeniusDaySummaryStore memory summary);

    function makeGeniusDaySummary(uint256 _summarizeLimit) external;

    function decreaseBurnedSupply(uint256 _amount) external;

    function increaseBurnedSupply(uint256 _amount) external;

    function burnedSupply() external view returns (uint256);

    function calcDayBasicPayout(uint256 _geniusDay)
        external
        view
        returns (uint256);

    function calcDayAdvPayout(uint256 _geniusDay, uint256 _basicPayout)
        external
        view
        returns (uint256);

    function decAdvShares(uint256 _amount) external;

    function decBasicShares(uint256 _amount) external;

    function shareRate() external view returns (uint256);

    function localSummarizeGeniusDay(
        uint256 _summarizeLimit,
        address _summarizer,
        bool mintNft
    ) external returns(uint256 itCount);

    function local10daySummary(uint256 _summarizeLimit, address _summarizer, bool mintNft) external returns(uint256 itCount);

    function local100daySummary(uint256 _summarizeLimit, address _summarizer, bool mintNft) external returns(uint256 itCount);

    function local1000daySummary(uint256 _summarizeLimit, address _summarizer, bool mintNft) external returns(uint256 itCount);

    function incAdvSharesNext(uint256 _amount) external;

    function incBasicSharesNext(uint256 _amount) external;

    function geniusDay() external view returns (uint256);

    function setShareRate(uint256 _shareRate) external;

    function minerTotalPps(uint256 startDay, uint256 lastServedDay, bool minerPolicy) external view returns(uint256);

    function setPenaltyContract(address _penaltyAddress) external;

    function setMinersContract(address _minersAddress) external;

    function setHexodusContract(address _hexodus) external;

    function incDailyPenalties(uint256 _amount) external;

    function setGnftContract(address _gnftAddress) external;

    function summarizeServedDays(address beneficiary, uint256 startDay,
        uint256 promiseDays, bool mintNft) external;
}

interface IMiners {
    function minerStore(address owner, uint256 minerIndex) external view returns(Utilities.MinerCache memory miner);
    function minerStoreLength(address owner) external view returns (uint256 length);
    function getMiners(address owner) external view returns(Utilities.MinerCache[] memory miners);
    function setMinerEnded(address owner, uint256 minerIndex, uint256 ended) external;
    function setMinerStoreLemClaimDay(address owner, uint256 minerIndex, uint256 lemClaimDay) external;
    function setHexodusContract(address _hexodus) external;
    function setGnftContract(address _gnftAddress) external;
    function checkMinerForEnd(
        Utilities.MinerCache memory miner,
        address owner,
        uint256 minerIndex,
        uint256 currentDay,
        uint256 servedDays
    ) external;
}

interface IGnft {
    function mintNft(address to, uint256 nextSalt) external;
}


contract Utilities {

    // Revert Errors
    error NoClaimExists();
    error CannotShutdown();
    error UnauthorizedLostBonusClaiming();

    /** PHI Constants
     * @notice all of the above constants (PHI & GENIUS_RATIO) have 21 decimals of precision
     */
    /* ~ CONSTANTS ~ */
    // PHI = 1.618033988749894848205
    uint256 internal constant PHI = 1618033988749894848204586834;
    // PHI^-2 = 0.38196601125010515179541316563436188227969082019424
    uint256 internal constant PHI_NPOW_2 = 381966011250105151795413165;
    // PHI^-3 = 0.23606797749978969640917366873127623544061835961153
    uint256 internal constant PHI_NPOW_3 = 236067977499789696409173668;
    // PHI^-3.5 = 0.18558516575586807029616916594610619486184991016702
    uint256 internal constant PHI_NPOW_35 = 185585165755868070296169165;
    // PHI^2 = 2.6180339887498948482045868343656381177203091798058
    uint256 internal constant PHI_POW_2 = 2618033988749894848204586834;
    // PHI^PHI = 2.1784575679375991473725457028712458518070433016933
    uint256 internal constant PHI_POW_PHI = 2178457567937599147372545702;

    uint256 internal constant PHI_PRECISION = 1000000000000000000000000000;

    uint256 internal constant GENIUS_PRECISION = 1000000000;

    address internal constant LGENI_OA = 0x66eCa275200015DCD0C2Eaa6E48d4eED3092cDD6;

    uint8 internal constant GENIUS_DECIMALS = 9;

    // Tue Dec 13 2022 20:44:06 GMT+0000
    // Tue Dec 13 2022 13:44:06 GMT-0700 (Mountain Standard Time)
    // Tue Dec 13 2022 14:44:06 PM CST GMT-0600 (Central Standard)
    uint256 public constant LAUNCH_TIMESTAMP = 1670964246;

    // 10 ** 18
    uint256 internal constant SHARE_PRECISION = 1000000000000000000;

    // Penalty Counter Precision: 10 ** 12
    uint256 internal constant PENALTY_COUNTER_PRECISION = 1000000000000;

    // claims root for airdrop
    /** @notice MAKE CONSTANT FOR PRODUCTION */
    bytes32 internal constant MERKLE_ROOT =
        0xcad71776a60b1a4ca80bfa5452bfc50beeb645b7f64e97f5c464ef45a41d548d;

    /* ~ Variables ~ */

    uint256 public advLockedSupply;
    uint256 public basicLockedSupply;

    address public stabilityPoolAddress;
    IStabilityPool stabilityPoolContract;

    address public auctionAddress;
    IGeniusAuction auctionHouse;

    address public calendarAddress;
    IGeniusCalendar calendar;

    address public penaltyAddress;
    IPenalty penaltyContract;

    address public minersAddress;
    IMiners minersContract;

    address public hexodusAddress;
    address public gnftAddress;
    IGnft _gnftContract;

    // Origin Address Wallet
    address public oaGrantor;
    address public oaBeneficiary;

    /** Sacrifice merkle claims tracker */
    mapping(address => bool) public claimed;

    uint256 public oaMintableBalance;

    /* ~ DATA STRUCTS ~ */
    struct MinerCache {
        bool policy;
        bool auctioned;
        bool exodus;
        uint256 startDay;
        uint256 promiseDays;
        uint256 lemClaimDay;
        uint256 rewardShares;
        uint256 penaltyDelta;
        bool nonTransferable;
        uint256 ended;
        uint256 principal; // in genitos (10^9)
        uint256 debtIssueRate;
    }

    struct PenaltyData {
        uint256 eemRewardFee;
        uint256 eemPrincipalFee;
        uint256 eemPenalty;
        uint256 lemRewardFee;
        uint256 lemPrincipalFee;
        uint256 lemPenalty;
    }

    /* ~ EVENTS STRUCTS ~ */
    event Claim(
        address sender,
        address claimant,
        uint256 amount
    );

    event LemRewardsClaim(
        address indexed executorRewardAddress,
        address owner,
        uint256 minerIndex,
        uint256 executorReward
    );

    /**
     * @param  owner        the account that owned the miner at the time of end.
     * @param  minerIndex   the account's index for the miner struct.
     * @param  benevolence  whether this "end" action was for community
     *                      benevolence.
     *
     * @param  principalPayout    The amount of Principal that was returned to
     *                            the owner minus principal penalties.
     * @param  totalMinerRewards  The total amount of rewards--will always be
     *                            the Total PPS multiplied by the Shares.
     * @param  rewardsPayout      The actual amount of rewards paid to the owner
     *                            minus penalties on the rewards.
     * @param  penaltyToMiners    From ending, this amount of penalties was
     *                            redistributed to other Advanced Miners.
     */
    event EndMiner(address indexed owner, uint256 minerIndex, bool benevolence,
        uint256 principalPayout, uint256 totalMinerRewards,
        uint256 rewardsPayout, uint256 penaltyToMiners, Utilities.MinerCache miner);

    event ShutdownMiner(address indexed minerAddress, uint256 minerIndex,
        address indexed executorRewardAddress, uint256 executorReward,
        uint256 performanceRewards, uint256 redistributedPenalties,
        uint256 toOa, uint256 burnedForever, Utilities.MinerCache miner);

    event ChangeOaGrantor(address newOaGrantor, uint256 updated);

    event ChangeOaBeneficiary(address newOaBeneficiary, uint256 updated);
}


// File contracts/Genius.sol

// License: UNLICENSED
// Genius is NOT LICENSED FOR COPYING.
// Genius (C) 2022. All Rights Reserved.
pragma solidity 0.8.4;





contract Genius is ERC20, ERC20Permit, Utilities, ReentrancyGuard {

    error ErrorNullAddress();
    error ErrorUnauthorized();
    error ErrorCannotReleaseShares();
    error ErrorCannotReleaseAuctionedShares();
    error ErrorNotLaunchedYet();

    struct ShutdownDataCache {
        uint256 principalToRedistribute;
        uint256 rewardsToRedistribute;
        uint256 txPrincipalRewards;
        uint256 txPerformanceRewards;
    }

    constructor(
        address _oaGrantor,
        address _oaBeneficiary
    ) ERC20("Genius", "GENI") ERC20Permit("Genius") {
        if (_oaGrantor == address(0) || _oaBeneficiary == address(0)) {
            revert ErrorNullAddress();
        }
        oaGrantor = _oaGrantor;
        oaBeneficiary = _oaBeneficiary;
        _mint(address(this), 240000000000000000000);
    }

    /**
     * @notice public facing pure, returns decimal precision value of genius
     */
    function decimals() public pure override returns (uint8) {
        return GENIUS_DECIMALS;
    }

    /**
     * @dev only callable by oaGrantor, set oaBeneficiary address
     */
    function changeOaBeneficiary(address _oaBeneficiary) external {
        if (_oaBeneficiary == address(0)) revert ErrorNullAddress();
        if (msg.sender != oaGrantor) revert ErrorUnauthorized();
        oaBeneficiary = _oaBeneficiary;
        stabilityPoolContract.setOaBeneficiary(_oaBeneficiary);
        emit ChangeOaBeneficiary(_oaBeneficiary, block.timestamp);
    }

    /**
     * @dev only callable by oaGrantor, change oaGrantor
     */
    function changeOaGrantor(address _newOaGrantor) external {
        if (_newOaGrantor == address(0)) revert ErrorNullAddress();
        if (msg.sender != oaGrantor) revert ErrorUnauthorized();
        oaGrantor = _newOaGrantor;
        stabilityPoolContract.setOaGrantor(_newOaGrantor);
        emit ChangeOaGrantor(_newOaGrantor, block.timestamp);
    }

    /**
     * @notice public facing, shielded. Only OA can set the auction.
     * @notice auction house must be set before auction functions are operable
     */
    function setAuctionContract(address _auction) external {
// NOTE: OA Grantor check removed because deployment will include these "set"
// functions.  The actual gate that will prevent the Auction Contract being
// set again is the requirement that auctionAddress is not yet set.
//        require(msg.sender == oaGrantor && auctionAddress == address(0), "u");
        if (_auction == address(0)) revert ErrorNullAddress();
        if (auctionAddress != address(0)) revert ErrorUnauthorized();
        auctionAddress = _auction;
        auctionHouse = IGeniusAuction(_auction);
        stabilityPoolContract.setAuctionContract(_auction);
    }

    /**
     * @dev only callable by oaGrantor, set stability pool address (only callable once)
     */
    function setStabilityPoolAddress(address _stabilityPool) external {
// NOTE: this prevents Stability Pool from being set again AFTER deployment
// by ensuring that the contract address has not already been set.
//        require(msg.sender == oaGrantor && stabilityPoolAddress == address(0), "u");
        if (_stabilityPool == address(0)) revert ErrorNullAddress();
        if (stabilityPoolAddress != address(0)) revert ErrorUnauthorized();
        stabilityPoolAddress = _stabilityPool;
        stabilityPoolContract = IStabilityPool(_stabilityPool);
        // NOTE: to prevent a circular dependency, the OA Grantor will need to
        // call this separately.
        //auctionHouse.setStabilityContract(_stabilityPool);
    }

    /**
     * @dev only callable by oaGrantor, set calendar address and calls setters on calendar and auction (only callable once)
     */
    function setCalendarContract(address _calendar) external {
// NOTE: this prevents Calendar from being set again AFTER deployment by
// ensuring that the contract address has not already been set.
        if (_calendar == address(0)) revert ErrorNullAddress();
        if (calendarAddress != address(0)) revert ErrorUnauthorized();
        calendarAddress = _calendar;
        calendar = IGeniusCalendar(_calendar);
        auctionHouse.setCalendarContract(_calendar);
    }

    /**
     * @dev only callable by oaGrantor, set penalty address and calls setters on calendar, stability pool and auction (only callable once)
     */
    function setPenaltyContract(address _pcAddress) external {
// NOTE: this prevents Penalty from being set again AFTER deployment by
// ensuring that the contract address has not already been set.  The deploy
// scripts manage and ensure that this is set at launch.
        if (_pcAddress == address(0)) revert ErrorNullAddress();
        if (penaltyAddress != address(0)) revert ErrorUnauthorized();
//        require(
//            msg.sender == oaGrantor &&
//            penaltyAddress == address(0) &&
//            calendarAddress != address(0) &&
//            stabilityPoolAddress != address(0) &&
//            auctionAddress != address(0)
//        , "u");

// NOTE: combining these saves 0.111 KB.
//        require(msg.sender == oaGrantor && penaltyAddress == address(0), "u");
//        require(calendarAddress != address(0), "1");
//        require(stabilityPoolAddress != address(0), "2");
//        require(auctionAddress != address(0), "3");
        penaltyContract = IPenalty(_pcAddress);
        penaltyAddress = _pcAddress;
        calendar.setPenaltyContract(_pcAddress);
        stabilityPoolContract.setPenaltyContract(_pcAddress);
        auctionHouse.setPenaltyAddress(_pcAddress);
    }

    /**
     * @dev only callable by oaGrantor, sets miners address and calls setters on auction, calendar and stability pool (only callable once)
     */
    function setMinersContract(address _minersAddress) external {
// NOTE: this prevents Miners from being set again AFTER deployment by
// ensuring that the contract address has not already been set.  The deploy
// scripts manage and ensure that this is set at launch.
//        require(msg.sender == oaGrantor && minersAddress == address(0), "u");
        if (_minersAddress == address(0)) revert ErrorNullAddress();
        if (minersAddress != address(0)) revert ErrorUnauthorized();
        minersAddress = _minersAddress;
        minersContract = IMiners(_minersAddress);
        auctionHouse.setMinersContract(_minersAddress);
        calendar.setMinersContract(_minersAddress);
        stabilityPoolContract.setMinersContract(_minersAddress);
        penaltyContract.setMinersContract(_minersAddress);
    }

    function setHexodusContract(address _hexodus) external {
        if (_hexodus == address(0)) revert ErrorNullAddress();
        if (msg.sender != oaGrantor || hexodusAddress != address(0)) {
            revert ErrorUnauthorized();
        }
        hexodusAddress = _hexodus;
        minersContract.setHexodusContract(_hexodus);
        calendar.setHexodusContract(_hexodus);
    }

    /**
     * @notice set up Genius NFT controller
     * @dev allowed only by OA grantor or deployer
     * @param _gnftAddress address of genius NFT controller
     */
    function setGnftContract(address _gnftAddress) external {
// NOTE: GNFT will be launched after the core Genius contracts, and therefore,
// it is necessary to also gate the setting of GNFT's address by limiting this
// action to the OA Grantor.
        if (_gnftAddress == address(0)) revert ErrorNullAddress();
        if (msg.sender != oaGrantor || gnftAddress != address(0)) {
            revert ErrorUnauthorized();
        }
        gnftAddress = _gnftAddress;
        _gnftContract = IGnft(_gnftAddress);

        auctionHouse.setGnftContract(_gnftAddress);
        calendar.setGnftContract(_gnftAddress);
        minersContract.setGnftContract(_gnftAddress);
        stabilityPoolContract.setGnftContract(_gnftAddress);
    }

    function _currentGeniusDay() internal view returns (uint256) {
        if (block.timestamp < LAUNCH_TIMESTAMP) revert ErrorNotLaunchedYet();
        unchecked {
            return (block.timestamp - LAUNCH_TIMESTAMP) / 1 days;
        }
    }

    /**
     * @dev PUBLIC FACING VIEW, view function that returns the total reserved supply accounting
     */
    function reserveSupply() external view returns (uint256) {
        unchecked {
            return totalSupply() + calendar.burnedSupply() + advLockedSupply + basicLockedSupply;
        }
    }

    /**
     * @dev Claims for initial GENI distribution
     * @param destination is the claimant, based on off chain data
     * @param amount claimant's amount of GENI to distribute
     * @param merkleProof array of hashes up the merkleTree
     * @param mintNft  The EOA's preference of whether or not to spend gas for
     *                 the chance of minting an NFT.
     */
    function claimGenius(
        address destination,
        uint256 amount,
        bytes32[] calldata merkleProof,
        bool mintNft
    ) external nonReentrant {
//        require(canClaim(destination, amount, merkleProof), "I");
        if (!canClaim(destination, amount, merkleProof)) {
            revert NoClaimExists();
        }

        claimed[destination] = true;

        if (destination == msg.sender || _currentGeniusDay() < 181 ||
            (block.timestamp < LAUNCH_TIMESTAMP && destination == LGENI_OA))
        {
            ERC20(address(this)).transfer(destination, amount);
            if (mintNft) {
                _gnftContract.mintNft(destination, 0);
            }
            emit Claim(msg.sender, destination, amount);
            return;
        }

        // Sender may get an NFT if they opted-into minting :)
        if (mintNft && _probability(msg.sender, PHI_NPOW_2, PHI_PRECISION, 0, 0)) {
            _gnftContract.mintNft(msg.sender, 1);
        }

        unchecked {
            // the msg.sender will receive 100 GENI, and the remainder goes to the
            // lazy owner of the claim :)
            ERC20(address(this)).transfer(msg.sender, 100000000000);
            ERC20(address(this)).transfer(destination, amount - 100000000000);
        }
        emit Claim(msg.sender, destination, amount);
    }

    /**
     * @dev helper for validating if an address has GENI to claim
     * @return true if claimant has not already claimed and the data is valid, false otherwise
     */
    function canClaim(
        address destination,
        uint256 amount,
        bytes32[] calldata merkleProof
    ) public view returns (bool) {
        bytes32 node = keccak256(abi.encodePacked(destination, amount));
        return
            !claimed[destination] &&
            MerkleProof.verify(merkleProof, MERKLE_ROOT, node);
    }

    /**
     * @dev only callable by auction contract.  Mints Genius token.
     */
    function mint(address owner, uint256 amount) external {
        if (msg.sender != auctionAddress) revert ErrorUnauthorized();
        _mint(owner, amount);
    }

    /**
     * @dev only callable by stability pool, auction, miners, or hexodus.
     *      Burns Genius token.
     */
    function burn(address owner, uint256 amount) external {
        if (
            msg.sender != stabilityPoolAddress &&
            msg.sender != auctionAddress &&
            msg.sender != minersAddress &&
            msg.sender != hexodusAddress
        ) {
            revert ErrorUnauthorized();
        }
        _burn(owner, amount);
    }


    /**
     * @dev INTERNAL, calculates new share rate based on eem payout
     */
    function _newShareRate(MinerCache memory miner, uint256 neemPayout) internal view returns(uint256 newShareRate) {
        unchecked {
            newShareRate = (neemPayout * PHI_PRECISION +
                _min(
                    neemPayout * PHI_POW_PHI,
                    (neemPayout *
                        _min(
                            4444 * PHI_PRECISION,
                            _ceiling(
                                miner.promiseDays *
                                    (PHI_PRECISION + PHI_NPOW_3),
                                PHI_PRECISION
                            ) - PHI_PRECISION
                        )) /
                        1456
                ) +
                neemPayout * _min(neemPayout * PHI_PRECISION, PHI * 10**17) / 10**18) /
                miner.rewardShares /
                PHI_PRECISION;
            return newShareRate;
        }
    }

    /**
     * @dev manage share rate calculations for end miner functionality
     */
    function _manageSystemShares(
        MinerCache memory miner,
        uint256 currentGeniusDay,
        uint256 eemPenalty,
        uint256 lemPenalty,
        uint256 rewards
    ) internal {
        if (miner.lemClaimDay == 0) {
            if (!miner.policy) {
                calendar.decBasicShares(miner.rewardShares);
            } else {
                calendar.decAdvShares(miner.rewardShares);
            }
        }
        unchecked {
            uint256 neemPayout = miner.principal + rewards -
                (currentGeniusDay < miner.startDay + miner.promiseDays ? eemPenalty : 0);
    //        uint256 neemPayout = _neemPayout(
    //            miner.principal,
    //            rewards,
    //            currentGeniusDay,
    //            miner.startDay + miner.promiseDays,
    //            eemPenalty
    //        ); // NEEMP - Non-Early End Mining Payout

            if (neemPayout >= miner.principal) {
                // calculate new Share Rate
                calendar.setShareRate(_newShareRate(miner, neemPayout));
            }
        }
    }

    /**
     * @dev send collateral miner payouts for ended miners
     */
    function _manageCollateralMinerPayouts(
        address owner,
        uint256 netPrincipalPayout,
        uint256 netRewardsPayout,
        bool benevolence
    ) internal {
        if (!benevolence) {
            // if net principal payout > 0:
            //      mint ( principal + rewards )
            if (netPrincipalPayout > 0) {
                unchecked {
                    _mint(owner, netPrincipalPayout + netRewardsPayout);
                }
            }

            // if net rewards payout > 0:
            //      decrease burned supply ( net rewards payout )
            if (netRewardsPayout > 0) {
                calendar.decreaseBurnedSupply(netRewardsPayout);
            }
        }
    }

    /**
     * @dev send miner payouts foe ended miners
     */
    function _manageMinerPayouts(
        MinerCache memory miner,
        address owner,
        uint256 eemPrincipalFee,
        uint256 lemPrincipalFee,
        uint256 eemRewardFee,
        uint256 lemRewardFee,
        uint256 rewards,
        bool benevolence
    ) internal returns (uint256 netPrincipalPayout, uint256 netRewardsPayout) {
        unchecked {
            uint256 principalPenalties = _max(eemPrincipalFee, lemPrincipalFee + penaltyContract.calcLemClaimed(miner));
            uint256 rewardPenalties = _max(eemRewardFee, lemRewardFee);
            netPrincipalPayout = miner.principal > principalPenalties ? miner.principal - principalPenalties : 0;
            netRewardsPayout = rewards > rewardPenalties ? rewards - rewardPenalties : 0;

            if (miner.lemClaimDay == 0) {
                // NOTE: the Release Shares function is responsible for moving the
                // entire principal out of the Locked Supply--because that principal
                // is no-longer "locked".  However, when LEM Claim Day is not set,
                // then the Release Shares function was not called, and the miner's
                // principal must be completely removed from the locked supply.

                if (miner.policy) {
                    // NOTE: the Principal Penalties will STILL be removed from
                    // the locked supply.  In other words, the entire principal
                    // must be removed.  The Lucid Chart specs were wrong;
                    // remove the entire supply.
                    advLockedSupply -= miner.principal;
                } else {
                    // NOTE: the entire principal should be removed from any of
                    // the Locked supplies because the principal is no-longer
                    // "locked".  Of course, any principal that does not get
                    // "minted" to the EOA or OA will need to be added to the
                    // Burned Supply.
                    basicLockedSupply -= miner.principal;
                }

                if (netRewardsPayout > 0 && !benevolence) {
                    calendar.decreaseBurnedSupply(netRewardsPayout);
                }

                // NOTE: if this is Benevolence, then is the entire principal must
                // be moved over to the Burned Supply.
                if (benevolence) {
                    calendar.increaseBurnedSupply(miner.principal);
                }
                else {
                    // But when the miner was not ended benevolently, then we will
                    // increase the burned supply by only the principal penalties,
                    // which *will not* include the LEM Claim Reward.  That reward
                    // will not be included in the 'principalPenalties' calculation
                    // because the lemClaimDay property is 0 :)
                    calendar.increaseBurnedSupply(principalPenalties);
                }
            } else {
                // WARNING: in this scope, the shares were released by the Release
                // Shares function, and therefore, all principal (minus the LEM
                // Claim Reward) was already moved over to the Burned Supply.

                // THEREFORE: we will not increase the Burned Supply here.  We will
                // only decrease the burned supply by the amount of principal and
                // rewards that get removed from the Burned Supply.

                // NOTE: When a non-collateral miner ends, if the shares were
                // released, like in this conditional scope, then the entire
                // principal was already unlocked and moved over to the burned
                // supply.  Therefore, we need to remove any principal (and rewards)
                // that will be minted out of the Burned Supply.
                calendar.decreaseBurnedSupply(netPrincipalPayout + netRewardsPayout);
            }

            // NOTE: all "penalized principal" must move over to the Burned Supply,
            // except for the LEM Claim Reward, because that was given to the EOA
            // that called the Release Shares function.  Furthermore, the payout
            // accounting is handled automatically by _mint -- Total Supply will be
            // increased, and the amount increased was already removed, or not added
            // to, the Burned Supply in the scope, above.

            if (!benevolence && netPrincipalPayout + netRewardsPayout > 0) {
                _mint(owner, netPrincipalPayout + netRewardsPayout);
            }
        }
    }

    /**
     * @dev extended logic for endMiner() function
     * @param  owner  the owner of the miner -- it is the responsibility of the
     *                external functions that call this function to provide end
     *                user security.  Only the msg sender can end a miner.
     * @param  minerIndex   miner index
     * @param  rewards      all performance rewards earned during this miner's
     *                      serving period.
     * @param  benevolence  is this miner ending for the sake of benevolence?
     *                      then anything minted will be burned.
     * @param  mintNft      end user opt-in to spend gas and possibly get an NFT
     */
    function _endMinerDeep(address owner, uint256 minerIndex, uint256 rewards, bool benevolence, bool mintNft) internal
        returns (
            uint256 netPrincipalPayout, uint256 netRewardsPayout, uint256 penaltyToMiners
        ) {
        MinerCache memory miner = minersContract.minerStore(owner, minerIndex);
        unchecked {
            uint256 currentGeniusDay = _currentGeniusDay();
            uint256 servedDays = (
                currentGeniusDay < (miner.startDay + miner.promiseDays)
                    ? currentGeniusDay
                    : (miner.startDay + miner.promiseDays)
                ) - miner.startDay;

            // EM_03
            PenaltyData memory ptData = penaltyContract.endMinerPenalties(miner, servedDays, currentGeniusDay, rewards);

            // EM_04
            if (servedDays < miner.promiseDays) {
                // @dev miner is ending early.
                penaltyToMiners = _redistribution(miner, rewards, ptData.eemPrincipalFee, ptData.eemRewardFee);

                if (mintNft) {
                    if (_probability(owner, PHI / (miner.policy ? 10 : 100),
                        PHI_PRECISION, miner.principal, 0))
                    {
                        _gnftContract.mintNft(owner, 1);
                    }
                    else if (benevolence &&
                        _probability(owner, PHI_PRECISION, PHI_PRECISION, miner.principal, 2))
                    {
                        _gnftContract.mintNft(owner, 1);
                    }
                }
            } else {
                if (currentGeniusDay > miner.startDay + miner.promiseDays + 7) {
                    // @dev miner ended late and will serve late penalties.
                    penaltyToMiners = _redistribution(miner, rewards, ptData.lemPrincipalFee, ptData.lemRewardFee);

                    if (mintNft) {
                        bool minted = false;
                        if (benevolence) {
                            if (_probability(owner, PHI / 10, PHI_PRECISION, miner.principal, 10)) {
                                _gnftContract.mintNft(owner, 11);
                                minted = true;
                            }
                        }

                        if (!minted) {
                            if (_probability(owner, PHI / (miner.policy ? 10 : 100),
                                PHI_PRECISION, miner.principal, 0))
                            {
                                _gnftContract.mintNft(owner, 1);
                            }
                        }
                    }
                } else {
                    // @dev miner ended on time, as promised by the EOA.

                    // if the EOA opted-in to mint an NFT...
                    if (mintNft) {
                        // if this miner had 90 or more promise days...
                        if (miner.promiseDays > 89) {
                            // NOTE: if someone created a BASIC miner w/ 89 Promise
                            // Days on Day 0, then they get a free day and free NFT
                            // ...lucky!! :D
                            if (_probability(owner, PHI_PRECISION, PHI_PRECISION,
                                miner.principal, 0))
                            {
                                _gnftContract.mintNft(owner, 1);
                            }

                            // ALSO NOTE: if this end is a result of benevolence,
                            // then there will be another round of chance.
                            if (benevolence) {
                                if (_probability(owner, PHI_PRECISION, PHI_PRECISION,
                                    miner.principal, 3))
                                {
                                    _gnftContract.mintNft(owner, 4);
                                }
                            }
                        }
                        else if (_probability(owner, PHI / 100, PHI_PRECISION,
                            miner.principal, 0))
                        {
                            // Promise days will be < 90, and therefore this must be a
                            // Basic Miner.
                            _gnftContract.mintNft(owner, 1);
                        }
                        else if (benevolence && _probability(
                            owner, PHI_PRECISION, PHI_PRECISION, miner.principal, 20))
                        {
                            // if this condition is met, then this is a basic miner
                            // that was Proof Of Benevolence'd.
                            _gnftContract.mintNft(owner, 1);
                        }
                    }
                }
            }

            // EM_05 Manage System Shares
            _manageSystemShares(
                miner,
                currentGeniusDay,
                ptData.eemPenalty,
                ptData.lemPenalty,
                rewards
            );

            if (miner.debtIssueRate > 0) {
                // EM_06B Manage Collateral Payouts
                (netPrincipalPayout, netRewardsPayout) = _manageCollateralPayouts(
                    miner, owner, minerIndex, rewards,
                    ptData.lemPrincipalFee, ptData.lemRewardFee, benevolence);
            } else {
                // EM_06A Manage Payouts
                // uint256 principalPenalties = _max(eemPrincipalFee, lemPrincipalFee + lemClaimed);
                // address localOwner = owner;
                uint256 rewards = rewards;
                bool benevolence = benevolence;
                (netPrincipalPayout, netRewardsPayout) = _manageMinerPayouts(
                    miner,
                    owner,
                    ptData.eemPrincipalFee,
                    ptData.lemPrincipalFee,
                    ptData.eemRewardFee,
                    ptData.lemRewardFee,
                    rewards,
                    benevolence
                );
            }
        }
    }

    function _manageCollateralPayouts(
        MinerCache memory _miner,
        address _owner,
        uint256 _minerIndex,
        uint256 _rewards,
        uint256 _principalPenalties,
        uint256 _rewardPenalties,
        bool _benevolence
    ) internal returns (uint256 netPrincipalPayout, uint256 netRewardsPayout) {

        unchecked {
            uint256 rewardPenalties = _min(_rewards, _principalPenalties + _rewardPenalties);
            uint256 currentGeniusDay = _currentGeniusDay();

            // EM_06B
            if (_miner.lemClaimDay == 0) {
                advLockedSupply -= _miner.principal;
            }

            /*
                Utilities.MinerCache calldata miner,
                address minerOwner,
                uint256 minerIndex,
                address beneficiary,
                uint256 currentGeniusDay,
                bool benevolent
            */
            address owner = _owner;
            uint256 minerSettlementAmount = stabilityPoolContract.clearGeniusDebt(
                _miner, owner, _minerIndex, owner,
                currentGeniusDay, _benevolence);
    //        netPrincipalPayout = availablePrincipal > minerSettlementAmount ? availablePrincipal - minerSettlementAmount : 0;
            netPrincipalPayout = _miner.principal > minerSettlementAmount ?
                _miner.principal - minerSettlementAmount : 0;

            // NOTE: _rewardPenalties is what was passed as a parameter, it is NOT
            // the recalculated local variable.  Use the local variable that was a
            // recalculation of the Reward Penalties.
            netRewardsPayout = _rewards - rewardPenalties;
            _manageCollateralMinerPayouts(owner, netPrincipalPayout, netRewardsPayout, _benevolence);
        }
    }

    /**
     * @dev handle miner end functionalities
     * @param  minerIndex   index of the miner
     * @param  benevolence  is the miner benevolenced?
     * @param  mintNft      end user opt-in to spend gas and possibly get an NFT
     */
    function endMiner(
        uint256 minerIndex,
        bool benevolence,
        bool mintNft
    ) external nonReentrant {
        MinerCache memory miner = minersContract.minerStore(msg.sender, minerIndex);
        unchecked {
            uint256 currentGeniusDay = _currentGeniusDay();

            // Promise End Day = miner.startDay + miner.promiseDays
            // Served Days = MIN(Current Genius Day, Promise End Day) - miner.startDay
            // NOTE: if the miner index is invalid, then the "servedDays" value will
            // result in 0.
            uint256 servedDays = (
                currentGeniusDay < (miner.startDay + miner.promiseDays)
                    ? currentGeniusDay
                    : (miner.startDay + miner.promiseDays)
            ) - miner.startDay;

            // Start EM_01
            minersContract.checkMinerForEnd(
                miner,
                msg.sender,
                minerIndex,
                currentGeniusDay,
                servedDays
            );

            // Start Phase EM_02 Summarize Served Days
            //uint256 lastServedDay = miner.startDay + servedDays - 1;
            uint256 lastSummarizedDay = calendar.geniusDay() - 1;

            // if the miner is ending early OR the miner is ending beyond the grace period...
            if (servedDays < miner.promiseDays || miner.startDay + miner.promiseDays + 7 <= currentGeniusDay) {
                //calendar.localSummarizeGeniusDay(_currentGeniusDay() - lastServedDay, msg.sender);
                //calendar.localSummarizeGeniusDay(_currentGeniusDay() - (miner.startDay + servedDays - 1), msg.sender);

                calendar.localSummarizeGeniusDay(0, msg.sender, mintNft);
                calendar.local10daySummary(0, msg.sender, mintNft);
                calendar.local100daySummary(0, msg.sender, mintNft);
                calendar.local1000daySummary(0, msg.sender, mintNft);
            }
            else {
                // NOTE: when the miner ends "on-time", we won't catch-up and
                // summarize every single day, 10-day, 100-day, and 1,000-day
                // period summary.  Instead, since the owner of the miner was a
                // "good end user" and did the "good thing" by ending on-time, we
                // will only summarize the days and periods that enclose the days
                // served.
                //
                // Therefore, we must do this before we calculate the Total PPS and
                // rewards:
                //
                // 1) summarize all single-day summaries: only summarize the served
                //    days that have not yet been summarized.
                //if (lastServedDay > lastSummarizedDay) {
                uint256 lastServedDay = miner.startDay + servedDays - 1;
                if (lastServedDay > lastSummarizedDay) {
                    //calendar.localSummarizeGeniusDay(lastServedDay - lastSummarizedDay, msg.sender);
                    calendar.localSummarizeGeniusDay(
                        lastServedDay - lastSummarizedDay,
                        msg.sender,
                        mintNft
                    );
                }

                // 2) Summarize all full 10-day periods within the SERVED DAYS.
                //    Therefore, if the miner served all days (including) 100-415
                //    and we realize that the only 10-day summaries that exist are
                //    for all days prior to 390, then we must create the 10-day
                //    summary for 390-399 (index 39) and 400-409 (index 40).
                //    Summary 410-419 (index 41) WILL NOT BE CREATED because the
                //    miner did not serve the entire period of days 410-419; that
                //    miner only served days 410-415.  We also won't summarize the
                //    index 41 to save the end user gas :)  And because the end user
                //    does not need index 41 to calculate their Total PPS.
                    // Dai Proving the calculation of index and full period
                    // Summaring example and index and period change
                    // startDay = 0, servedDays = 10, lastServedDay = 9 =>
                    //      10summary index 0, period 1
                    //      100summary index 0, period 1
                    //      1000summary index 0, period 1
                    // startDay = 0, servedDays = 100, lastServedDay = 99 =>
                    //      10summary index 9, period 10
                    //      100summary index 9, period 0
                    //      1000summary index 9, period 0
                    // ... ...
                    // start day = 100, servedDays = 316 lastServedDay = startDay + servedDays - 1 = 415 =>
                    //      10summary index 41, period 42
                    //      100summary index 4, period 5
                    //      1000summary index 0, period 0
                    // Generalizing....
                    // maxXIndex = (miner.startDay +servedDays - 1) / X-days;
                    // maxXPeriod = max10Index + 1 = (miner.startDay +servedDays - 1) / X-days + 1;
                    // actualXPeriod = maxXPeriod - 1 = (miner.startDay +servedDays - 1) / X-days + 1 - 1 = (miner.startDay +servedDays - 1) / X-days
                    calendar.local10daySummary(lastServedDay / 10, msg.sender, mintNft);

                // 3) Just like with the 10-day periods, we must summarize all
                //    100-day periods that the miner needs to calculate the Total
                //    PPS / rewards, properly.
                    calendar.local100daySummary(lastServedDay / 100, msg.sender, mintNft);

                // 4) And then, finally, we must make sure that all 1,000-day
                //    periods within the SERVED DAYS are summarized.
                    calendar.local1000daySummary(lastServedDay / 1000, msg.sender, mintNft);
            }

            //calendar.minerTotalPps(miner.startDay, lastServedDay, miner.policy)
            uint256 totalMinerPps = calendar.minerTotalPps(miner.startDay, (miner.startDay + servedDays - 1), miner.policy);
            uint256 rewards = miner.rewardShares * totalMinerPps / SHARE_PRECISION;

            // End Phase EM_02
            (
                uint256 netPrincipalPayout,
                uint256 netRewardsPayout,
                uint256 penaltyToMiners
            )
            = _endMinerDeep(msg.sender, minerIndex, rewards, benevolence, mintNft);
            MinerCache memory miner2 = miner;
            emit EndMiner(msg.sender, minerIndex, benevolence,
                netPrincipalPayout, rewards,
                netRewardsPayout, penaltyToMiners, miner2);
        }
    }

    /**
     * @dev calculates late end mining penalties
     */
    function _penaltiesLem(
        uint256 geniusDay,
        uint256 promiseEndDay,
        uint256 principal,
        uint256 penalties,
        bool policy
    ) internal pure returns (uint256) {
        unchecked {
            uint256 lateDays = geniusDay - promiseEndDay - 7;
            uint256 min;

            if (!policy) {
                uint256 ceil = (principal * PHI * 100) / (7 * PHI_PRECISION);
                ceil =
                    ((ceil + GENIUS_PRECISION) - GENIUS_PRECISION) *
                    GENIUS_PRECISION;
                min = ceil > principal ? principal : ceil;
            } else {
                uint256 ceil = (principal * PHI_POW_2 * 100) / (7 * PHI_PRECISION);
                ceil =
                    ((ceil + GENIUS_PRECISION) - GENIUS_PRECISION) *
                    GENIUS_PRECISION;
                min = ceil > principal ? principal : ceil;
            }
            return (penalties / 1000) - (lateDays * min);
        }
    }

    /**
     * @dev mint amount stored in oaMintableBalance to the oaBeneficiary
     */
    function claimLostMintBonus() external nonReentrant {
// NOTE: converting this to a revert saves ... only 2 bytes :(
//        require(
//            msg.sender == oaGrantor &&
//            _currentGeniusDay() > 31 &&
//            oaMintableBalance > 0
//        , "u");
        if (msg.sender != oaGrantor ||
            _currentGeniusDay() < 32 ||
            oaMintableBalance == 0)
        {
            revert UnauthorizedLostBonusClaiming();
        }

// NOTE: combining these saves 0.039 KB
//        require(msg.sender == oaGrantor, "u");
//        require(_currentGeniusDay() > 31 && oaMintableBalance > 0, "o");
        _mint(oaBeneficiary, oaMintableBalance);
        oaMintableBalance = 0;
    }

    /**
     * @dev only callable by miners, increase oaMintableBalance
     */
    function incOaMintableBalance(uint256 bonusLostForever) external {
        if (msg.sender != minersAddress) revert ErrorUnauthorized();
        oaMintableBalance += bonusLostForever;
    }

    /**
     * @dev PUBLIC FACING, executes releaseShares core functionality (releases shares from pool)
     * @param  owner    owner of the miner that has the shares to be released.
     * @param  minerId  the INDEX of the owner's miner
     * @param  mintNft  end user opt-in to spend gas and possibly get an NFT
     */
    function releaseShares(address owner, uint256 minerId, bool mintNft) external nonReentrant {
        /*
            Inspect the lucid chart spec carefully, and be sure to update the flow and implementation of the RED TEXT AREAS.
            https://lucid.app/lucidchart/f1a1439e-e956-4a2c-be2f-e5dba66cc6a5/edit?view_items=0ccNMa7ilC91&invitationId=inv_5b23c2b2-e19b-434c-b6a4-9fcc5f90496c#

            For accounting references, check out the "Release Shares Burning Principal" sub-sheet.
            https://docs.google.com/spreadsheets/d/16JXDzM2PwEOQD-324uwTPVYQbhWbUWnavtKcusaWjzs/edit?usp=sharing
         */
        // Require: Miner Ended is False
        MinerCache memory miner = minersContract.minerStore(owner, minerId);
        unchecked {
    // NOTE: combining the 3 requires below saves 0.078 KB.
    //        require(miner.ended == 0, "f");

            // Require: Miner LEM Claim Day == 0
    //        require(miner.lemClaimDay == 0, "L");

            uint256 promiseEndDay = miner.startDay + miner.promiseDays;
            uint256 cgd = _currentGeniusDay();

            // Require: CGD >= Promise End Day
    //        require(cgd >= promiseEndDay, "E");
            if (miner.auctioned && miner.nonTransferable) {
                revert ErrorCannotReleaseAuctionedShares();
            }
            if (
                miner.ended > 0 ||
                miner.lemClaimDay > 0 ||
                cgd < promiseEndDay ||
                miner.promiseDays == 0
            ) {
                revert ErrorCannotReleaseShares();
            }

            // Set the Miner LEM Claim Day to CGD
            minersContract.setMinerStoreLemClaimDay(owner, minerId, cgd);

            // Calculate Daily Late Fee
            uint256 ceil;
            if (miner.policy) {
                // Need to consider PHI precision
                ceil = _ceiling(miner.principal * PHI_POW_2 / 7 / 100, PHI_PRECISION) / PHI_PRECISION;
            } else {
                // Need to consider PHI precision
                ceil = _ceiling(miner.principal * PHI / 7 / 100, PHI_PRECISION) / PHI_PRECISION;
            }

            // Calculate the LEM Release Reward

            // lemReleaseReward = MIN(principal, lateDayCount * dailyLateFee)
            // NOTE: dailyLateFee = MIN(principal, CEILING(calculation here))
            uint256 lemReleaseReward = _min(miner.principal, (cgd > promiseEndDay + 7 ? cgd - promiseEndDay - 7 : 0)
                * _min(miner.principal, ceil));

            // Check if the miner is under auction and the auction has zero bids.
            if (miner.auctioned) {
                if (auctionHouse.verifyAuctionNoBid(owner, minerId)) {
                    auctionHouse.cancelAuction(owner, minerId);
                }
            }

            // Enforce that at least the first day of the miner was summarized.
            // This prevents a possible underflow when removing the shares from the
            // calendar's share pool.
            uint256 gDay = calendar.geniusDay();
            if (gDay < miner.startDay + 1) {
                calendar.localSummarizeGeniusDay(miner.startDay + 1 - gDay, msg.sender, mintNft);
            }

            if (miner.policy) {
                advLockedSupply -= miner.principal;
                calendar.decAdvShares(miner.rewardShares);
            } else {
                basicLockedSupply -= miner.principal;
                calendar.decBasicShares(miner.rewardShares);
            }

            uint256 minerSettlementAmount;
            if (miner.debtIssueRate > 0) {
                if (lemReleaseReward > 0) {
                    address colToken = stabilityPoolContract.getMinerColAddress(owner, minerId);
                    minerSettlementAmount =
                        stabilityPoolContract.settleGeniusDebt(msg.sender, colToken, lemReleaseReward, cgd - miner.startDay, false);
                    lemReleaseReward = _min(minerSettlementAmount, lemReleaseReward);
                }
            } else {
                calendar.increaseBurnedSupply(miner.principal > lemReleaseReward ? miner.principal - lemReleaseReward : 0);
                if (lemReleaseReward > 0) {
                    _mint(msg.sender, lemReleaseReward);
                }
            }

            if (mintNft && _probability(msg.sender, PHI_NPOW_3, PHI_PRECISION, 0, 0)) {
                _gnftContract.mintNft(msg.sender, 1);
            }

            // By checking the event param, we can have people know that if there is no debt to settle, they actually get no reward.
            emit LemRewardsClaim(msg.sender, owner, minerId, lemReleaseReward);
        }
    }

    /**
     * @dev round up or ceil a number with the precision specified.
     * @param a number to be rounded up or ceiled
     * @param m precision (10^x, where x >= 0) of ceiling the number
     * @return ceiled value
     */
    function _ceiling(uint256 a, uint256 m) internal pure returns (uint256) {
        //return ((a + m - 1) / m) * m;
        unchecked {
            return (a / m + (a % m == 0 ? 0 : 1)) * m;
        }
    }

    /**
     * @dev compare two numbers and return smaller one.
     * @param a number a
     * @param b number b
     * @return smaller value
     */
    function _min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev compare two numbers and return greater one.
     * @param a number a
     * @param b number b
     * @return greater value
     */
    function _max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev PUBLIC FACING, executes shutdownMiner core functionality
     * @param owner owner of the miner
     * @param minerId ID(index) of the miner
     */
    function shutdownMiner(address owner, uint256 minerId, bool mintNft)
        external nonReentrant
    {
        MinerCache memory miner = minersContract.minerStore(owner, minerId);
        unchecked {
            // First Late Day = Start Day + Promise Days + 7
            uint256 forcedShutdownDay = miner.policy ?
                miner.startDay + miner.promiseDays + 275 :
                miner.startDay + miner.promiseDays + 440;

            if (
                _currentGeniusDay() < forcedShutdownDay ||
                miner.ended > 0 ||
                miner.auctioned ||
                miner.promiseDays == 0
            ) {
                revert CannotShutdown();
            }

            ShutdownDataCache memory shutdownData =
                _shutdownMiner(miner, owner, minerId, forcedShutdownDay, mintNft);

            if (mintNft && _probability(msg.sender, PHI_NPOW_3, PHI_PRECISION, 0, 0)) {
                _gnftContract.mintNft(msg.sender, 1);
            }

            _mintTokenToOa(owner, minerId, shutdownData.principalToRedistribute,
                shutdownData.rewardsToRedistribute, shutdownData.txPrincipalRewards,
                shutdownData.txPerformanceRewards, miner);
        }
    }

    function _shutdownMiner(
        MinerCache memory miner,
        address owner,
        uint256 minerId,
        uint256 forcedShutdownDay,
        bool mintNft
    ) private returns (ShutdownDataCache memory shutdownData) {
        // Set Miner "ended" to the current time
        minersContract.setMinerEnded(owner, minerId, block.timestamp);
        miner.ended = block.timestamp;
        penaltyContract.decMinerPopulation(miner.principal);
        uint256 lemClaimed = penaltyContract.calcLemClaimed(miner);

        // Before we calculate the rewards, we need to be sure that all
        // SERVED DAYS are Summarized.
        //
        // Then we must make sure all 10-day periods within the SERVED DAYS
        // are also summarized.
        //
        // Then we must make sure all 100-day periods within the SERVED DAYS
        // are summarized.
        //
        // And then, finally, we must make sure that all 1,000-day periods
        // within the SERVED DAYS are summarized.
        calendar.summarizeServedDays(msg.sender, miner.startDay,
            miner.promiseDays, mintNft);
        unchecked {
            uint256 netPrincipal = miner.principal > lemClaimed ? miner.principal - lemClaimed : 0;
            uint256 rewards = miner.rewardShares *
                calendar.minerTotalPps(miner.startDay, miner.startDay + miner.promiseDays - 1, miner.policy)
                / SHARE_PRECISION;
            uint256 netPayout = netPrincipal + rewards;

            // Start Phase EM_04
            _manageShutdownMinerShares(miner, forcedShutdownDay, rewards);
            // End Phase EM_04

            uint256 maxTxRewards = netPayout * PHI_NPOW_3 / PHI_PRECISION;
            shutdownData.txPrincipalRewards = _min(netPrincipal, maxTxRewards);

            if (miner.debtIssueRate > 0) {
                /*
                    Utilities.MinerCache calldata miner,
                    address minerOwner,
                    uint256 minerIndex,
                    address beneficiary,
                    uint256 currentGeniusDay,
                    bool benevolent
                */

                MinerCache memory miner2  = miner;
                bool mintNft2 = mintNft;
                address owner2 = owner;
                uint256 minerId2 = minerId;

                uint256 txSettledRewards = stabilityPoolContract.settleGeniusDebt(
                    msg.sender,
                    stabilityPoolContract.getMinerColAddress(owner2, minerId2),
                    shutdownData.txPrincipalRewards,
                    _currentGeniusDay() - miner2.startDay,
                    mintNft2
                );

                uint256 minerDebtCleared = stabilityPoolContract.clearGeniusDebt(
                    miner2, owner2, minerId2, address(0),
                    _currentGeniusDay(), true);

                shutdownData.txPerformanceRewards = maxTxRewards > txSettledRewards ? maxTxRewards - txSettledRewards : 0;
                shutdownData.txPrincipalRewards -= txSettledRewards;
                // shutdownData.principalToRedistribute = netPrincipal - txSettledRewards - minerDebtCleared -
                // (shutdownData.txPrincipalRewards - txSettledRewards)
                // = netPrincipal - minerDebtCleared - shutdownData.txPrincipalRewards
                // it might be underflow
                uint256 totalSub = txSettledRewards + minerDebtCleared + shutdownData.txPrincipalRewards;
                if (netPrincipal > totalSub) {
                    shutdownData.principalToRedistribute = netPrincipal - totalSub;
                    calendar.increaseBurnedSupply(shutdownData.principalToRedistribute);
                } else {
                    shutdownData.principalToRedistribute = 0;
                }
                shutdownData.rewardsToRedistribute = rewards > shutdownData.txPerformanceRewards ? rewards - shutdownData.txPerformanceRewards : 0;

                if (miner2.lemClaimDay == 0) {
                    if (miner2.policy) {
                        advLockedSupply -= miner2.principal;
                    } else {
                        basicLockedSupply -= miner2.principal;
                    }
                }
            } else { // Debt Issue Rate == 0
                shutdownData.txPerformanceRewards = maxTxRewards > netPrincipal ? maxTxRewards - netPrincipal : 0;
                shutdownData.principalToRedistribute = netPrincipal > shutdownData.txPrincipalRewards ? netPrincipal - shutdownData.txPrincipalRewards : 0;
                shutdownData.rewardsToRedistribute = rewards > shutdownData.txPerformanceRewards ? rewards - shutdownData.txPerformanceRewards : 0;

                if (miner.lemClaimDay == 0)  {
                    calendar.increaseBurnedSupply(miner.principal);
                    if (miner.policy) {
                        advLockedSupply -= miner.principal;
                    } else {
                        basicLockedSupply -= miner.principal;
                    }
                }
            }
        }

    }

    function _mintTokenToOa(
        address owner,
        uint256 minerId,
        uint256 principalToRedistribute,
        uint256 rewardsToRedistribute,
        uint256 txPrincipalRewards,
        uint256 txPerformanceRewards,
        MinerCache memory miner
    ) private {
        unchecked {
            uint256 totalPenalties = principalToRedistribute + rewardsToRedistribute;
            uint256 redistributedPenalties = totalPenalties * PHI_PRECISION / PHI;
            calendar.incDailyPenalties(redistributedPenalties);
            uint256 toOa = totalPenalties - redistributedPenalties - (totalPenalties * PHI_NPOW_3 / PHI_PRECISION);
            uint256 resurrection = toOa + txPrincipalRewards + txPerformanceRewards;

            if (resurrection > 0) {
                calendar.decreaseBurnedSupply(resurrection);
            }

            if (toOa > 0) {
                _mint(oaBeneficiary, toOa);
            }

            // we will not check if txPerf + txPrinc is > 0 because if this is the
            // case, then the miner was likely a stale, "dust" miner with not much
            // principal and likely zero earnings.
            _mint(msg.sender, txPerformanceRewards + txPrincipalRewards);

            emit ShutdownMiner(owner, minerId, msg.sender,
                txPrincipalRewards, txPerformanceRewards,
                redistributedPenalties, toOa, (totalPenalties * PHI_NPOW_3 / PHI_PRECISION),
                miner
            );
        }
    }

    /**
     * @dev INTERNAL, helper function used in shutdownMiner()
     */
    function _manageShutdownMinerShares(
        MinerCache memory miner, uint256 forcedShutdownDay, uint256 rewards
    ) internal {
        if (miner.lemClaimDay == 0) {
            if (!miner.policy) {
                calendar.decBasicShares(miner.rewardShares);
            } else {
                calendar.decAdvShares(miner.rewardShares);
            }
        }
        unchecked {
            calendar.setShareRate(_newShareRate(miner, miner.principal + rewards));
        }
    }

    /**
     * @dev only callable by calendar, mint summary rewards calculated by
     * summarize functions in calendar.
     */
    function mintSummaryReward(address _to, uint256 _amount) external {
        if (msg.sender != calendarAddress) {
            revert ErrorUnauthorized();
        }
        _mint(_to, _amount);
    }

    /**
     * @dev only callable by Penalty contract, advLockedSupply accounting.
     */
    function decAdvLockedSupply(uint256 _amount) external {
        if (msg.sender != penaltyAddress) revert ErrorUnauthorized();
        unchecked { advLockedSupply -= _amount; }
    }

    /**
     * @dev only callable by Penalty contract, basicLockedSupply accounting.
     */
    function decBasicLockedSupply(uint256 _amount) external {
        if (msg.sender != penaltyAddress) revert ErrorUnauthorized();
        unchecked { basicLockedSupply -= _amount; }
    }

    /**
     * @dev only callable by Miners contract, advLockedSupply accounting.
     */
    function incAdvLockedSupply(uint256 _amount) external {
        if (msg.sender != minersAddress) revert ErrorUnauthorized();
        unchecked { advLockedSupply += _amount; }
    }

    /**
     * @dev only callable by Miners contract, basicLockedSupply accounting.
     */
    function incBasicLockedSupply(uint256 _amount) external {
        if (msg.sender != minersAddress) revert ErrorUnauthorized();
        unchecked { basicLockedSupply += _amount; }
    }

    /**
     * @dev only called by the End Miner functionality; this redistributes
     * fees incurrred for ending the miner.
     * @param rewards the performance earnings of the miner.
     * @param principalPenalties penalties applied to the principal.
     * @param rewardPenalties penalties applied to the rewards.
     * @return redistributedPenalties the amount of penalties that will be
     * redistributed to Advanced Miners that are currently active.
     */
    function _redistribution(
        MinerCache memory miner,
        uint256 rewards,
        uint256 principalPenalties,
        uint256 rewardPenalties
    ) internal returns (uint256 redistributedPenalties) {
        unchecked {
            uint256 totalPenalties;
            if (miner.debtIssueRate > 0) {
                totalPenalties = _min(rewards, principalPenalties + rewardPenalties);
                rewardPenalties = totalPenalties;
                principalPenalties = 0;
            } else {
                if (miner.lemClaimDay == 0) {
                    if (miner.policy) {
                        advLockedSupply -= principalPenalties;
                    } else {
                        basicLockedSupply -= principalPenalties;
                    }
                    calendar.increaseBurnedSupply(principalPenalties);
                }
                totalPenalties = principalPenalties + rewardPenalties;
            }

            redistributedPenalties = totalPenalties * PHI_PRECISION / PHI;
            calendar.incDailyPenalties(redistributedPenalties);
            uint256 oaReceivingAmount = totalPenalties - redistributedPenalties
                - totalPenalties * PHI_NPOW_3 / PHI_PRECISION;

            _mint(oaBeneficiary, oaReceivingAmount);
            calendar.decreaseBurnedSupply(oaReceivingAmount);
        }
    }

    /**
     * @dev   Calculates a secure-ish random 256-bit number for GENFTs.
     *        These are the motivations and purposes behind each parameter to
     *        calculate the random number:
     *
     *        1. salt: each function that initially invokes the first
     *           _probability / _random functions will originate with its own
     *           unique 'salt'.  This is to ensure that when multiple functions
     *           are called by the EOA within the same transaction, the EOA will
     *           have equally-random chances to yield a completely different
     *           GENFT.  The block timestamp is added to salt to make it more
     *           difficult for an end user to predict which GENFT they'll mint.
     *
     *        2. blockhash: the only EOAs that can reasonably use this to their
     *           advantage without adding significant costs for the transaction,
     *           such as the capital required to create a miner with a weight of
     *           1 or greater, are EOAs that run the function to "claim" their
     *           sacrifie tokens and EOAs that run the function to summarize
     *           a Genius Calendar period.  That is because these functions have
     *           a 100% chance to mint a GENFT.
     *
     *           However, the "claim" function can only be run once per EOA that
     *           participated in the Genius Sacrifice Event.  Therefore, this
     *           will not be useful for the EOA, even if they have the ability
     *           to influence the block hash.  See: https://sacrifice.to
     *
     *           In regards to the Calendar summarize functions, the EOA cannot
     *           waste time figuring out their best chances because if they are
     *           not the first EOA to run the function, then they lose the
     *           ability to run the function for the day/period.
     *
     *           For every other function, the EOA is prevented from spamming
     *           these functions not only from the blockchain's gas fee, but
     *           spam is additional prevented because every other function
     *           has one of the following qualities:
     *              a. It is a "first-come, first-to-benefit" function, e.g. the
     *                 functions to claimAuction, releaseShares, etc.
     *              b. The function is necessary for "cleaning up" or updating
     *                 Genius' environment, active shares, etc., and therefore,
     *                 the EOA should be rewarded as they wish.
     *              c. The EOA had to have input something of value to the
     *                 network, i.e. they had to put up a significant, non-dust
     *                 amount of GENI capital, which ultimately benefitted the
     *                 Genius end users.
     *
     *           Therefore, if it is worth it for the EOA to exert the position-
     *           ing and effort to influence random numbers for their purpose,
     *           then this action is also not guaranteed, and its repeated
     *           action is designed to benefit the Genius end user.  Since the
     *           purpose of GENFTs is purely as collectibles and *not* for
     *           significant financial value, it is perfectly acceptable for
     *           EOAs to "game" the possibilities of yielding the GENFT that
     *           they desire.
     *
     *        3. account: used so that different EOAs running the same GENFT
     *           minting functions within the same block will not generate the
     *           same GENFTs.  Likewise, if different accounts are unpacking
     *           booster/ultimate packs within the same transaction, this will
     *           ensure that the end users do not unpack the same GENFTs.
     *
     *        Finally, it should be noted that the GENFT controller prevents
     *        EOAs from minting GENFTs with the same randomization salt or
     *        unpacking to mint multiple GENFTs within the same block.  This is
     *        done to prevent the end user from duplicating multiple copies of
     *        the same GENFTs.
     *
     * @param account address used to generate a random number
     * @param salt  when multiple random numbers are necessary, this is used
     *                to add some randomness.  This is important because within
     *                a single transaction, the random number will be exactly
     *                the same without this _salt.
     */
    function _random(address account, uint256 salt) internal view returns (uint256) {
        unchecked {
            return uint256(
                keccak256(
                    abi.encodePacked(
                        salt + block.timestamp,
                        blockhash(block.number),
                        account
                    )
                )
            );
        }
    }

    /**
     * @dev     You tell the function the "probability" that something will
     *          happen, and this function tells you if it happened :)
     * @param   account address used for the calculation
     * @param   chances How many chances of successes will there be out of the entire...
     * @param   totals ...range of precision totals?
     * @param   weight will the weight be based on?  Use "0" for no weight.
     * @param   nonce "nonce" so that if this function is called multiple times
     *          within a transaction, the random number will be different each
     *          time this function is invoked.
     * @return  Whether the probability test was succcessful :)
     */
    function _probability(address account, uint256 chances, uint256 totals, uint256 weight, uint256 nonce)
        internal view returns (bool)
    {
        unchecked {
            // STEP 1: increase the weight of the chances if necessary.
            if (weight > 0) {
                chances = chances * penaltyContract.minerWeight(weight)
                    / PENALTY_COUNTER_PRECISION;
            }

            if (chances >= totals) {
                return true;
            }

            // NOTE: beyond this point, chances < totals, and therefore, it is not
            // possible for chances to be equal to or greater than totals, resulting
            // in an overflow.

            // STEP 2: Find a random number between 0 and the totals.
            uint256 random = _random(account, nonce) % totals;

            // STEP 3: Is the random number within the probability range of chance?
            // The minimum that (totals - chances) will be is 1, so therefore, if
            // the random number is 0, then the return value will be false.  In the
            // situation where this is a "1 in X" chance, "random" must be 0 in
            // order for the logical expression (below) to be true.
            return random >= totals - chances;
        }
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_oaGrantor","type":"address"},{"internalType":"address","name":"_oaBeneficiary","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotShutdown","type":"error"},{"inputs":[],"name":"ErrorCannotReleaseAuctionedShares","type":"error"},{"inputs":[],"name":"ErrorCannotReleaseShares","type":"error"},{"inputs":[],"name":"ErrorNotLaunchedYet","type":"error"},{"inputs":[],"name":"ErrorNullAddress","type":"error"},{"inputs":[],"name":"ErrorUnauthorized","type":"error"},{"inputs":[],"name":"NoClaimExists","type":"error"},{"inputs":[],"name":"UnauthorizedLostBonusClaiming","type":"error"},{"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":false,"internalType":"address","name":"newOaBeneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"updated","type":"uint256"}],"name":"ChangeOaBeneficiary","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOaGrantor","type":"address"},{"indexed":false,"internalType":"uint256","name":"updated","type":"uint256"}],"name":"ChangeOaGrantor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"minerIndex","type":"uint256"},{"indexed":false,"internalType":"bool","name":"benevolence","type":"bool"},{"indexed":false,"internalType":"uint256","name":"principalPayout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalMinerRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardsPayout","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penaltyToMiners","type":"uint256"},{"components":[{"internalType":"bool","name":"policy","type":"bool"},{"internalType":"bool","name":"auctioned","type":"bool"},{"internalType":"bool","name":"exodus","type":"bool"},{"internalType":"uint256","name":"startDay","type":"uint256"},{"internalType":"uint256","name":"promiseDays","type":"uint256"},{"internalType":"uint256","name":"lemClaimDay","type":"uint256"},{"internalType":"uint256","name":"rewardShares","type":"uint256"},{"internalType":"uint256","name":"penaltyDelta","type":"uint256"},{"internalType":"bool","name":"nonTransferable","type":"bool"},{"internalType":"uint256","name":"ended","type":"uint256"},{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"debtIssueRate","type":"uint256"}],"indexed":false,"internalType":"struct Utilities.MinerCache","name":"miner","type":"tuple"}],"name":"EndMiner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executorRewardAddress","type":"address"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"minerIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"executorReward","type":"uint256"}],"name":"LemRewardsClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minerAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"minerIndex","type":"uint256"},{"indexed":true,"internalType":"address","name":"executorRewardAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"executorReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"performanceRewards","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redistributedPenalties","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toOa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedForever","type":"uint256"},{"components":[{"internalType":"bool","name":"policy","type":"bool"},{"internalType":"bool","name":"auctioned","type":"bool"},{"internalType":"bool","name":"exodus","type":"bool"},{"internalType":"uint256","name":"startDay","type":"uint256"},{"internalType":"uint256","name":"promiseDays","type":"uint256"},{"internalType":"uint256","name":"lemClaimDay","type":"uint256"},{"internalType":"uint256","name":"rewardShares","type":"uint256"},{"internalType":"uint256","name":"penaltyDelta","type":"uint256"},{"internalType":"bool","name":"nonTransferable","type":"bool"},{"internalType":"uint256","name":"ended","type":"uint256"},{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"debtIssueRate","type":"uint256"}],"indexed":false,"internalType":"struct Utilities.MinerCache","name":"miner","type":"tuple"}],"name":"ShutdownMiner","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"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LAUNCH_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"advLockedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"auctionAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"basicLockedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"calendarAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"destination","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oaBeneficiary","type":"address"}],"name":"changeOaBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOaGrantor","type":"address"}],"name":"changeOaGrantor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"destination","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"},{"internalType":"bool","name":"mintNft","type":"bool"}],"name":"claimGenius","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimLostMintBonus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"decAdvLockedSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"decBasicLockedSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","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":"uint256","name":"minerIndex","type":"uint256"},{"internalType":"bool","name":"benevolence","type":"bool"},{"internalType":"bool","name":"mintNft","type":"bool"}],"name":"endMiner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gnftAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hexodusAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"incAdvLockedSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"incBasicLockedSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bonusLostForever","type":"uint256"}],"name":"incOaMintableBalance","outputs":[],"stateMutability":"nonpayable","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":[],"name":"minersAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintSummaryReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oaBeneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oaGrantor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oaMintableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"penaltyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"minerId","type":"uint256"},{"internalType":"bool","name":"mintNft","type":"bool"}],"name":"releaseShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_auction","type":"address"}],"name":"setAuctionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_calendar","type":"address"}],"name":"setCalendarContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gnftAddress","type":"address"}],"name":"setGnftContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hexodus","type":"address"}],"name":"setHexodusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_minersAddress","type":"address"}],"name":"setMinersContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pcAddress","type":"address"}],"name":"setPenaltyContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stabilityPool","type":"address"}],"name":"setStabilityPoolAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"minerId","type":"uint256"},{"internalType":"bool","name":"mintNft","type":"bool"}],"name":"shutdownMiner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stabilityPoolAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

6101406040523480156200001257600080fd5b50604051620062a1380380620062a18339810160408190526200003591620003ab565b6040518060400160405280600681526020016547656e69757360d01b81525080604051806040016040528060018152602001603160f81b8152506040518060400160405280600681526020016547656e69757360d01b8152506040518060400160405280600481526020016347454e4960e01b8152508160039080519060200190620000c3929190620002e8565b508051620000d9906004906020840190620002e8565b5050825160208085019190912083518483012060e08290526101008190524660a0818152604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81880181905281830187905260608201869052608082019490945230818401528151808203909301835260c0019052805194019390932091935091906080523060601b60c0526101205250506001601a555050506001600160a01b03821615806200019457506001600160a01b038116155b15620001b3576040516342bec4df60e01b815260040160405180910390fd5b601680546001600160a01b038085166001600160a01b0319928316179092556017805492841692909116919091179055620001f830680d02ab486cedc0000062000200565b505062000444565b6001600160a01b0382166200025b5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b80600260008282546200026f9190620003e2565b90915550506001600160a01b038216600090815260208190526040812080548392906200029e908490620003e2565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b828054620002f69062000407565b90600052602060002090601f0160209004810192826200031a576000855562000365565b82601f106200033557805160ff191683800117855562000365565b8280016001018555821562000365579182015b828111156200036557825182559160200191906001019062000348565b506200037392915062000377565b5090565b5b8082111562000373576000815560010162000378565b80516001600160a01b0381168114620003a657600080fd5b919050565b60008060408385031215620003be578182fd5b620003c9836200038e565b9150620003d9602084016200038e565b90509250929050565b600082198211156200040257634e487b7160e01b81526011600452602481fd5b500190565b600181811c908216806200041c57607f821691505b602082108114156200043e57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160601c60e0516101005161012051615e0a6200049760003960006134a9015260006134f8015260006134d30152600061342c01526000613456015260006134800152615e0a6000f3fe608060405234801561001057600080fd5b506004361061030c5760003560e01c806360f1edf71161019d578063a9059cbb116100e9578063d505accf116100a2578063dfcad7ea1161007c578063dfcad7ea146106ad578063e09f0817146106c0578063e954f41d146106d3578063e9c4239b146106de57600080fd5b8063d505accf14610674578063dc38bdb514610687578063dd62ed3e1461069a57600080fd5b8063a9059cbb146105f2578063ad09d65814610605578063b074d2f614610618578063c884ef831461062b578063cb01454b1461064e578063d11d01db1461066157600080fd5b806376df7c321161015657806395d89b411161013057806395d89b41146105b157806396cc563f146105b95780639dc29fac146105cc578063a457c2d7146105df57600080fd5b806376df7c32146105785780637ecebe001461058b578063873f0a331461059e57600080fd5b806360f1edf7146104f057806360f6c4d61461050357806363fcd08a146105165780636f72995f1461052957806370a082311461053c57806372fb9c551461056557600080fd5b806323b872dd1161025c578063379b2c1311610215578063445c101f116101ef578063445c101f146104ae5780634bd0cd42146104b75780635476ea9e146104ca57806357ec85dd146104dd57600080fd5b8063379b2c1314610475578063395093511461048857806340c10f191461049b57600080fd5b806323b872dd1461041c578063269858651461042f5780632c265c88146104425780632ceaaf281461044b578063313ce5671461045e5780633644e5151461046d57600080fd5b80630c6eae62116102c9578063197162be116102a3578063197162be146103e55780631ad03156146103f85780631bf803391461040b578063238bf8e01461041457600080fd5b80630c6eae62146103b757806315df1fca146103ca57806318160ddd146103dd57600080fd5b8063023924c71461031157806303d41eb61461032657806306fdde0314610341578063095ea7b314610356578063096ff58a146103795780630b622ab21461038c575b600080fd5b61032461031f36600461562d565b6106f1565b005b61032e6107c7565b6040519081526020015b60405180910390f35b610349610860565b6040516103389190615b18565b610369610364366004615752565b6108f2565b6040519015158152602001610338565b61032461038736600461562d565b61090c565b60095461039f906001600160a01b031681565b6040516001600160a01b039091168152602001610338565b6103246103c536600461562d565b610ae6565b60115461039f906001600160a01b031681565b60025461032e565b6103246103f33660046159e0565b610bea565b600d5461039f906001600160a01b031681565b61032e60075481565b610324610c21565b61036961042a36600461569d565b610cc1565b61032461043d3660046157d7565b610ce5565b61032e60085481565b60165461039f906001600160a01b031681565b60405160098152602001610338565b61032e6110c4565b60135461039f906001600160a01b031681565b610369610496366004615752565b6110d3565b6103246104a9366004615752565b6110f5565b61032e60195481565b6103246104c536600461562d565b61112e565b600b5461039f906001600160a01b031681565b6103246104eb366004615a10565b6112f0565b6103246104fe36600461562d565b611a95565b61032461051136600461562d565b611b8e565b60175461039f906001600160a01b031681565b61032461053736600461562d565b611c33565b61032e61054a36600461562d565b6001600160a01b031660009081526020819052604090205490565b6103246105733660046159e0565b611d44565b6103246105863660046159e0565b611d7a565b61032e61059936600461562d565b611dbf565b60145461039f906001600160a01b031681565b610349611ddd565b6103246105c736600461562d565b611dec565b6103246105da366004615752565b611f4f565b6103696105ed366004615752565b611fcb565b610369610600366004615752565b612046565b61032461061336600461562d565b612054565b600f5461039f906001600160a01b031681565b61036961063936600461562d565b60186020526000908152604090205460ff1681565b61032461065c3660046159e0565b6120d1565b61032461066f366004615849565b612107565b6103246106823660046156dd565b61230b565b61036961069536600461577d565b61246f565b61032e6106a8366004615665565b612541565b6103246106bb366004615752565b61256c565b6103246106ce3660046159e0565b612597565b61032e636398e41681565b6103246106ec366004615849565b6125ce565b6001600160a01b038116610718576040516342bec4df60e01b815260040160405180910390fd5b600b546001600160a01b03161561074257604051631d0b184b60e21b815260040160405180910390fd5b600b80546001600160a01b038381166001600160a01b03199283168117909355600c80549092168317909155600a5460405163023924c760e01b81526004810193909352169063023924c7906024015b600060405180830381600087803b1580156107ac57600080fd5b505af11580156107c0573d6000803e3d6000fd5b5050505050565b6000600854600754600e60009054906101000a90046001600160a01b03166001600160a01b03166355d0a1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561081d57600080fd5b505afa158015610831573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085591906159f8565b600254010101905090565b60606003805461086f90615d4b565b80601f016020809104026020016040519081016040528092919081815260200182805461089b90615d4b565b80156108e85780601f106108bd576101008083540402835291602001916108e8565b820191906000526020600020905b8154815290600101906020018083116108cb57829003601f168201915b5050505050905090565b600033610900818585612ea5565b60019150505b92915050565b6001600160a01b038116610933576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314158061095757506014546001600160a01b031615155b1561097557604051631d0b184b60e21b815260040160405180910390fd5b601480546001600160a01b038381166001600160a01b03199283168117909355601580549092168317909155600c546040516304b7fac560e11b81526004810193909352169063096ff58a90602401600060405180830381600087803b1580156109de57600080fd5b505af11580156109f2573d6000803e3d6000fd5b5050600e546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401600060405180830381600087803b158015610a3d57600080fd5b505af1158015610a51573d6000803e3d6000fd5b50506012546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401600060405180830381600087803b158015610a9c57600080fd5b505af1158015610ab0573d6000803e3d6000fd5b5050600a546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401610792565b6001600160a01b038116610b0d576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314610b3857604051631d0b184b60e21b815260040160405180910390fd5b601780546001600160a01b0319166001600160a01b03838116918217909255600a54604051637827d56160e01b8152600481019290925290911690637827d56190602401600060405180830381600087803b158015610b9657600080fd5b505af1158015610baa573d6000803e3d6000fd5b505050507fdd475012ca9bbf511d7eb2d3c4f7709ade7f0e3910b847b5dcda58b16684d7518142604051610bdf929190615ade565b60405180910390a150565b600f546001600160a01b03163314610c1557604051631d0b184b60e21b815260040160405180910390fd5b60078054919091039055565b6002601a541415610c4d5760405162461bcd60e51b8152600401610c4490615b6b565b60405180910390fd5b6002601a556016546001600160a01b031633141580610c7357506020610c71612fca565b105b80610c7e5750601954155b15610c9c576040516390172c2b60e01b815260040160405180910390fd5b601754601954610cb5916001600160a01b031690613002565b60006019556001601a55565b600033610ccf8582856130e1565b610cda85858561315b565b506001949350505050565b6002601a541415610d085760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55610d198585858561246f565b610d3657604051633d9a544f60e21b815260040160405180910390fd5b6001600160a01b0385166000818152601860205260409020805460ff19166001179055331480610d6d575060b5610d6b612fca565b105b80610da25750636398e41642108015610da257506001600160a01b0385167366eca275200015dcd0c2eaa6e48d4eed3092cdd6145b15610ed95760405163a9059cbb60e01b8152309063a9059cbb90610dcc9088908890600401615ade565b602060405180830381600087803b158015610de657600080fd5b505af1158015610dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1e919061588a565b508015610e8b5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90610e58908890600090600401615ade565b600060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050505b604080513381526001600160a01b03871660208201529081018590527f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060600160405180910390a16110b8565b808015610f065750610f06336b013bf472f5ed1d56574ec0ad676765c793fa10079d601b1b600080613329565b15610f715760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90610f3e903390600190600401615ade565b600060405180830381600087803b158015610f5857600080fd5b505af1158015610f6c573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b8152309063a9059cbb90610f9b90339064174876e80090600401615ade565b602060405180830381600087803b158015610fb557600080fd5b505af1158015610fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fed919061588a565b5060405163a9059cbb60e01b8152309063a9059cbb9061101b90889064174876e7ff19890190600401615ade565b602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d919061588a565b50604080513381526001600160a01b03871660208201529081018590527f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060600160405180910390a15b50506001601a55505050565b60006110ce61341f565b905090565b6000336109008185856110e68383612541565b6110f09190615d1c565b612ea5565b600b546001600160a01b0316331461112057604051631d0b184b60e21b815260040160405180910390fd5b61112a8282613002565b5050565b6001600160a01b038116611155576040516342bec4df60e01b815260040160405180910390fd5b6011546001600160a01b03161561117f57604051631d0b184b60e21b815260040160405180910390fd5b601180546001600160a01b038381166001600160a01b03199283168117909355601280549092168317909155600c546040516325e866a160e11b815260048101939093521690634bd0cd4290602401600060405180830381600087803b1580156111e857600080fd5b505af11580156111fc573d6000803e3d6000fd5b5050600e546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401600060405180830381600087803b15801561124757600080fd5b505af115801561125b573d6000803e3d6000fd5b5050600a546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401600060405180830381600087803b1580156112a657600080fd5b505af11580156112ba573d6000803e3d6000fd5b50506010546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401610792565b6002601a5414156113135760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d9539061134b9033908890600401615ade565b6101806040518083038186803b15801561136457600080fd5b505afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c91906158a6565b905060006113a8612fca565b60608301516080840151919250600091810183106113d05783608001518460600151016113d2565b825b60125460405163f139dfb760e01b81529290910392506001600160a01b03169063f139dfb79061140e90869033908b9088908890600401615bfc565b600060405180830381600087803b15801561142857600080fd5b505af115801561143c573d6000803e3d6000fd5b5050505060006001600e60009054906101000a90046001600160a01b03166001600160a01b0316630f90e0076040518163ffffffff1660e01b815260040160206040518083038186803b15801561149257600080fd5b505afa1580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca91906159f8565b03905083608001518210806114ec575082846080015185606001510160070111155b1561171657600e546040516348d62c6d60e11b81526001600160a01b03909116906391ac58da906115269060009033908a90600401615af7565b602060405180830381600087803b15801561154057600080fd5b505af1158015611554573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157891906159f8565b50600e54604051633b30762f60e11b81526001600160a01b0390911690637660ec5e906115ae9060009033908a90600401615af7565b602060405180830381600087803b1580156115c857600080fd5b505af11580156115dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160091906159f8565b50600e5460405163ab18a02760e01b81526001600160a01b039091169063ab18a027906116369060009033908a90600401615af7565b602060405180830381600087803b15801561165057600080fd5b505af1158015611664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168891906159f8565b50600e54604051637c6d493160e11b81526001600160a01b039091169063f8da9262906116be9060009033908a90600401615af7565b602060405180830381600087803b1580156116d857600080fd5b505af11580156116ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171091906159f8565b5061194e565b6060840151820160001901818111156117b357600e546040516348d62c6d60e11b81526001600160a01b03909116906391ac58da9061175f908585039033908b90600401615af7565b602060405180830381600087803b15801561177957600080fd5b505af115801561178d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b191906159f8565b505b600e546001600160a01b0316637660ec5e600a830433896040518463ffffffff1660e01b81526004016117e893929190615af7565b602060405180830381600087803b15801561180257600080fd5b505af1158015611816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183a91906159f8565b50600e546001600160a01b031663ab18a0276064830433896040518463ffffffff1660e01b815260040161187093929190615af7565b602060405180830381600087803b15801561188a57600080fd5b505af115801561189e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c291906159f8565b50600e546001600160a01b031663f8da92626103e8830433896040518463ffffffff1660e01b81526004016118f993929190615af7565b602060405180830381600087803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b91906159f8565b50505b600e5460608501518551604051634c29019760e11b815260048101839052918501600019016024830152151560448201526000916001600160a01b031690639852032e9060640160206040518083038186803b1580156119ad57600080fd5b505afa1580156119c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e591906159f8565b90506000670de0b6b3a7640000828760c001510281611a1457634e487b7160e01b600052601260045260246000fd5b0490506000806000611a29338d868e8e613546565b9250925092506000899050336001600160a01b03167fe16ef2c5ff376e78191b54a217db16e2ca4eca7cb451d282f7dd8a75c492df498e8e8789888888604051611a799796959493929190615c68565b60405180910390a250506001601a555050505050505050505050565b6001600160a01b038116611abc576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314611ae757604051631d0b184b60e21b815260040160405180910390fd5b601680546001600160a01b0319166001600160a01b03838116918217909255600a54604051637e98d42960e11b815260048101929092529091169063fd31a85290602401600060405180830381600087803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050507fd535651a5590e21c663adfebb2eb6431447c10dccf3eee90c4c4d8bf7983c14a8142604051610bdf929190615ade565b6001600160a01b038116611bb5576040516342bec4df60e01b815260040160405180910390fd5b600d546001600160a01b031615611bdf57604051631d0b184b60e21b815260040160405180910390fd5b600d80546001600160a01b038381166001600160a01b03199283168117909355600e80549092168317909155600c5460405163307b626b60e11b8152600481019390935216906360f6c4d690602401610792565b6001600160a01b038116611c5a576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b031633141580611c7e57506013546001600160a01b031615155b15611c9c57604051631d0b184b60e21b815260040160405180910390fd5b601380546001600160a01b0319166001600160a01b03838116918217909255601254604051636f72995f60e01b8152600481019290925290911690636f72995f90602401600060405180830381600087803b158015611cfa57600080fd5b505af1158015611d0e573d6000803e3d6000fd5b5050600e54604051636f72995f60e01b81526001600160a01b0385811660048301529091169250636f72995f9150602401610792565b6011546001600160a01b03163314611d6f57604051631d0b184b60e21b815260040160405180910390fd5b600780549091019055565b6011546001600160a01b03163314611da557604051631d0b184b60e21b815260040160405180910390fd5b8060196000828254611db79190615d1c565b909155505050565b6001600160a01b038116600090815260056020526040812054610906565b60606004805461086f90615d4b565b6001600160a01b038116611e13576040516342bec4df60e01b815260040160405180910390fd5b600f546001600160a01b031615611e3d57604051631d0b184b60e21b815260040160405180910390fd5b601080546001600160a01b038381166001600160a01b03199283168117909355600f80549092168317909155600e546040516396cc563f60e01b8152600481019390935216906396cc563f90602401600060405180830381600087803b158015611ea657600080fd5b505af1158015611eba573d6000803e3d6000fd5b5050600a546040516396cc563f60e01b81526001600160a01b03858116600483015290911692506396cc563f9150602401600060405180830381600087803b158015611f0557600080fd5b505af1158015611f19573d6000803e3d6000fd5b5050600c54604051632e8098c560e01b81526001600160a01b0385811660048301529091169250632e8098c59150602401610792565b6009546001600160a01b03163314801590611f755750600b546001600160a01b03163314155b8015611f8c57506011546001600160a01b03163314155b8015611fa357506013546001600160a01b03163314155b15611fc157604051631d0b184b60e21b815260040160405180910390fd5b61112a8282613c21565b60003381611fd98286612541565b9050838110156120395760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610c44565b610cda8286868403612ea5565b60003361090081858561315b565b6001600160a01b03811661207b576040516342bec4df60e01b815260040160405180910390fd5b6009546001600160a01b0316156120a557604051631d0b184b60e21b815260040160405180910390fd5b600980546001600160a01b039092166001600160a01b03199283168117909155600a8054909216179055565b6011546001600160a01b031633146120fc57604051631d0b184b60e21b815260040160405180910390fd5b600880549091019055565b6002601a54141561212a5760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d953906121629087908790600401615ade565b6101806040518083038186803b15801561217b57600080fd5b505afa15801561218f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b391906158a6565b9050600081600001516121d45781608001518260600151016101b8016121e4565b8160800151826060015101610113015b9050806121ef612fca565b108061220057506000826101200151115b8061220c575081602001515b8061221957506080820151155b156122375760405163270b039d60e21b815260040160405180910390fd5b60006122468387878588613d67565b90508380156122745750612274336ac34556b3f6459039627ea4676765c793fa10079d601b1b600080613329565b156122df5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b906122ac903390600190600401615ade565b600060405180830381600087803b1580156122c657600080fd5b505af11580156122da573d6000803e3d6000fd5b505050505b6122fe868683600001518460200151856040015186606001518961447c565b50506001601a5550505050565b8342111561235b5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610c44565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861238a8c614643565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e58261466b565b905060006123f5828787876146b9565b9050896001600160a01b0316816001600160a01b0316146124585760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610c44565b6124638a8a8a612ea5565b50505050505050505050565b6040516bffffffffffffffffffffffff19606086901b16602082015260348101849052600090819060540160408051601f1981840301815291815281516020928301206001600160a01b0389166000908152601890935291205490915060ff1615801561253757506125378484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507fcad71776a60b1a4ca80bfa5452bfc50beeb645b7f64e97f5c464ef45a41d548d92508591506146e19050565b9695505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600d546001600160a01b0316331461112057604051631d0b184b60e21b815260040160405180910390fd5b600f546001600160a01b031633146125c257604051631d0b184b60e21b815260040160405180910390fd5b60088054919091039055565b6002601a5414156125f15760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d953906126299087908790600401615ade565b6101806040518083038186803b15801561264257600080fd5b505afa158015612656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267a91906158a6565b60808101516060820151919250016000612692612fca565b9050826020015180156126a757508261010001515b156126c557604051635ad8888f60e01b815260040160405180910390fd5b600083610120015111806126dd575060008360a00151115b806126e757508181105b806126f457506080830151155b15612712576040516301ddf13b60e61b815260040160405180910390fd5b601254604051632fd96bfd60e11b81526001600160a01b038881166004830152602482018890526044820184905290911690635fb2d7fa90606401600060405180830381600087803b15801561276757600080fd5b505af115801561277b573d6000803e3d6000fd5b50505050600083600001511561281e57676765c793fa10079d601b1b6127fb606460076b08759642e984636060b13f5288610140015102816127cd57634e487b7160e01b600052601260045260246000fd5b04816127e957634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b6146f7565b8161281657634e487b7160e01b600052601260045260246000fd5b04905061287f565b676765c793fa10079d601b1b612860606460076b053a680649b3e32378b13f5288610140015102816127cd57634e487b7160e01b600052601260045260246000fd5b8161287b57634e487b7160e01b600052601260045260246000fd5b0490505b6101408401516000906128b4906128968185614751565b8660070186116128a75760006128ae565b6007878703035b02614751565b90508460200151156129ae57600c546040516303f9f6f560e61b81526001600160a01b039091169063fe7dbd40906128f2908b908b90600401615ade565b602060405180830381600087803b15801561290c57600080fd5b505af1158015612920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612944919061588a565b156129ae57600c546040516342cdcbff60e11b81526001600160a01b039091169063859b97fe9061297b908b908b90600401615ade565b600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b505050505b600e5460408051630f90e00760e01b815290516000926001600160a01b031691630f90e007916004808301926020929190829003018186803b1580156129f357600080fd5b505afa158015612a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2b91906159f8565b90508560600151600101811015612acf57600e5460608701516040516348d62c6d60e11b81526001600160a01b03909216916391ac58da91612a7b91908590036001019033908c90600401615af7565b602060405180830381600087803b158015612a9557600080fd5b505af1158015612aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612acd91906159f8565b505b855115612b545761014086015160078054919091039055600e5460c08701516040516310d6833b60e31b81526001600160a01b03909216916386b419d891612b1d9160040190815260200190565b600060405180830381600087803b158015612b3757600080fd5b505af1158015612b4b573d6000803e3d6000fd5b50505050612bce565b61014086015160088054919091039055600e5460c0870151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd91612b9b9160040190815260200190565b600060405180830381600087803b158015612bb557600080fd5b505af1158015612bc9573d6000803e3d6000fd5b505050505b61016086015160009015612d1d578215612d1857600a546040516317858ab160e31b81526000916001600160a01b03169063bc2c558890612c15908e908e90600401615ade565b602060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c679190615649565b600a5460608a0151604051631898636d60e31b81523360048201526001600160a01b03808516602483015260448201899052918a03606482015260006084820152929350169063c4c31b689060a401602060405180830381600087803b158015612cd057600080fd5b505af1158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d0891906159f8565b9150612d148285614751565b9350505b612db1565b600e546101408801516001600160a01b0390911690631ce2ed86908510612d45576000612d4e565b84896101400151035b6040518263ffffffff1660e01b8152600401612d6c91815260200190565b600060405180830381600087803b158015612d8657600080fd5b505af1158015612d9a573d6000803e3d6000fd5b505050506000831115612db157612db13384613002565b878015612ddd5750612ddd336ac34556b3f6459039627ea4676765c793fa10079d601b1b600080613329565b15612e485760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90612e15903390600190600401615ade565b600060405180830381600087803b158015612e2f57600080fd5b505af1158015612e43573d6000803e3d6000fd5b505050505b604080516001600160a01b038c168152602081018b905290810184905233907f0d6b33a90fd9ff440fc1c724f3f3d492e7c2fc1c629b5a8aacf5c76c2ecbcdbe9060600160405180910390a250506001601a555050505050505050565b6001600160a01b038316612f075760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610c44565b6001600160a01b038216612f685760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610c44565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000636398e416421015612ff157604051633c109e6160e11b815260040160405180910390fd5b506201518042636398e41519010490565b6001600160a01b0382166130585760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610c44565b806002600082825461306a9190615d1c565b90915550506001600160a01b03821660009081526020819052604081208054839290613097908490615d1c565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006130ed8484612541565b9050600019811461315557818110156131485760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610c44565b6131558484848403612ea5565b50505050565b6001600160a01b0383166131bf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c44565b6001600160a01b0382166132215760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c44565b6001600160a01b038316600090815260208190526040902054818110156132995760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610c44565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906132d0908490615d1c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331c91815260200190565b60405180910390a3613155565b600082156133d357601054604051631f8ee6fb60e11b81526004810185905264e8d4a51000916001600160a01b031690633f1dcdf69060240160206040518083038186803b15801561337a57600080fd5b505afa15801561338e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b291906159f8565b8602816133cf57634e487b7160e01b600052601260045260246000fd5b0494505b8385106133e257506001613416565b6000846133ef8885614769565b8161340a57634e487b7160e01b600052601260045260246000fd5b87870391900610159150505b95945050505050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614801561347857507f000000000000000000000000000000000000000000000000000000000000000046145b156134a257507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b601254604051631f11d95360e01b81526000918291829182916001600160a01b0390911690631f11d95390613581908c908c90600401615ade565b6101806040518083038186803b15801561359a57600080fd5b505afa1580156135ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135d291906158a6565b905060006135de612fca565b6060830151608084015191925060009181018310613606578360800151846060015101613608565b825b0390506000601060009054906101000a90046001600160a01b03166001600160a01b031663e4c2a4d68584868e6040518563ffffffff1660e01b81526004016136549493929190615c3b565b60c060405180830381600087803b15801561366e57600080fd5b505af1158015613682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a6919061595b565b905083608001518210156137fe576136c8848b836020015184600001516147c5565b945087156137f95761372c8c85600001516136e45760646136e7565b600a5b60ff166b053a680649b3e32378b13f528161371257634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b8761014001516000613329565b1561379b5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b600060405180830381600087803b15801561377e57600080fd5b505af1158015613792573d6000803e3d6000fd5b50505050613b9f565b8880156137c157506137c18c676765c793fa10079d601b1b808761014001516002613329565b156137f95760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b613b9f565b83608001518460600151016007018311156139c757613827848b836080015184606001516147c5565b945087156137f957600089156138e4576138648d600a6b053a680649b3e32378b13f5204676765c793fa10079d601b1b886101400151600a613329565b156138e457601560009054906101000a90046001600160a01b03166001600160a01b031663d1194e2b8e600b6040518363ffffffff1660e01b81526004016138ad929190615ade565b600060405180830381600087803b1580156138c757600080fd5b505af11580156138db573d6000803e3d6000fd5b50505050600190505b806139c1576139458d86600001516138fd576064613900565b600a5b60ff166b053a680649b3e32378b13f528161392b57634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b8861014001516000613329565b156139c157601560009054906101000a90046001600160a01b03166001600160a01b031663d1194e2b8e60016040518363ffffffff1660e01b815260040161398e929190615ade565b600060405180830381600087803b1580156139a857600080fd5b505af11580156139bc573d6000803e3d6000fd5b505050505b50613b9f565b8715613b9f57605984608001511115613abe576139f88c676765c793fa10079d601b1b808761014001516000613329565b15613a635760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613a30908f90600190600401615ade565b600060405180830381600087803b158015613a4a57600080fd5b505af1158015613a5e573d6000803e3d6000fd5b505050505b88156137f957613a878c676765c793fa10079d601b1b808761014001516003613329565b156137f95760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f906004908101615ade565b613ad68c60646b053a680649b3e32378b13f52613712565b15613b0e5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b888015613b345750613b348c676765c793fa10079d601b1b808761014001516014613329565b15613b9f5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613b6c908f90600190600401615ade565b600060405180830381600087803b158015613b8657600080fd5b505af1158015613b9a573d6000803e3d6000fd5b505050505b613bb4848483604001518460a001518e6149b6565b61016084015115613be057613bd6848d8d8d856080015186606001518f614b3f565b9097509550613c12565b60008a905060008a9050613c0a868f85602001518660800151876000015188606001518888614c61565b909950975050505b50505050955095509592505050565b6001600160a01b038216613c815760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610c44565b6001600160a01b03821660009081526020819052604090205481811015613cf55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610c44565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613d24908490615d34565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612fbd565b613d926040518060800160405280600081526020016000815260200160008152602001600081525090565b6012546040516365892b4960e01b81526001600160a01b03878116600483015260248201879052426044830152909116906365892b4990606401600060405180830381600087803b158015613de657600080fd5b505af1158015613dfa573d6000803e3d6000fd5b50504261012089015250506010546101408701516040516336a34f2760e01b81526001600160a01b03909216916336a34f2791613e3d9160040190815260200190565b600060405180830381600087803b158015613e5757600080fd5b505af1158015613e6b573d6000803e3d6000fd5b50506010546040516303e2f69160e11b8152600093506001600160a01b0390911691506307c5ed2290613ea2908a90600401615ba2565b60206040518083038186803b158015613eba57600080fd5b505afa158015613ece573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef291906159f8565b600e54606089015160808a0151604051635d070d7f60e11b81523360048201526024810192909252604482015285151560648201529192506001600160a01b03169063ba0e1afe90608401600060405180830381600087803b158015613f5757600080fd5b505af1158015613f6b573d6000803e3d6000fd5b5050505060008188610140015111613f84576000613f8d565b81886101400151035b600e5460608a015160808b01518b51604051634c29019760e11b815260048101849052919092016000190160248201529015156044820152919250600091670de0b6b3a7640000916001600160a01b031690639852032e9060640160206040518083038186803b15801561400057600080fd5b505afa158015614014573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061403891906159f8565b8a60c00151028161405957634e487b7160e01b600052601260045260246000fd5b04905081810161406a8a8884614f26565b676765c793fa10079d601b1b6ac34556b3f6459039627ea482020461408f8482614751565b60408701526101608b01511561437957600a546040516317858ab160e31b81528c9189918d918d916000916001600160a01b03169063c4c31b68903390839063bc2c5588906140e49089908990600401615ade565b602060405180830381600087803b1580156140fe57600080fd5b505af1158015614112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141369190615649565b8e604001518960600151614148612fca565b6040516001600160e01b031960e088901b1681526001600160a01b039586166004820152949093166024850152604484019190915290036064820152861515608482015260a401602060405180830381600087803b1580156141a957600080fd5b505af11580156141bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141e191906159f8565b600a549091506000906001600160a01b03166354f4758f87868685614204612fca565b60016040518763ffffffff1660e01b815260040161422796959493929190615bb1565b602060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427991906159f8565b905081871161428957600061428d565b8187035b60608d015260408c0180518390039081905281830101808b111561431357808b03808e52600e54604051630e7176c360e11b815260048101929092526001600160a01b031690631ce2ed8690602401600060405180830381600087803b1580156142f657600080fd5b505af115801561430a573d6000803e3d6000fd5b50505050614318565b60008d525b8c606001518a1161432a576000614332565b8c606001518a035b60208e015260a087015161436d5786511561435c576101408701516007805491909103905561436d565b610140870151600880549190910390555b5050505050505061446e565b83811161438757600061438b565b8381035b6060870152604086015184116143a25760006143aa565b856040015184035b8652606086015183116143be5760006143c6565b856060015183035b602087015260a08b015161446e57600e546101408c0151604051630e7176c360e11b81526001600160a01b0390921691631ce2ed869161440c9160040190815260200190565b600060405180830381600087803b15801561442657600080fd5b505af115801561443a573d6000803e3d6000fd5b505050508a600001511561445d576101408b01516007805491909103905561446e565b6101408b0151600880549190910390555b505050505095945050505050565b84840160006b053a680649b3e32378b13f52676765c793fa10079d601b1b8302600e546040516339dbe92160e21b8152929091046004830181905292506001600160a01b03169063e76fa48490602401600060405180830381600087803b1580156144e657600080fd5b505af11580156144fa573d6000803e3d6000fd5b505050506000676765c793fa10079d601b1b6ac34556b3f6459039627ea484028161453557634e487b7160e01b600052601260045260246000fd5b04828403039050858101850180156145a657600e5460405163c0c8835760e01b8152600481018390526001600160a01b039091169063c0c8835790602401600060405180830381600087803b15801561458d57600080fd5b505af11580156145a1573d6000803e3d6000fd5b505050505b81156145c2576017546145c2906001600160a01b031683613002565b6145ce33888801613002565b336001600160a01b038c167f3d7c224e9ad9e12f013ba8a086e40c61608308a8810a12b8fa970887f0feb6aa8c8a8a8888676765c793fa10079d601b1b6ac34556b3f6459039627ea48d02048d60405161462e9796959493929190615cad565b60405180910390a35050505050505050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b600061090661467861341f565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006146ca8787878761508a565b915091506146d781615177565b5095945050505050565b6000826146ee858461537b565b14949350505050565b60008182848161471757634e487b7160e01b600052601260045260246000fd5b0615614724576001614727565b60005b60ff1683858161474757634e487b7160e01b600052601260045260246000fd5b0401029392505050565b60008183106147605781614762565b825b9392505050565b60004282014340846040516020016147a693929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f1981840301815291905280516020909101209392505050565b600080600086610160015111156147f0576147e285848601614751565b90508092506000935061487c565b60a08601516148775785511561480e57600780548590039055614818565b6008805485900390555b600e54604051630e7176c360e11b8152600481018690526001600160a01b0390911690631ce2ed8690602401600060405180830381600087803b15801561485e57600080fd5b505af1158015614872573d6000803e3d6000fd5b505050505b508282015b600e546040516339dbe92160e21b81526b053a680649b3e32378b13f52676765c793fa10079d601b1b8402046004820181905293506001600160a01b039091169063e76fa48490602401600060405180830381600087803b1580156148e057600080fd5b505af11580156148f4573d6000803e3d6000fd5b505050506000676765c793fa10079d601b1b6ac34556b3f6459039627ea483028161492f57634e487b7160e01b600052601260045260246000fd5b60175491900484840303915061494e906001600160a01b031682613002565b600e5460405163c0c8835760e01b8152600481018390526001600160a01b039091169063c0c8835790602401600060405180830381600087803b15801561499457600080fd5b505af11580156149a8573d6000803e3d6000fd5b505050505050949350505050565b60a0850151614a9d578451614a3357600e5460c0860151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd916149fc9160040190815260200190565b600060405180830381600087803b158015614a1657600080fd5b505af1158015614a2a573d6000803e3d6000fd5b50505050614a9d565b600e5460c08601516040516310d6833b60e31b81526001600160a01b03909216916386b419d891614a6a9160040190815260200190565b600060405180830381600087803b158015614a8457600080fd5b505af1158015614a98573d6000803e3d6000fd5b505050505b600085608001518660600151018510614ab7576000614ab9565b835b82876101400151010390508561014001518110614b3757600e546001600160a01b03166365407202614aeb88846153fd565b6040518263ffffffff1660e01b8152600401614b0991815260200190565b600060405180830381600087803b158015614b2357600080fd5b505af1158015612463573d6000803e3d6000fd5b505050505050565b6000806000614b5087868801614751565b90506000614b5c612fca565b90508a60a0015160001415614b7c576101408b0151600780549190910390555b60008a90506000600a60009054906101000a90046001600160a01b03166001600160a01b03166354f4758f8e848e86888d6040518763ffffffff1660e01b8152600401614bce96959493929190615bb1565b602060405180830381600087803b158015614be857600080fd5b505af1158015614bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c2091906159f8565b9050808d610140015111614c35576000614c3e565b808d6101400151035b9550838a039450614c518287878a615543565b5050505097509795505050505050565b6000806000614d0289601060009054906101000a90046001600160a01b03166001600160a01b03166307c5ed228e6040518263ffffffff1660e01b8152600401614cab9190615ba2565b60206040518083038186803b158015614cc357600080fd5b505afa158015614cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cfb91906159f8565b8a016155c4565b90506000614d1088886155c4565b9050818c610140015111614d25576000614d2e565b818c6101400151035b9350808611614d3e576000614d42565b8086035b92508b60a0015160001415614e96578b5115614d6d576101408c015160078054919091039055614d7e565b6101408c0151600880549190910390555b600083118015614d8c575084155b15614df057600e5460405163c0c8835760e01b8152600481018590526001600160a01b039091169063c0c8835790602401600060405180830381600087803b158015614dd757600080fd5b505af1158015614deb573d6000803e3d6000fd5b505050505b8415614e6557600e546101408d0151604051630e7176c360e11b81526001600160a01b0390921691631ce2ed8691614e2e9160040190815260200190565b600060405180830381600087803b158015614e4857600080fd5b505af1158015614e5c573d6000803e3d6000fd5b50505050614ef6565b600e54604051630e7176c360e11b8152600481018490526001600160a01b0390911690631ce2ed8690602401614e2e565b600e5460405163c0c8835760e01b815284860160048201526001600160a01b039091169063c0c8835790602401600060405180830381600087803b158015614edd57600080fd5b505af1158015614ef1573d6000803e3d6000fd5b505050505b84158015614f0657506000838501115b15614f1757614f178b848601613002565b50509850989650505050505050565b60a083015161500d578251614fa357600e5460c0840151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd91614f6c9160040190815260200190565b600060405180830381600087803b158015614f8657600080fd5b505af1158015614f9a573d6000803e3d6000fd5b5050505061500d565b600e5460c08401516040516310d6833b60e31b81526001600160a01b03909216916386b419d891614fda9160040190815260200190565b600060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050505b600e546101408401516001600160a01b039091169063654072029061503590869085016153fd565b6040518263ffffffff1660e01b815260040161505391815260200190565b600060405180830381600087803b15801561506d57600080fd5b505af1158015615081573d6000803e3d6000fd5b50505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156150c1575060009050600361516e565b8460ff16601b141580156150d957508460ff16601c14155b156150ea575060009050600461516e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561513e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166151675760006001925092505061516e565b9150600090505b94509492505050565b600081600481111561519957634e487b7160e01b600052602160045260246000fd5b14156151a25750565b60018160048111156151c457634e487b7160e01b600052602160045260246000fd5b14156152125760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610c44565b600281600481111561523457634e487b7160e01b600052602160045260246000fd5b14156152825760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610c44565b60038160048111156152a457634e487b7160e01b600052602160045260246000fd5b14156152fd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610c44565b600481600481111561531f57634e487b7160e01b600052602160045260246000fd5b14156153785760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610c44565b50565b600081815b84518110156153f55760008582815181106153ab57634e487b7160e01b600052603260045260246000fd5b602002602001015190508083116153d157600083815260208290526040902092506153e2565b600081815260208490526040902092505b50806153ed81615d80565b915050615380565b509392505050565b6000676765c793fa10079d601b1b8360c00151670de0b6b3a7640000615446676765c793fa10079d601b1b86026b053a680649b3e32378b13f5267016345785d8a000002614751565b85028161546357634e487b7160e01b600052601260045260246000fd5b046154f46b0709fa55642a614ae4f586a686026105b06154d1676765c793fa10079d601b1b61115c02676765c793fa10079d601b1b6154cb6ac34556b3f6459039627ea4676765c793fa10079d601b1b018d6080015102676765c793fa10079d601b1b6146f7565b03614751565b8802816154ee57634e487b7160e01b600052601260045260246000fd5b04614751565b676765c793fa10079d601b1b860201018161551f57634e487b7160e01b600052601260045260246000fd5b048161553b57634e487b7160e01b600052601260045260246000fd5b049392505050565b8061315557821561555a5761555a84838501613002565b811561315557600e5460405163c0c8835760e01b8152600481018490526001600160a01b039091169063c0c8835790602401600060405180830381600087803b1580156155a657600080fd5b505af11580156155ba573d6000803e3d6000fd5b5050505050505050565b60008183116147605781614762565b60008083601f8401126155e4578182fd5b50813567ffffffffffffffff8111156155fb578182fd5b6020830191508360208260051b850101111561561657600080fd5b9250929050565b805161562881615dc6565b919050565b60006020828403121561563e578081fd5b813561476281615db1565b60006020828403121561565a578081fd5b815161476281615db1565b60008060408385031215615677578081fd5b823561568281615db1565b9150602083013561569281615db1565b809150509250929050565b6000806000606084860312156156b1578081fd5b83356156bc81615db1565b925060208401356156cc81615db1565b929592945050506040919091013590565b600080600080600080600060e0888a0312156156f7578283fd5b873561570281615db1565b9650602088013561571281615db1565b95506040880135945060608801359350608088013560ff81168114615735578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215615764578182fd5b823561576f81615db1565b946020939093013593505050565b60008060008060608587031215615792578384fd5b843561579d81615db1565b935060208501359250604085013567ffffffffffffffff8111156157bf578283fd5b6157cb878288016155d3565b95989497509550505050565b6000806000806000608086880312156157ee578081fd5b85356157f981615db1565b945060208601359350604086013567ffffffffffffffff81111561581b578182fd5b615827888289016155d3565b909450925050606086013561583b81615dc6565b809150509295509295909350565b60008060006060848603121561585d578081fd5b833561586881615db1565b925060208401359150604084013561587f81615dc6565b809150509250925092565b60006020828403121561589b578081fd5b815161476281615dc6565b600061018082840312156158b8578081fd5b6158c0615ce4565b6158c98361561d565b81526158d76020840161561d565b60208201526158e86040840161561d565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010061592d81850161561d565b9082015261012083810151908201526101408084015190820152610160928301519281019290925250919050565b600060c0828403121561596c578081fd5b60405160c0810181811067ffffffffffffffff8211171561599b57634e487b7160e01b83526041600452602483fd5b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201528091505092915050565b6000602082840312156159f1578081fd5b5035919050565b600060208284031215615a09578081fd5b5051919050565b600080600060608486031215615a24578081fd5b833592506020840135615a3681615dc6565b9150604084013561587f81615dc6565b8051151582526020810151615a5f602084018215159052565b506040810151615a73604084018215159052565b50606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151615aba8285018215159052565b50506101208181015190830152610140808201519083015261016090810151910152565b6001600160a01b03929092168252602082015260400190565b9283526001600160a01b039190911660208301521515604082015260600190565b6000602080835283518082850152825b81811015615b4457858101830151858201604001528201615b28565b81811115615b555783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b61018081016109068284615a46565b6102208101615bc08289615a46565b6001600160a01b039687166101808301526101a0820195909552929094166101c08301526101e082015291151561020090920191909152919050565b6102008101615c0b8288615a46565b6001600160a01b03959095166101808201526101a08101939093526101c08301919091526101e090910152919050565b6101e08101615c4a8287615a46565b84610180830152836101a0830152826101c083015295945050505050565b60006102408201905088825287151560208301528660408301528560608301528460808301528360a0830152615ca160c0830184615a46565b98975050505050505050565b6000610240820190508882528760208301528660408301528560608301528460808301528360a0830152615ca160c0830184615a46565b604051610180810167ffffffffffffffff81118282101715615d1657634e487b7160e01b600052604160045260246000fd5b60405290565b60008219821115615d2f57615d2f615d9b565b500190565b600082821015615d4657615d46615d9b565b500390565b600181811c90821680615d5f57607f821691505b6020821081141561466557634e487b7160e01b600052602260045260246000fd5b6000600019821415615d9457615d94615d9b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461537857600080fd5b801515811461537857600080fdfea2646970667358221220cf7fec9b990305171b472ea11addeeab57dabb8532cd6cde4b8907984b8c951864736f6c63430008040033000000000000000000000000dca40b6fb95e9c1c4511f7758bc6f3aec7474444000000000000000000000000f2ebcc36ecbbf57bcf7d7531fe24f137afc4c555

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061030c5760003560e01c806360f1edf71161019d578063a9059cbb116100e9578063d505accf116100a2578063dfcad7ea1161007c578063dfcad7ea146106ad578063e09f0817146106c0578063e954f41d146106d3578063e9c4239b146106de57600080fd5b8063d505accf14610674578063dc38bdb514610687578063dd62ed3e1461069a57600080fd5b8063a9059cbb146105f2578063ad09d65814610605578063b074d2f614610618578063c884ef831461062b578063cb01454b1461064e578063d11d01db1461066157600080fd5b806376df7c321161015657806395d89b411161013057806395d89b41146105b157806396cc563f146105b95780639dc29fac146105cc578063a457c2d7146105df57600080fd5b806376df7c32146105785780637ecebe001461058b578063873f0a331461059e57600080fd5b806360f1edf7146104f057806360f6c4d61461050357806363fcd08a146105165780636f72995f1461052957806370a082311461053c57806372fb9c551461056557600080fd5b806323b872dd1161025c578063379b2c1311610215578063445c101f116101ef578063445c101f146104ae5780634bd0cd42146104b75780635476ea9e146104ca57806357ec85dd146104dd57600080fd5b8063379b2c1314610475578063395093511461048857806340c10f191461049b57600080fd5b806323b872dd1461041c578063269858651461042f5780632c265c88146104425780632ceaaf281461044b578063313ce5671461045e5780633644e5151461046d57600080fd5b80630c6eae62116102c9578063197162be116102a3578063197162be146103e55780631ad03156146103f85780631bf803391461040b578063238bf8e01461041457600080fd5b80630c6eae62146103b757806315df1fca146103ca57806318160ddd146103dd57600080fd5b8063023924c71461031157806303d41eb61461032657806306fdde0314610341578063095ea7b314610356578063096ff58a146103795780630b622ab21461038c575b600080fd5b61032461031f36600461562d565b6106f1565b005b61032e6107c7565b6040519081526020015b60405180910390f35b610349610860565b6040516103389190615b18565b610369610364366004615752565b6108f2565b6040519015158152602001610338565b61032461038736600461562d565b61090c565b60095461039f906001600160a01b031681565b6040516001600160a01b039091168152602001610338565b6103246103c536600461562d565b610ae6565b60115461039f906001600160a01b031681565b60025461032e565b6103246103f33660046159e0565b610bea565b600d5461039f906001600160a01b031681565b61032e60075481565b610324610c21565b61036961042a36600461569d565b610cc1565b61032461043d3660046157d7565b610ce5565b61032e60085481565b60165461039f906001600160a01b031681565b60405160098152602001610338565b61032e6110c4565b60135461039f906001600160a01b031681565b610369610496366004615752565b6110d3565b6103246104a9366004615752565b6110f5565b61032e60195481565b6103246104c536600461562d565b61112e565b600b5461039f906001600160a01b031681565b6103246104eb366004615a10565b6112f0565b6103246104fe36600461562d565b611a95565b61032461051136600461562d565b611b8e565b60175461039f906001600160a01b031681565b61032461053736600461562d565b611c33565b61032e61054a36600461562d565b6001600160a01b031660009081526020819052604090205490565b6103246105733660046159e0565b611d44565b6103246105863660046159e0565b611d7a565b61032e61059936600461562d565b611dbf565b60145461039f906001600160a01b031681565b610349611ddd565b6103246105c736600461562d565b611dec565b6103246105da366004615752565b611f4f565b6103696105ed366004615752565b611fcb565b610369610600366004615752565b612046565b61032461061336600461562d565b612054565b600f5461039f906001600160a01b031681565b61036961063936600461562d565b60186020526000908152604090205460ff1681565b61032461065c3660046159e0565b6120d1565b61032461066f366004615849565b612107565b6103246106823660046156dd565b61230b565b61036961069536600461577d565b61246f565b61032e6106a8366004615665565b612541565b6103246106bb366004615752565b61256c565b6103246106ce3660046159e0565b612597565b61032e636398e41681565b6103246106ec366004615849565b6125ce565b6001600160a01b038116610718576040516342bec4df60e01b815260040160405180910390fd5b600b546001600160a01b03161561074257604051631d0b184b60e21b815260040160405180910390fd5b600b80546001600160a01b038381166001600160a01b03199283168117909355600c80549092168317909155600a5460405163023924c760e01b81526004810193909352169063023924c7906024015b600060405180830381600087803b1580156107ac57600080fd5b505af11580156107c0573d6000803e3d6000fd5b5050505050565b6000600854600754600e60009054906101000a90046001600160a01b03166001600160a01b03166355d0a1d06040518163ffffffff1660e01b815260040160206040518083038186803b15801561081d57600080fd5b505afa158015610831573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085591906159f8565b600254010101905090565b60606003805461086f90615d4b565b80601f016020809104026020016040519081016040528092919081815260200182805461089b90615d4b565b80156108e85780601f106108bd576101008083540402835291602001916108e8565b820191906000526020600020905b8154815290600101906020018083116108cb57829003601f168201915b5050505050905090565b600033610900818585612ea5565b60019150505b92915050565b6001600160a01b038116610933576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314158061095757506014546001600160a01b031615155b1561097557604051631d0b184b60e21b815260040160405180910390fd5b601480546001600160a01b038381166001600160a01b03199283168117909355601580549092168317909155600c546040516304b7fac560e11b81526004810193909352169063096ff58a90602401600060405180830381600087803b1580156109de57600080fd5b505af11580156109f2573d6000803e3d6000fd5b5050600e546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401600060405180830381600087803b158015610a3d57600080fd5b505af1158015610a51573d6000803e3d6000fd5b50506012546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401600060405180830381600087803b158015610a9c57600080fd5b505af1158015610ab0573d6000803e3d6000fd5b5050600a546040516304b7fac560e11b81526001600160a01b038581166004830152909116925063096ff58a9150602401610792565b6001600160a01b038116610b0d576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314610b3857604051631d0b184b60e21b815260040160405180910390fd5b601780546001600160a01b0319166001600160a01b03838116918217909255600a54604051637827d56160e01b8152600481019290925290911690637827d56190602401600060405180830381600087803b158015610b9657600080fd5b505af1158015610baa573d6000803e3d6000fd5b505050507fdd475012ca9bbf511d7eb2d3c4f7709ade7f0e3910b847b5dcda58b16684d7518142604051610bdf929190615ade565b60405180910390a150565b600f546001600160a01b03163314610c1557604051631d0b184b60e21b815260040160405180910390fd5b60078054919091039055565b6002601a541415610c4d5760405162461bcd60e51b8152600401610c4490615b6b565b60405180910390fd5b6002601a556016546001600160a01b031633141580610c7357506020610c71612fca565b105b80610c7e5750601954155b15610c9c576040516390172c2b60e01b815260040160405180910390fd5b601754601954610cb5916001600160a01b031690613002565b60006019556001601a55565b600033610ccf8582856130e1565b610cda85858561315b565b506001949350505050565b6002601a541415610d085760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55610d198585858561246f565b610d3657604051633d9a544f60e21b815260040160405180910390fd5b6001600160a01b0385166000818152601860205260409020805460ff19166001179055331480610d6d575060b5610d6b612fca565b105b80610da25750636398e41642108015610da257506001600160a01b0385167366eca275200015dcd0c2eaa6e48d4eed3092cdd6145b15610ed95760405163a9059cbb60e01b8152309063a9059cbb90610dcc9088908890600401615ade565b602060405180830381600087803b158015610de657600080fd5b505af1158015610dfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1e919061588a565b508015610e8b5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90610e58908890600090600401615ade565b600060405180830381600087803b158015610e7257600080fd5b505af1158015610e86573d6000803e3d6000fd5b505050505b604080513381526001600160a01b03871660208201529081018590527f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060600160405180910390a16110b8565b808015610f065750610f06336b013bf472f5ed1d56574ec0ad676765c793fa10079d601b1b600080613329565b15610f715760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90610f3e903390600190600401615ade565b600060405180830381600087803b158015610f5857600080fd5b505af1158015610f6c573d6000803e3d6000fd5b505050505b60405163a9059cbb60e01b8152309063a9059cbb90610f9b90339064174876e80090600401615ade565b602060405180830381600087803b158015610fb557600080fd5b505af1158015610fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fed919061588a565b5060405163a9059cbb60e01b8152309063a9059cbb9061101b90889064174876e7ff19890190600401615ade565b602060405180830381600087803b15801561103557600080fd5b505af1158015611049573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106d919061588a565b50604080513381526001600160a01b03871660208201529081018590527f70eb43c4a8ae8c40502dcf22436c509c28d6ff421cf07c491be56984bd9870689060600160405180910390a15b50506001601a55505050565b60006110ce61341f565b905090565b6000336109008185856110e68383612541565b6110f09190615d1c565b612ea5565b600b546001600160a01b0316331461112057604051631d0b184b60e21b815260040160405180910390fd5b61112a8282613002565b5050565b6001600160a01b038116611155576040516342bec4df60e01b815260040160405180910390fd5b6011546001600160a01b03161561117f57604051631d0b184b60e21b815260040160405180910390fd5b601180546001600160a01b038381166001600160a01b03199283168117909355601280549092168317909155600c546040516325e866a160e11b815260048101939093521690634bd0cd4290602401600060405180830381600087803b1580156111e857600080fd5b505af11580156111fc573d6000803e3d6000fd5b5050600e546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401600060405180830381600087803b15801561124757600080fd5b505af115801561125b573d6000803e3d6000fd5b5050600a546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401600060405180830381600087803b1580156112a657600080fd5b505af11580156112ba573d6000803e3d6000fd5b50506010546040516325e866a160e11b81526001600160a01b0385811660048301529091169250634bd0cd429150602401610792565b6002601a5414156113135760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d9539061134b9033908890600401615ade565b6101806040518083038186803b15801561136457600080fd5b505afa158015611378573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139c91906158a6565b905060006113a8612fca565b60608301516080840151919250600091810183106113d05783608001518460600151016113d2565b825b60125460405163f139dfb760e01b81529290910392506001600160a01b03169063f139dfb79061140e90869033908b9088908890600401615bfc565b600060405180830381600087803b15801561142857600080fd5b505af115801561143c573d6000803e3d6000fd5b5050505060006001600e60009054906101000a90046001600160a01b03166001600160a01b0316630f90e0076040518163ffffffff1660e01b815260040160206040518083038186803b15801561149257600080fd5b505afa1580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca91906159f8565b03905083608001518210806114ec575082846080015185606001510160070111155b1561171657600e546040516348d62c6d60e11b81526001600160a01b03909116906391ac58da906115269060009033908a90600401615af7565b602060405180830381600087803b15801561154057600080fd5b505af1158015611554573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157891906159f8565b50600e54604051633b30762f60e11b81526001600160a01b0390911690637660ec5e906115ae9060009033908a90600401615af7565b602060405180830381600087803b1580156115c857600080fd5b505af11580156115dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160091906159f8565b50600e5460405163ab18a02760e01b81526001600160a01b039091169063ab18a027906116369060009033908a90600401615af7565b602060405180830381600087803b15801561165057600080fd5b505af1158015611664573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168891906159f8565b50600e54604051637c6d493160e11b81526001600160a01b039091169063f8da9262906116be9060009033908a90600401615af7565b602060405180830381600087803b1580156116d857600080fd5b505af11580156116ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171091906159f8565b5061194e565b6060840151820160001901818111156117b357600e546040516348d62c6d60e11b81526001600160a01b03909116906391ac58da9061175f908585039033908b90600401615af7565b602060405180830381600087803b15801561177957600080fd5b505af115801561178d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b191906159f8565b505b600e546001600160a01b0316637660ec5e600a830433896040518463ffffffff1660e01b81526004016117e893929190615af7565b602060405180830381600087803b15801561180257600080fd5b505af1158015611816573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061183a91906159f8565b50600e546001600160a01b031663ab18a0276064830433896040518463ffffffff1660e01b815260040161187093929190615af7565b602060405180830381600087803b15801561188a57600080fd5b505af115801561189e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c291906159f8565b50600e546001600160a01b031663f8da92626103e8830433896040518463ffffffff1660e01b81526004016118f993929190615af7565b602060405180830381600087803b15801561191357600080fd5b505af1158015611927573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061194b91906159f8565b50505b600e5460608501518551604051634c29019760e11b815260048101839052918501600019016024830152151560448201526000916001600160a01b031690639852032e9060640160206040518083038186803b1580156119ad57600080fd5b505afa1580156119c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e591906159f8565b90506000670de0b6b3a7640000828760c001510281611a1457634e487b7160e01b600052601260045260246000fd5b0490506000806000611a29338d868e8e613546565b9250925092506000899050336001600160a01b03167fe16ef2c5ff376e78191b54a217db16e2ca4eca7cb451d282f7dd8a75c492df498e8e8789888888604051611a799796959493929190615c68565b60405180910390a250506001601a555050505050505050505050565b6001600160a01b038116611abc576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b03163314611ae757604051631d0b184b60e21b815260040160405180910390fd5b601680546001600160a01b0319166001600160a01b03838116918217909255600a54604051637e98d42960e11b815260048101929092529091169063fd31a85290602401600060405180830381600087803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050507fd535651a5590e21c663adfebb2eb6431447c10dccf3eee90c4c4d8bf7983c14a8142604051610bdf929190615ade565b6001600160a01b038116611bb5576040516342bec4df60e01b815260040160405180910390fd5b600d546001600160a01b031615611bdf57604051631d0b184b60e21b815260040160405180910390fd5b600d80546001600160a01b038381166001600160a01b03199283168117909355600e80549092168317909155600c5460405163307b626b60e11b8152600481019390935216906360f6c4d690602401610792565b6001600160a01b038116611c5a576040516342bec4df60e01b815260040160405180910390fd5b6016546001600160a01b031633141580611c7e57506013546001600160a01b031615155b15611c9c57604051631d0b184b60e21b815260040160405180910390fd5b601380546001600160a01b0319166001600160a01b03838116918217909255601254604051636f72995f60e01b8152600481019290925290911690636f72995f90602401600060405180830381600087803b158015611cfa57600080fd5b505af1158015611d0e573d6000803e3d6000fd5b5050600e54604051636f72995f60e01b81526001600160a01b0385811660048301529091169250636f72995f9150602401610792565b6011546001600160a01b03163314611d6f57604051631d0b184b60e21b815260040160405180910390fd5b600780549091019055565b6011546001600160a01b03163314611da557604051631d0b184b60e21b815260040160405180910390fd5b8060196000828254611db79190615d1c565b909155505050565b6001600160a01b038116600090815260056020526040812054610906565b60606004805461086f90615d4b565b6001600160a01b038116611e13576040516342bec4df60e01b815260040160405180910390fd5b600f546001600160a01b031615611e3d57604051631d0b184b60e21b815260040160405180910390fd5b601080546001600160a01b038381166001600160a01b03199283168117909355600f80549092168317909155600e546040516396cc563f60e01b8152600481019390935216906396cc563f90602401600060405180830381600087803b158015611ea657600080fd5b505af1158015611eba573d6000803e3d6000fd5b5050600a546040516396cc563f60e01b81526001600160a01b03858116600483015290911692506396cc563f9150602401600060405180830381600087803b158015611f0557600080fd5b505af1158015611f19573d6000803e3d6000fd5b5050600c54604051632e8098c560e01b81526001600160a01b0385811660048301529091169250632e8098c59150602401610792565b6009546001600160a01b03163314801590611f755750600b546001600160a01b03163314155b8015611f8c57506011546001600160a01b03163314155b8015611fa357506013546001600160a01b03163314155b15611fc157604051631d0b184b60e21b815260040160405180910390fd5b61112a8282613c21565b60003381611fd98286612541565b9050838110156120395760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610c44565b610cda8286868403612ea5565b60003361090081858561315b565b6001600160a01b03811661207b576040516342bec4df60e01b815260040160405180910390fd5b6009546001600160a01b0316156120a557604051631d0b184b60e21b815260040160405180910390fd5b600980546001600160a01b039092166001600160a01b03199283168117909155600a8054909216179055565b6011546001600160a01b031633146120fc57604051631d0b184b60e21b815260040160405180910390fd5b600880549091019055565b6002601a54141561212a5760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d953906121629087908790600401615ade565b6101806040518083038186803b15801561217b57600080fd5b505afa15801561218f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b391906158a6565b9050600081600001516121d45781608001518260600151016101b8016121e4565b8160800151826060015101610113015b9050806121ef612fca565b108061220057506000826101200151115b8061220c575081602001515b8061221957506080820151155b156122375760405163270b039d60e21b815260040160405180910390fd5b60006122468387878588613d67565b90508380156122745750612274336ac34556b3f6459039627ea4676765c793fa10079d601b1b600080613329565b156122df5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b906122ac903390600190600401615ade565b600060405180830381600087803b1580156122c657600080fd5b505af11580156122da573d6000803e3d6000fd5b505050505b6122fe868683600001518460200151856040015186606001518961447c565b50506001601a5550505050565b8342111561235b5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610c44565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861238a8c614643565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e58261466b565b905060006123f5828787876146b9565b9050896001600160a01b0316816001600160a01b0316146124585760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610c44565b6124638a8a8a612ea5565b50505050505050505050565b6040516bffffffffffffffffffffffff19606086901b16602082015260348101849052600090819060540160408051601f1981840301815291815281516020928301206001600160a01b0389166000908152601890935291205490915060ff1615801561253757506125378484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507fcad71776a60b1a4ca80bfa5452bfc50beeb645b7f64e97f5c464ef45a41d548d92508591506146e19050565b9695505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600d546001600160a01b0316331461112057604051631d0b184b60e21b815260040160405180910390fd5b600f546001600160a01b031633146125c257604051631d0b184b60e21b815260040160405180910390fd5b60088054919091039055565b6002601a5414156125f15760405162461bcd60e51b8152600401610c4490615b6b565b6002601a55601254604051631f11d95360e01b81526000916001600160a01b031690631f11d953906126299087908790600401615ade565b6101806040518083038186803b15801561264257600080fd5b505afa158015612656573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267a91906158a6565b60808101516060820151919250016000612692612fca565b9050826020015180156126a757508261010001515b156126c557604051635ad8888f60e01b815260040160405180910390fd5b600083610120015111806126dd575060008360a00151115b806126e757508181105b806126f457506080830151155b15612712576040516301ddf13b60e61b815260040160405180910390fd5b601254604051632fd96bfd60e11b81526001600160a01b038881166004830152602482018890526044820184905290911690635fb2d7fa90606401600060405180830381600087803b15801561276757600080fd5b505af115801561277b573d6000803e3d6000fd5b50505050600083600001511561281e57676765c793fa10079d601b1b6127fb606460076b08759642e984636060b13f5288610140015102816127cd57634e487b7160e01b600052601260045260246000fd5b04816127e957634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b6146f7565b8161281657634e487b7160e01b600052601260045260246000fd5b04905061287f565b676765c793fa10079d601b1b612860606460076b053a680649b3e32378b13f5288610140015102816127cd57634e487b7160e01b600052601260045260246000fd5b8161287b57634e487b7160e01b600052601260045260246000fd5b0490505b6101408401516000906128b4906128968185614751565b8660070186116128a75760006128ae565b6007878703035b02614751565b90508460200151156129ae57600c546040516303f9f6f560e61b81526001600160a01b039091169063fe7dbd40906128f2908b908b90600401615ade565b602060405180830381600087803b15801561290c57600080fd5b505af1158015612920573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612944919061588a565b156129ae57600c546040516342cdcbff60e11b81526001600160a01b039091169063859b97fe9061297b908b908b90600401615ade565b600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b505050505b600e5460408051630f90e00760e01b815290516000926001600160a01b031691630f90e007916004808301926020929190829003018186803b1580156129f357600080fd5b505afa158015612a07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a2b91906159f8565b90508560600151600101811015612acf57600e5460608701516040516348d62c6d60e11b81526001600160a01b03909216916391ac58da91612a7b91908590036001019033908c90600401615af7565b602060405180830381600087803b158015612a9557600080fd5b505af1158015612aa9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612acd91906159f8565b505b855115612b545761014086015160078054919091039055600e5460c08701516040516310d6833b60e31b81526001600160a01b03909216916386b419d891612b1d9160040190815260200190565b600060405180830381600087803b158015612b3757600080fd5b505af1158015612b4b573d6000803e3d6000fd5b50505050612bce565b61014086015160088054919091039055600e5460c0870151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd91612b9b9160040190815260200190565b600060405180830381600087803b158015612bb557600080fd5b505af1158015612bc9573d6000803e3d6000fd5b505050505b61016086015160009015612d1d578215612d1857600a546040516317858ab160e31b81526000916001600160a01b03169063bc2c558890612c15908e908e90600401615ade565b602060405180830381600087803b158015612c2f57600080fd5b505af1158015612c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c679190615649565b600a5460608a0151604051631898636d60e31b81523360048201526001600160a01b03808516602483015260448201899052918a03606482015260006084820152929350169063c4c31b689060a401602060405180830381600087803b158015612cd057600080fd5b505af1158015612ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d0891906159f8565b9150612d148285614751565b9350505b612db1565b600e546101408801516001600160a01b0390911690631ce2ed86908510612d45576000612d4e565b84896101400151035b6040518263ffffffff1660e01b8152600401612d6c91815260200190565b600060405180830381600087803b158015612d8657600080fd5b505af1158015612d9a573d6000803e3d6000fd5b505050506000831115612db157612db13384613002565b878015612ddd5750612ddd336ac34556b3f6459039627ea4676765c793fa10079d601b1b600080613329565b15612e485760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90612e15903390600190600401615ade565b600060405180830381600087803b158015612e2f57600080fd5b505af1158015612e43573d6000803e3d6000fd5b505050505b604080516001600160a01b038c168152602081018b905290810184905233907f0d6b33a90fd9ff440fc1c724f3f3d492e7c2fc1c629b5a8aacf5c76c2ecbcdbe9060600160405180910390a250506001601a555050505050505050565b6001600160a01b038316612f075760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610c44565b6001600160a01b038216612f685760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610c44565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000636398e416421015612ff157604051633c109e6160e11b815260040160405180910390fd5b506201518042636398e41519010490565b6001600160a01b0382166130585760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610c44565b806002600082825461306a9190615d1c565b90915550506001600160a01b03821660009081526020819052604081208054839290613097908490615d1c565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006130ed8484612541565b9050600019811461315557818110156131485760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610c44565b6131558484848403612ea5565b50505050565b6001600160a01b0383166131bf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c44565b6001600160a01b0382166132215760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c44565b6001600160a01b038316600090815260208190526040902054818110156132995760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610c44565b6001600160a01b038085166000908152602081905260408082208585039055918516815290812080548492906132d0908490615d1c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161331c91815260200190565b60405180910390a3613155565b600082156133d357601054604051631f8ee6fb60e11b81526004810185905264e8d4a51000916001600160a01b031690633f1dcdf69060240160206040518083038186803b15801561337a57600080fd5b505afa15801561338e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133b291906159f8565b8602816133cf57634e487b7160e01b600052601260045260246000fd5b0494505b8385106133e257506001613416565b6000846133ef8885614769565b8161340a57634e487b7160e01b600052601260045260246000fd5b87870391900610159150505b95945050505050565b6000306001600160a01b037f000000000000000000000000444444444444c1a66f394025ac839a535246fcc81614801561347857507f000000000000000000000000000000000000000000000000000000000000000146145b156134a257507fd951a38113188a785d6753c8c4b58034c16acb79f12f2984aaf2450160fe2feb90565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f0a66c77ba3b0497bc9ceb34460a870cd59906d00eaa03ff7f53a58db8b994326828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b601254604051631f11d95360e01b81526000918291829182916001600160a01b0390911690631f11d95390613581908c908c90600401615ade565b6101806040518083038186803b15801561359a57600080fd5b505afa1580156135ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135d291906158a6565b905060006135de612fca565b6060830151608084015191925060009181018310613606578360800151846060015101613608565b825b0390506000601060009054906101000a90046001600160a01b03166001600160a01b031663e4c2a4d68584868e6040518563ffffffff1660e01b81526004016136549493929190615c3b565b60c060405180830381600087803b15801561366e57600080fd5b505af1158015613682573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a6919061595b565b905083608001518210156137fe576136c8848b836020015184600001516147c5565b945087156137f95761372c8c85600001516136e45760646136e7565b600a5b60ff166b053a680649b3e32378b13f528161371257634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b8761014001516000613329565b1561379b5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b600060405180830381600087803b15801561377e57600080fd5b505af1158015613792573d6000803e3d6000fd5b50505050613b9f565b8880156137c157506137c18c676765c793fa10079d601b1b808761014001516002613329565b156137f95760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b613b9f565b83608001518460600151016007018311156139c757613827848b836080015184606001516147c5565b945087156137f957600089156138e4576138648d600a6b053a680649b3e32378b13f5204676765c793fa10079d601b1b886101400151600a613329565b156138e457601560009054906101000a90046001600160a01b03166001600160a01b031663d1194e2b8e600b6040518363ffffffff1660e01b81526004016138ad929190615ade565b600060405180830381600087803b1580156138c757600080fd5b505af11580156138db573d6000803e3d6000fd5b50505050600190505b806139c1576139458d86600001516138fd576064613900565b600a5b60ff166b053a680649b3e32378b13f528161392b57634e487b7160e01b600052601260045260246000fd5b04676765c793fa10079d601b1b8861014001516000613329565b156139c157601560009054906101000a90046001600160a01b03166001600160a01b031663d1194e2b8e60016040518363ffffffff1660e01b815260040161398e929190615ade565b600060405180830381600087803b1580156139a857600080fd5b505af11580156139bc573d6000803e3d6000fd5b505050505b50613b9f565b8715613b9f57605984608001511115613abe576139f88c676765c793fa10079d601b1b808761014001516000613329565b15613a635760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613a30908f90600190600401615ade565b600060405180830381600087803b158015613a4a57600080fd5b505af1158015613a5e573d6000803e3d6000fd5b505050505b88156137f957613a878c676765c793fa10079d601b1b808761014001516003613329565b156137f95760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f906004908101615ade565b613ad68c60646b053a680649b3e32378b13f52613712565b15613b0e5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613764908f90600190600401615ade565b888015613b345750613b348c676765c793fa10079d601b1b808761014001516014613329565b15613b9f5760155460405163d1194e2b60e01b81526001600160a01b039091169063d1194e2b90613b6c908f90600190600401615ade565b600060405180830381600087803b158015613b8657600080fd5b505af1158015613b9a573d6000803e3d6000fd5b505050505b613bb4848483604001518460a001518e6149b6565b61016084015115613be057613bd6848d8d8d856080015186606001518f614b3f565b9097509550613c12565b60008a905060008a9050613c0a868f85602001518660800151876000015188606001518888614c61565b909950975050505b50505050955095509592505050565b6001600160a01b038216613c815760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610c44565b6001600160a01b03821660009081526020819052604090205481811015613cf55760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610c44565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613d24908490615d34565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612fbd565b613d926040518060800160405280600081526020016000815260200160008152602001600081525090565b6012546040516365892b4960e01b81526001600160a01b03878116600483015260248201879052426044830152909116906365892b4990606401600060405180830381600087803b158015613de657600080fd5b505af1158015613dfa573d6000803e3d6000fd5b50504261012089015250506010546101408701516040516336a34f2760e01b81526001600160a01b03909216916336a34f2791613e3d9160040190815260200190565b600060405180830381600087803b158015613e5757600080fd5b505af1158015613e6b573d6000803e3d6000fd5b50506010546040516303e2f69160e11b8152600093506001600160a01b0390911691506307c5ed2290613ea2908a90600401615ba2565b60206040518083038186803b158015613eba57600080fd5b505afa158015613ece573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ef291906159f8565b600e54606089015160808a0151604051635d070d7f60e11b81523360048201526024810192909252604482015285151560648201529192506001600160a01b03169063ba0e1afe90608401600060405180830381600087803b158015613f5757600080fd5b505af1158015613f6b573d6000803e3d6000fd5b5050505060008188610140015111613f84576000613f8d565b81886101400151035b600e5460608a015160808b01518b51604051634c29019760e11b815260048101849052919092016000190160248201529015156044820152919250600091670de0b6b3a7640000916001600160a01b031690639852032e9060640160206040518083038186803b15801561400057600080fd5b505afa158015614014573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061403891906159f8565b8a60c00151028161405957634e487b7160e01b600052601260045260246000fd5b04905081810161406a8a8884614f26565b676765c793fa10079d601b1b6ac34556b3f6459039627ea482020461408f8482614751565b60408701526101608b01511561437957600a546040516317858ab160e31b81528c9189918d918d916000916001600160a01b03169063c4c31b68903390839063bc2c5588906140e49089908990600401615ade565b602060405180830381600087803b1580156140fe57600080fd5b505af1158015614112573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141369190615649565b8e604001518960600151614148612fca565b6040516001600160e01b031960e088901b1681526001600160a01b039586166004820152949093166024850152604484019190915290036064820152861515608482015260a401602060405180830381600087803b1580156141a957600080fd5b505af11580156141bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141e191906159f8565b600a549091506000906001600160a01b03166354f4758f87868685614204612fca565b60016040518763ffffffff1660e01b815260040161422796959493929190615bb1565b602060405180830381600087803b15801561424157600080fd5b505af1158015614255573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061427991906159f8565b905081871161428957600061428d565b8187035b60608d015260408c0180518390039081905281830101808b111561431357808b03808e52600e54604051630e7176c360e11b815260048101929092526001600160a01b031690631ce2ed8690602401600060405180830381600087803b1580156142f657600080fd5b505af115801561430a573d6000803e3d6000fd5b50505050614318565b60008d525b8c606001518a1161432a576000614332565b8c606001518a035b60208e015260a087015161436d5786511561435c576101408701516007805491909103905561436d565b610140870151600880549190910390555b5050505050505061446e565b83811161438757600061438b565b8381035b6060870152604086015184116143a25760006143aa565b856040015184035b8652606086015183116143be5760006143c6565b856060015183035b602087015260a08b015161446e57600e546101408c0151604051630e7176c360e11b81526001600160a01b0390921691631ce2ed869161440c9160040190815260200190565b600060405180830381600087803b15801561442657600080fd5b505af115801561443a573d6000803e3d6000fd5b505050508a600001511561445d576101408b01516007805491909103905561446e565b6101408b0151600880549190910390555b505050505095945050505050565b84840160006b053a680649b3e32378b13f52676765c793fa10079d601b1b8302600e546040516339dbe92160e21b8152929091046004830181905292506001600160a01b03169063e76fa48490602401600060405180830381600087803b1580156144e657600080fd5b505af11580156144fa573d6000803e3d6000fd5b505050506000676765c793fa10079d601b1b6ac34556b3f6459039627ea484028161453557634e487b7160e01b600052601260045260246000fd5b04828403039050858101850180156145a657600e5460405163c0c8835760e01b8152600481018390526001600160a01b039091169063c0c8835790602401600060405180830381600087803b15801561458d57600080fd5b505af11580156145a1573d6000803e3d6000fd5b505050505b81156145c2576017546145c2906001600160a01b031683613002565b6145ce33888801613002565b336001600160a01b038c167f3d7c224e9ad9e12f013ba8a086e40c61608308a8810a12b8fa970887f0feb6aa8c8a8a8888676765c793fa10079d601b1b6ac34556b3f6459039627ea48d02048d60405161462e9796959493929190615cad565b60405180910390a35050505050505050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b600061090661467861341f565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006146ca8787878761508a565b915091506146d781615177565b5095945050505050565b6000826146ee858461537b565b14949350505050565b60008182848161471757634e487b7160e01b600052601260045260246000fd5b0615614724576001614727565b60005b60ff1683858161474757634e487b7160e01b600052601260045260246000fd5b0401029392505050565b60008183106147605781614762565b825b9392505050565b60004282014340846040516020016147a693929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f1981840301815291905280516020909101209392505050565b600080600086610160015111156147f0576147e285848601614751565b90508092506000935061487c565b60a08601516148775785511561480e57600780548590039055614818565b6008805485900390555b600e54604051630e7176c360e11b8152600481018690526001600160a01b0390911690631ce2ed8690602401600060405180830381600087803b15801561485e57600080fd5b505af1158015614872573d6000803e3d6000fd5b505050505b508282015b600e546040516339dbe92160e21b81526b053a680649b3e32378b13f52676765c793fa10079d601b1b8402046004820181905293506001600160a01b039091169063e76fa48490602401600060405180830381600087803b1580156148e057600080fd5b505af11580156148f4573d6000803e3d6000fd5b505050506000676765c793fa10079d601b1b6ac34556b3f6459039627ea483028161492f57634e487b7160e01b600052601260045260246000fd5b60175491900484840303915061494e906001600160a01b031682613002565b600e5460405163c0c8835760e01b8152600481018390526001600160a01b039091169063c0c8835790602401600060405180830381600087803b15801561499457600080fd5b505af11580156149a8573d6000803e3d6000fd5b505050505050949350505050565b60a0850151614a9d578451614a3357600e5460c0860151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd916149fc9160040190815260200190565b600060405180830381600087803b158015614a1657600080fd5b505af1158015614a2a573d6000803e3d6000fd5b50505050614a9d565b600e5460c08601516040516310d6833b60e31b81526001600160a01b03909216916386b419d891614a6a9160040190815260200190565b600060405180830381600087803b158015614a8457600080fd5b505af1158015614a98573d6000803e3d6000fd5b505050505b600085608001518660600151018510614ab7576000614ab9565b835b82876101400151010390508561014001518110614b3757600e546001600160a01b03166365407202614aeb88846153fd565b6040518263ffffffff1660e01b8152600401614b0991815260200190565b600060405180830381600087803b158015614b2357600080fd5b505af1158015612463573d6000803e3d6000fd5b505050505050565b6000806000614b5087868801614751565b90506000614b5c612fca565b90508a60a0015160001415614b7c576101408b0151600780549190910390555b60008a90506000600a60009054906101000a90046001600160a01b03166001600160a01b03166354f4758f8e848e86888d6040518763ffffffff1660e01b8152600401614bce96959493929190615bb1565b602060405180830381600087803b158015614be857600080fd5b505af1158015614bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614c2091906159f8565b9050808d610140015111614c35576000614c3e565b808d6101400151035b9550838a039450614c518287878a615543565b5050505097509795505050505050565b6000806000614d0289601060009054906101000a90046001600160a01b03166001600160a01b03166307c5ed228e6040518263ffffffff1660e01b8152600401614cab9190615ba2565b60206040518083038186803b158015614cc357600080fd5b505afa158015614cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614cfb91906159f8565b8a016155c4565b90506000614d1088886155c4565b9050818c610140015111614d25576000614d2e565b818c6101400151035b9350808611614d3e576000614d42565b8086035b92508b60a0015160001415614e96578b5115614d6d576101408c015160078054919091039055614d7e565b6101408c0151600880549190910390555b600083118015614d8c575084155b15614df057600e5460405163c0c8835760e01b8152600481018590526001600160a01b039091169063c0c8835790602401600060405180830381600087803b158015614dd757600080fd5b505af1158015614deb573d6000803e3d6000fd5b505050505b8415614e6557600e546101408d0151604051630e7176c360e11b81526001600160a01b0390921691631ce2ed8691614e2e9160040190815260200190565b600060405180830381600087803b158015614e4857600080fd5b505af1158015614e5c573d6000803e3d6000fd5b50505050614ef6565b600e54604051630e7176c360e11b8152600481018490526001600160a01b0390911690631ce2ed8690602401614e2e565b600e5460405163c0c8835760e01b815284860160048201526001600160a01b039091169063c0c8835790602401600060405180830381600087803b158015614edd57600080fd5b505af1158015614ef1573d6000803e3d6000fd5b505050505b84158015614f0657506000838501115b15614f1757614f178b848601613002565b50509850989650505050505050565b60a083015161500d578251614fa357600e5460c0840151604051633f9d44fd60e01b81526001600160a01b0390921691633f9d44fd91614f6c9160040190815260200190565b600060405180830381600087803b158015614f8657600080fd5b505af1158015614f9a573d6000803e3d6000fd5b5050505061500d565b600e5460c08401516040516310d6833b60e31b81526001600160a01b03909216916386b419d891614fda9160040190815260200190565b600060405180830381600087803b158015614ff457600080fd5b505af1158015615008573d6000803e3d6000fd5b505050505b600e546101408401516001600160a01b039091169063654072029061503590869085016153fd565b6040518263ffffffff1660e01b815260040161505391815260200190565b600060405180830381600087803b15801561506d57600080fd5b505af1158015615081573d6000803e3d6000fd5b50505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156150c1575060009050600361516e565b8460ff16601b141580156150d957508460ff16601c14155b156150ea575060009050600461516e565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561513e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166151675760006001925092505061516e565b9150600090505b94509492505050565b600081600481111561519957634e487b7160e01b600052602160045260246000fd5b14156151a25750565b60018160048111156151c457634e487b7160e01b600052602160045260246000fd5b14156152125760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610c44565b600281600481111561523457634e487b7160e01b600052602160045260246000fd5b14156152825760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610c44565b60038160048111156152a457634e487b7160e01b600052602160045260246000fd5b14156152fd5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610c44565b600481600481111561531f57634e487b7160e01b600052602160045260246000fd5b14156153785760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610c44565b50565b600081815b84518110156153f55760008582815181106153ab57634e487b7160e01b600052603260045260246000fd5b602002602001015190508083116153d157600083815260208290526040902092506153e2565b600081815260208490526040902092505b50806153ed81615d80565b915050615380565b509392505050565b6000676765c793fa10079d601b1b8360c00151670de0b6b3a7640000615446676765c793fa10079d601b1b86026b053a680649b3e32378b13f5267016345785d8a000002614751565b85028161546357634e487b7160e01b600052601260045260246000fd5b046154f46b0709fa55642a614ae4f586a686026105b06154d1676765c793fa10079d601b1b61115c02676765c793fa10079d601b1b6154cb6ac34556b3f6459039627ea4676765c793fa10079d601b1b018d6080015102676765c793fa10079d601b1b6146f7565b03614751565b8802816154ee57634e487b7160e01b600052601260045260246000fd5b04614751565b676765c793fa10079d601b1b860201018161551f57634e487b7160e01b600052601260045260246000fd5b048161553b57634e487b7160e01b600052601260045260246000fd5b049392505050565b8061315557821561555a5761555a84838501613002565b811561315557600e5460405163c0c8835760e01b8152600481018490526001600160a01b039091169063c0c8835790602401600060405180830381600087803b1580156155a657600080fd5b505af11580156155ba573d6000803e3d6000fd5b5050505050505050565b60008183116147605781614762565b60008083601f8401126155e4578182fd5b50813567ffffffffffffffff8111156155fb578182fd5b6020830191508360208260051b850101111561561657600080fd5b9250929050565b805161562881615dc6565b919050565b60006020828403121561563e578081fd5b813561476281615db1565b60006020828403121561565a578081fd5b815161476281615db1565b60008060408385031215615677578081fd5b823561568281615db1565b9150602083013561569281615db1565b809150509250929050565b6000806000606084860312156156b1578081fd5b83356156bc81615db1565b925060208401356156cc81615db1565b929592945050506040919091013590565b600080600080600080600060e0888a0312156156f7578283fd5b873561570281615db1565b9650602088013561571281615db1565b95506040880135945060608801359350608088013560ff81168114615735578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215615764578182fd5b823561576f81615db1565b946020939093013593505050565b60008060008060608587031215615792578384fd5b843561579d81615db1565b935060208501359250604085013567ffffffffffffffff8111156157bf578283fd5b6157cb878288016155d3565b95989497509550505050565b6000806000806000608086880312156157ee578081fd5b85356157f981615db1565b945060208601359350604086013567ffffffffffffffff81111561581b578182fd5b615827888289016155d3565b909450925050606086013561583b81615dc6565b809150509295509295909350565b60008060006060848603121561585d578081fd5b833561586881615db1565b925060208401359150604084013561587f81615dc6565b809150509250925092565b60006020828403121561589b578081fd5b815161476281615dc6565b600061018082840312156158b8578081fd5b6158c0615ce4565b6158c98361561d565b81526158d76020840161561d565b60208201526158e86040840161561d565b6040820152606083015160608201526080830151608082015260a083015160a082015260c083015160c082015260e083015160e082015261010061592d81850161561d565b9082015261012083810151908201526101408084015190820152610160928301519281019290925250919050565b600060c0828403121561596c578081fd5b60405160c0810181811067ffffffffffffffff8211171561599b57634e487b7160e01b83526041600452602483fd5b8060405250825181526020830151602082015260408301516040820152606083015160608201526080830151608082015260a083015160a08201528091505092915050565b6000602082840312156159f1578081fd5b5035919050565b600060208284031215615a09578081fd5b5051919050565b600080600060608486031215615a24578081fd5b833592506020840135615a3681615dc6565b9150604084013561587f81615dc6565b8051151582526020810151615a5f602084018215159052565b506040810151615a73604084018215159052565b50606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e083015261010080820151615aba8285018215159052565b50506101208181015190830152610140808201519083015261016090810151910152565b6001600160a01b03929092168252602082015260400190565b9283526001600160a01b039190911660208301521515604082015260600190565b6000602080835283518082850152825b81811015615b4457858101830151858201604001528201615b28565b81811115615b555783604083870101525b50601f01601f1916929092016040019392505050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b61018081016109068284615a46565b6102208101615bc08289615a46565b6001600160a01b039687166101808301526101a0820195909552929094166101c08301526101e082015291151561020090920191909152919050565b6102008101615c0b8288615a46565b6001600160a01b03959095166101808201526101a08101939093526101c08301919091526101e090910152919050565b6101e08101615c4a8287615a46565b84610180830152836101a0830152826101c083015295945050505050565b60006102408201905088825287151560208301528660408301528560608301528460808301528360a0830152615ca160c0830184615a46565b98975050505050505050565b6000610240820190508882528760208301528660408301528560608301528460808301528360a0830152615ca160c0830184615a46565b604051610180810167ffffffffffffffff81118282101715615d1657634e487b7160e01b600052604160045260246000fd5b60405290565b60008219821115615d2f57615d2f615d9b565b500190565b600082821015615d4657615d46615d9b565b500390565b600181811c90821680615d5f57607f821691505b6020821081141561466557634e487b7160e01b600052602260045260246000fd5b6000600019821415615d9457615d94615d9b565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461537857600080fd5b801515811461537857600080fdfea2646970667358221220cf7fec9b990305171b472ea11addeeab57dabb8532cd6cde4b8907984b8c951864736f6c63430008040033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000dca40b6fb95e9c1c4511f7758bc6f3aec7474444000000000000000000000000f2ebcc36ecbbf57bcf7d7531fe24f137afc4c555

-----Decoded View---------------
Arg [0] : _oaGrantor (address): 0xDCA40B6FB95e9C1C4511F7758Bc6f3aec7474444
Arg [1] : _oaBeneficiary (address): 0xf2EbcC36ecbbF57BCf7D7531FE24f137Afc4C555

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000dca40b6fb95e9c1c4511f7758bc6f3aec7474444
Arg [1] : 000000000000000000000000f2ebcc36ecbbf57bcf7d7531fe24f137afc4c555


Deployed Bytecode Sourcemap

59440:62722:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61581:652;;;;;;:::i;:::-;;:::i;:::-;;67819:196;;;:::i;:::-;;;14255:25:1;;;14243:2;14228:18;67819:196:0;;;;;;;;11857:100;;;:::i;:::-;;;;;;;:::i;14208:201::-;;;;;;:::i;:::-;;:::i;:::-;;;14082:14:1;;14075:22;14057:41;;14045:2;14030:18;14208:201:0;14012:92:1;66694:747:0;;;;;;:::i;:::-;;:::i;56061:35::-;;;;;-1:-1:-1;;;;;56061:35:0;;;;;;-1:-1:-1;;;;;10451:32:1;;;10433:51;;10421:2;10406:18;56061:35:0;10388:102:1;60582:380:0;;;;;;:::i;:::-;;:::i;56359:28::-;;;;;-1:-1:-1;;;;;56359:28:0;;;12977:108;13065:12;;12977:108;;112172:184;;;;;;:::i;:::-;;:::i;56220:30::-;;;;;-1:-1:-1;;;;;56220:30:0;;;55983;;;;;;95920:729;;;:::i;14989:295::-;;;;;;:::i;:::-;;:::i;68416:1388::-;;;;;;:::i;:::-;;:::i;56020:32::-;;;;;;56552:24;;;;;-1:-1:-1;;;;;56552:24:0;;;60391:98;;;55293:1;27718:36:1;;27706:2;27691:18;60391:98:0;27673:87:1;44234:115:0;;;:::i;56425:29::-;;;;;-1:-1:-1;;;;;56425:29:0;;;15693:238;;;;;;:::i;:::-;;:::i;70437:164::-;;;;;;:::i;:::-;;:::i;56712:32::-;;;;;;65289:824;;;;;;:::i;:::-;;:::i;56148:29::-;;;;;-1:-1:-1;;;;;56148:29:0;;;87855:6884;;;;;;:::i;:::-;;:::i;61046:359::-;;;;;;:::i;:::-;;:::i;63242:481::-;;;;;;:::i;:::-;;:::i;56583:28::-;;;;;-1:-1:-1;;;;;56583:28:0;;;66121:389;;;;;;:::i;:::-;;:::i;13148:127::-;;;;;;:::i;:::-;-1:-1:-1;;;;;13249:18:0;13222:7;13249:18;;;;;;;;;;;;13148:127;112749:183;;;;;;:::i;:::-;;:::i;96740:191::-;;;;;;:::i;:::-;;:::i;43976:128::-;;;;;;:::i;:::-;;:::i;56461:26::-;;;;;-1:-1:-1;;;;;56461:26:0;;;12076:104;;;:::i;63889:1234::-;;;;;;:::i;:::-;;:::i;70735:354::-;;;;;;:::i;:::-;;:::i;16434:436::-;;;;;;:::i;:::-;;:::i;13481:193::-;;;;;;:::i;:::-;;:::i;62348:743::-;;;;;;:::i;:::-;;:::i;56290:29::-;;;;;-1:-1:-1;;;;;56290:29:0;;;56664:39;;;;;;:::i;:::-;;;;;;;;;;;;;;;;113035:187;;;;;;:::i;:::-;;:::i;103205:1256::-;;;;;;:::i;:::-;;:::i;43265:645::-;;;;;;:::i;:::-;;:::i;69993:349::-;;;;;;:::i;:::-;;:::i;13737:151::-;;;;;;:::i;:::-;;:::i;111868:202::-;;;;;;:::i;:::-;;:::i;112460:188::-;;;;;;:::i;:::-;;:::i;55480:53::-;;55523:10;55480:53;;97269:4756;;;;;;:::i;:::-;;:::i;61581:652::-;-1:-1:-1;;;;;61958:22:0;;61954:53;;61989:18;;-1:-1:-1;;;61989:18:0;;;;;;;;;;;61954:53;62022:14;;-1:-1:-1;;;;;62022:14:0;:28;62018:60;;62059:19;;-1:-1:-1;;;62059:19:0;;;;;;;;;;;62018:60;62089:14;:25;;-1:-1:-1;;;;;62089:25:0;;;-1:-1:-1;;;;;;62089:25:0;;;;;;;;62125:12;:39;;;;;;;;;;62175:21;;:50;;-1:-1:-1;;;62175:50:0;;;;;10433:51:1;;;;62175:21:0;;:40;;10406:18:1;;62175:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61581:652;:::o;67819:196::-;67867:7;67979:17;;67961:15;;67935:8;;;;;;;;;-1:-1:-1;;;;;67935:8:0;-1:-1:-1;;;;;67935:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13065:12;;67919:39;:57;:77;67912:84;;67819:196;:::o;11857:100::-;11911:13;11944:5;11937:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11857:100;:::o;14208:201::-;14291:4;9556:10;14347:32;9556:10;14363:7;14372:6;14347:8;:32::i;:::-;14397:4;14390:11;;;14208:201;;;;;:::o;66694:747::-;-1:-1:-1;;;;;66955:26:0;;66951:57;;66990:18;;-1:-1:-1;;;66990:18:0;;;;;;;;;;;66951:57;67037:9;;-1:-1:-1;;;;;67037:9:0;67023:10;:23;;;:52;;-1:-1:-1;67050:11:0;;-1:-1:-1;;;;;67050:11:0;:25;;67023:52;67019:111;;;67099:19;;-1:-1:-1;;;67099:19:0;;;;;;;;;;;67019:111;67140:11;:26;;-1:-1:-1;;;;;67140:26:0;;;-1:-1:-1;;;;;;67140:26:0;;;;;;;;67177:13;:35;;;;;;;;;;67225:12;;:42;;-1:-1:-1;;;67225:42:0;;;;;10433:51:1;;;;67225:12:0;;:28;;10406:18:1;;67225:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67278:8:0;;:38;;-1:-1:-1;;;67278:38:0;;-1:-1:-1;;;;;10451:32:1;;;67278:38:0;;;10433:51:1;67278:8:0;;;;-1:-1:-1;67278:24:0;;-1:-1:-1;10406:18:1;;67278:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67327:14:0;;:44;;-1:-1:-1;;;67327:44:0;;-1:-1:-1;;;;;10451:32:1;;;67327:44:0;;;10433:51:1;67327:14:0;;;;-1:-1:-1;67327:30:0;;-1:-1:-1;10406:18:1;;67327:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67382:21:0;;:51;;-1:-1:-1;;;67382:51:0;;-1:-1:-1;;;;;10451:32:1;;;67382:51:0;;;10433::1;67382:21:0;;;;-1:-1:-1;67382:37:0;;-1:-1:-1;10406:18:1;;67382:51:0;10388:102:1;60582:380:0;-1:-1:-1;;;;;60659:28:0;;60655:59;;60696:18;;-1:-1:-1;;;60696:18:0;;;;;;;;;;;60655:59;60743:9;;-1:-1:-1;;;;;60743:9:0;60729:10;:23;60725:55;;60761:19;;-1:-1:-1;;;60761:19:0;;;;;;;;;;;60725:55;60791:13;:30;;-1:-1:-1;;;;;;60791:30:0;-1:-1:-1;;;;;60791:30:0;;;;;;;;;60832:21;;:54;;-1:-1:-1;;;60832:54:0;;;;;10433:51:1;;;;60832:21:0;;;;:38;;10406:18:1;;60832:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60902:52;60922:14;60938:15;60902:52;;;;;;;:::i;:::-;;;;;;;;60582:380;:::o;112172:184::-;112255:14;;-1:-1:-1;;;;;112255:14:0;112241:10;:28;112237:60;;112278:19;;-1:-1:-1;;;112278:19:0;;;;;;;;;;;112237:60;112320:15;:26;;;;;;;;112172:184::o;95920:729::-;7071:1;7669:7;;:19;;7661:63;;;;-1:-1:-1;;;7661:63:0;;;;;;;:::i;:::-;;;;;;;;;7071:1;7802:7;:18;96226:9:::1;::::0;-1:-1:-1;;;;;96226:9:0::1;96212:10;:23;;::::0;:64:::1;;;96274:2;96252:19;:17;:19::i;:::-;:24;96212:64;:103;;;-1:-1:-1::0;96293:17:0::1;::::0;:22;96212:103:::1;96208:183;;;96348:31;;-1:-1:-1::0;;;96348:31:0::1;;;;;;;;;;;96208:183;96576:13;::::0;96591:17:::1;::::0;96570:39:::1;::::0;-1:-1:-1;;;;;96576:13:0::1;::::0;96570:5:::1;:39::i;:::-;96640:1;96620:17;:21:::0;7027:1;7981:7;:22;95920:729::o;14989:295::-;15120:4;9556:10;15178:38;15194:4;9556:10;15209:6;15178:15;:38::i;:::-;15227:27;15237:4;15243:2;15247:6;15227:9;:27::i;:::-;-1:-1:-1;15272:4:0;;14989:295;-1:-1:-1;;;;14989:295:0:o;68416:1388::-;7071:1;7669:7;;:19;;7661:63;;;;-1:-1:-1;;;7661:63:0;;;;;;;:::i;:::-;7071:1;7802:7;:18;68670:42:::1;68679:11:::0;68692:6;68700:11;;68670:8:::1;:42::i;:::-;68665:98;;68736:15;;-1:-1:-1::0;;;68736:15:0::1;;;;;;;;;;;68665:98;-1:-1:-1::0;;;;;68775:20:0;::::1;;::::0;;;:7:::1;:20;::::0;;;;:27;;-1:-1:-1;;68775:27:0::1;68798:4;68775:27;::::0;;68834:10:::1;68819:25;::::0;:54:::1;;;68870:3;68848:19;:17;:19::i;:::-;:25;68819:54;:134;;;;55523:10;68891:15;:34;:61;;;;-1:-1:-1::0;;;;;;68929:23:0;::::1;55200:42;68929:23;68891:61;68815:404;;;68979:50;::::0;-1:-1:-1;;;68979:50:0;;68993:4:::1;::::0;68979:29:::1;::::0;:50:::1;::::0;69009:11;;69022:6;;68979:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69048:7;69044:85;;;69076:13;::::0;:37:::1;::::0;-1:-1:-1;;;69076:37:0;;-1:-1:-1;;;;;69076:13:0;;::::1;::::0;:21:::1;::::0;:37:::1;::::0;69098:11;;69076:13:::1;::::0;:37:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;69044:85;69148:38;::::0;;69154:10:::1;10735:34:1::0;;-1:-1:-1;;;;;10805:15:1;;10800:2;10785:18;;10778:43;10837:18;;;10830:34;;;69148:38:0::1;::::0;10685:2:1;10670:18;69148:38:0::1;;;;;;;69201:7;;68815:404;69299:7;:68;;;;;69310:57;69323:10;54409:27;-1:-1:-1::0;;;69362:1:0::1;69365::::0;69310:12:::1;:57::i;:::-;69295:137;;;69384:13;::::0;:36:::1;::::0;-1:-1:-1;;;69384:36:0;;-1:-1:-1;;;;;69384:13:0;;::::1;::::0;:21:::1;::::0;:36:::1;::::0;69406:10:::1;::::0;69384:13;;:36:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;69295:137;69596:55;::::0;-1:-1:-1;;;69596:55:0;;69610:4:::1;::::0;69596:29:::1;::::0;:55:::1;::::0;69626:10:::1;::::0;69638:12:::1;::::0;69596:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;69666:65:0::1;::::0;-1:-1:-1;;;69666:65:0;;69680:4:::1;::::0;69666:29:::1;::::0;:65:::1;::::0;69696:11;;-1:-1:-1;;69709:21:0;;;69666:65:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;69758:38:0::1;::::0;;69764:10:::1;10735:34:1::0;;-1:-1:-1;;;;;10805:15:1;;10800:2;10785:18;;10778:43;10837:18;;;10830:34;;;69758:38:0::1;::::0;10685:2:1;10670:18;69758:38:0::1;;;;;;;7833:1;-1:-1:-1::0;;7027:1:0;7981:7;:22;-1:-1:-1;;;68416:1388:0:o;44234:115::-;44294:7;44321:20;:18;:20::i;:::-;44314:27;;44234:115;:::o;15693:238::-;15781:4;9556:10;15837:64;9556:10;15853:7;15890:10;15862:25;9556:10;15853:7;15862:9;:25::i;:::-;:38;;;;:::i;:::-;15837:8;:64::i;70437:164::-;70520:14;;-1:-1:-1;;;;;70520:14:0;70506:10;:28;70502:60;;70543:19;;-1:-1:-1;;;70543:19:0;;;;;;;;;;;70502:60;70573:20;70579:5;70586:6;70573:5;:20::i;:::-;70437:164;;:::o;65289:824::-;-1:-1:-1;;;;;65652:28:0;;65648:59;;65689:18;;-1:-1:-1;;;65689:18:0;;;;;;;;;;;65648:59;65722:13;;-1:-1:-1;;;;;65722:13:0;:27;65718:59;;65758:19;;-1:-1:-1;;;65758:19:0;;;;;;;;;;;65718:59;65788:13;:30;;-1:-1:-1;;;;;65788:30:0;;;-1:-1:-1;;;;;;65788:30:0;;;;;;;;65829:14;:40;;;;;;;;;;65880:12;;:46;;-1:-1:-1;;;65880:46:0;;;;;10433:51:1;;;;65880:12:0;;:30;;10406:18:1;;65880:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65937:8:0;;:42;;-1:-1:-1;;;65937:42:0;;-1:-1:-1;;;;;10451:32:1;;;65937:42:0;;;10433:51:1;65937:8:0;;;;-1:-1:-1;65937:26:0;;-1:-1:-1;10406:18:1;;65937:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65990:21:0;;:55;;-1:-1:-1;;;65990:55:0;;-1:-1:-1;;;;;10451:32:1;;;65990:55:0;;;10433:51:1;65990:21:0;;;;-1:-1:-1;65990:39:0;;-1:-1:-1;10406:18:1;;65990:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66056:15:0;;:49;;-1:-1:-1;;;66056:49:0;;-1:-1:-1;;;;;10451:32:1;;;66056:49:0;;;10433:51:1;66056:15:0;;;;-1:-1:-1;66056:33:0;;-1:-1:-1;10406:18:1;;66056:49:0;10388:102:1;87855:6884:0;7071:1;7669:7;;:19;;7661:63;;;;-1:-1:-1;;;7661:63:0;;;;;;;:::i;:::-;7071:1;7802:7;:18;88018:14:::1;::::0;:49:::1;::::0;-1:-1:-1;;;88018:49:0;;87992:23:::1;::::0;-1:-1:-1;;;;;88018:14:0::1;::::0;:25:::1;::::0;:49:::1;::::0;88044:10:::1;::::0;88056;;88018:49:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87992:75;;88103:24;88130:19;:17;:19::i;:::-;88651:14;::::0;::::1;::::0;88515:17:::1;::::0;::::1;::::0;88103:46;;-1:-1:-1;88438:18:0::1;::::0;88498:34;::::1;88478:55:::0;::::1;:155;;88615:5;:17;;;88598:5;:14;;;:34;88478:155;;;88557:16;88478:155;88710:14;::::0;:192:::1;::::0;-1:-1:-1;;;88710:192:0;;88459:206;;;::::1;::::0;-1:-1:-1;;;;;;88710:14:0::1;::::0;:31:::1;::::0;:192:::1;::::0;88760:5;;88784:10:::1;::::0;88813;;88842:16;;88459:206;;88710:192:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;89047:25;89098:1;89075:8;;;;;;;;;-1:-1:-1::0;;;;;89075:8:0::1;-1:-1:-1::0;;;;;89075:18:0::1;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:24;89047:52;;89228:5;:17;;;89215:10;:30;:92;;;;89291:16;89266:5;:17;;;89249:5;:14;;;:34;89286:1;89249:38;:58;;89215:92;89211:4718;;;89554:8;::::0;:56:::1;::::0;-1:-1:-1;;;89554:56:0;;-1:-1:-1;;;;;89554:8:0;;::::1;::::0;:32:::1;::::0;:56:::1;::::0;:8:::1;::::0;89590:10:::1;::::0;89602:7;;89554:56:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;89629:8:0::1;::::0;:50:::1;::::0;-1:-1:-1;;;89629:50:0;;-1:-1:-1;;;;;89629:8:0;;::::1;::::0;:26:::1;::::0;:50:::1;::::0;:8:::1;::::0;89659:10:::1;::::0;89671:7;;89629:50:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;89698:8:0::1;::::0;:51:::1;::::0;-1:-1:-1;;;89698:51:0;;-1:-1:-1;;;;;89698:8:0;;::::1;::::0;:27:::1;::::0;:51:::1;::::0;:8:::1;::::0;89729:10:::1;::::0;89741:7;;89698:51:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;89768:8:0::1;::::0;:52:::1;::::0;-1:-1:-1;;;89768:52:0;;-1:-1:-1;;;;;89768:8:0;;::::1;::::0;:28:::1;::::0;:52:::1;::::0;:8:::1;::::0;89800:10:::1;::::0;89812:7;;89768:52:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;89211:4718;;;90693:14;::::0;::::1;::::0;:27;::::1;-1:-1:-1::0;;90693:31:0;90747:33;;::::1;90743:372;;;90909:8;::::0;:186:::1;::::0;-1:-1:-1;;;90909:186:0;;-1:-1:-1;;;;;90909:8:0;;::::1;::::0;:32:::1;::::0;:186:::1;::::0;90968:33;;::::1;::::0;91028:10:::1;::::0;91065:7;;90909:186:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;90743:372;93296:8;::::0;-1:-1:-1;;;;;93296:8:0::1;:26;93339:2;93323:13:::0;:18:::1;93343:10;93355:7;93296:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;93599:8:0::1;::::0;-1:-1:-1;;;;;93599:8:0::1;:27;93643:3;93627:13:::0;:19:::1;93648:10;93660:7;93599:69;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;93842:8:0::1;::::0;-1:-1:-1;;;;;93842:8:0::1;:28;93887:4;93871:13:::0;:20:::1;93893:10;93905:7;93842:71;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;89211:4718;;94052:8;::::0;94075:14:::1;::::0;::::1;::::0;94126:12;;94052:87:::1;::::0;-1:-1:-1;;;94052:87:0;;::::1;::::0;::::1;26748:25:1::0;;;94092:27:0;;::::1;-1:-1:-1::0;;94092:31:0;26789:18:1;;;26782:34;26859:14;26852:22;26832:18;;;26825:50;94028:21:0::1;::::0;-1:-1:-1;;;;;94052:8:0::1;::::0;:22:::1;::::0;26721:18:1;;94052:87:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;94028:111;;94154:15;55603:19;94193:13;94172:5;:18;;;:34;:52;;;-1:-1:-1::0;;;94172:52:0::1;;;;;;;;;;94154:70;;94292:26;94337:24:::0;94380:23:::1;94434:68;94448:10;94460;94472:7;94481:11;94494:7;94434:13;:68::i;:::-;94273:229;;;;;;94517:24;94544:5;94517:32;;94578:10;-1:-1:-1::0;;;;;94569:151:0::1;;94590:10;94602:11;94632:18;94652:7;94678:16;94696:15;94713:6;94569:151;;;;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;7027:1:0;7981:7;:22;-1:-1:-1;;;;;;;;;;;87855:6884:0:o;61046:359::-;-1:-1:-1;;;;;61118:27:0;;61114:58;;61154:18;;-1:-1:-1;;;61154:18:0;;;;;;;;;;;61114:58;61201:9;;-1:-1:-1;;;;;61201:9:0;61187:10;:23;61183:55;;61219:19;;-1:-1:-1;;;61219:19:0;;;;;;;;;;;61183:55;61249:9;:25;;-1:-1:-1;;;;;;61249:25:0;-1:-1:-1;;;;;61249:25:0;;;;;;;;;61285:21;;:49;;-1:-1:-1;;;61285:49:0;;;;;10433:51:1;;;;61285:21:0;;;;:34;;10406:18:1;;61285:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61350:47;61366:13;61381:15;61350:47;;;;;;;:::i;63242:481::-;-1:-1:-1;;;;;63453:23:0;;63449:54;;63485:18;;-1:-1:-1;;;63485:18:0;;;;;;;;;;;63449:54;63518:15;;-1:-1:-1;;;;;63518:15:0;:29;63514:61;;63556:19;;-1:-1:-1;;;63556:19:0;;;;;;;;;;;63514:61;63586:15;:27;;-1:-1:-1;;;;;63586:27:0;;;-1:-1:-1;;;;;;63586:27:0;;;;;;;;63624:8;:37;;;;;;;;;;63672:12;;:43;;-1:-1:-1;;;63672:43:0;;;;;10433:51:1;;;;63672:12:0;;:32;;10406:18:1;;63672:43:0;10388:102:1;66121:389:0;-1:-1:-1;;;;;66191:22:0;;66187:53;;66222:18;;-1:-1:-1;;;66222:18:0;;;;;;;;;;;66187:53;66269:9;;-1:-1:-1;;;;;66269:9:0;66255:10;:23;;;:55;;-1:-1:-1;66282:14:0;;-1:-1:-1;;;;;66282:14:0;:28;;66255:55;66251:114;;;66334:19;;-1:-1:-1;;;66334:19:0;;;;;;;;;;;66251:114;66375:14;:25;;-1:-1:-1;;;;;;66375:25:0;-1:-1:-1;;;;;66375:25:0;;;;;;;;;66411:14;;:43;;-1:-1:-1;;;66411:43:0;;;;;10433:51:1;;;;66411:14:0;;;;:33;;10406:18:1;;66411:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66465:8:0;;:37;;-1:-1:-1;;;66465:37:0;;-1:-1:-1;;;;;10451:32:1;;;66465:37:0;;;10433:51:1;66465:8:0;;;;-1:-1:-1;66465:27:0;;-1:-1:-1;10406:18:1;;66465:37:0;10388:102:1;112749:183:0;112832:13;;-1:-1:-1;;;;;112832:13:0;112818:10;:27;112814:59;;112854:19;;-1:-1:-1;;;112854:19:0;;;;;;;;;;;112814:59;112896:15;:26;;;;;;;112749:183::o;96740:191::-;96834:13;;-1:-1:-1;;;;;96834:13:0;96820:10;:27;96816:59;;96856:19;;-1:-1:-1;;;96856:19:0;;;;;;;;;;;96816:59;96907:16;96886:17;;:37;;;;;;;:::i;:::-;;;;-1:-1:-1;;;96740:191:0:o;43976:128::-;-1:-1:-1;;;;;44072:14:0;;44045:7;44072:14;;;:7;:14;;;;;4735;44072:24;4643:114;12076:104;12132:13;12165:7;12158:14;;;;;:::i;63889:1234::-;-1:-1:-1;;;;;64169:24:0;;64165:55;;64202:18;;-1:-1:-1;;;64202:18:0;;;;;;;;;;;64165:55;64235:14;;-1:-1:-1;;;;;64235:14:0;:28;64231:60;;64272:19;;-1:-1:-1;;;64272:19:0;;;;;;;;;;;64231:60;64873:15;:38;;-1:-1:-1;;;;;64873:38:0;;;-1:-1:-1;;;;;;64873:38:0;;;;;;;;64922:14;:27;;;;;;;;;;64960:8;;:39;;-1:-1:-1;;;64960:39:0;;;;;10433:51:1;;;;64960:8:0;;:27;;10406:18:1;;64960:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65010:21:0;;:52;;-1:-1:-1;;;65010:52:0;;-1:-1:-1;;;;;10451:32:1;;;65010:52:0;;;10433:51:1;65010:21:0;;;;-1:-1:-1;65010:40:0;;-1:-1:-1;10406:18:1;;65010:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65073:12:0;;:42;;-1:-1:-1;;;65073:42:0;;-1:-1:-1;;;;;10451:32:1;;;65073:42:0;;;10433:51:1;65073:12:0;;;;-1:-1:-1;65073:30:0;;-1:-1:-1;10406:18:1;;65073:42:0;10388:102:1;70735:354:0;70832:20;;-1:-1:-1;;;;;70832:20:0;70818:10;:34;;;;:79;;-1:-1:-1;70883:14:0;;-1:-1:-1;;;;;70883:14:0;70869:10;:28;;70818:79;:123;;;;-1:-1:-1;70928:13:0;;-1:-1:-1;;;;;70928:13:0;70914:10;:27;;70818:123;:168;;;;-1:-1:-1;70972:14:0;;-1:-1:-1;;;;;70972:14:0;70958:10;:28;;70818:168;70800:251;;;71020:19;;-1:-1:-1;;;71020:19:0;;;;;;;;;;;70800:251;71061:20;71067:5;71074:6;71061:5;:20::i;16434:436::-;16527:4;9556:10;16527:4;16610:25;9556:10;16627:7;16610:9;:25::i;:::-;16583:52;;16674:15;16654:16;:35;;16646:85;;;;-1:-1:-1;;;16646:85:0;;22746:2:1;16646:85:0;;;22728:21:1;22785:2;22765:18;;;22758:30;22824:34;22804:18;;;22797:62;-1:-1:-1;;;22875:18:1;;;22868:35;22920:19;;16646:85:0;22718:227:1;16646:85:0;16767:60;16776:5;16783:7;16811:15;16792:16;:34;16767:8;:60::i;13481:193::-;13560:4;9556:10;13616:28;9556:10;13633:2;13637:6;13616:9;:28::i;62348:743::-;-1:-1:-1;;;;;62662:28:0;;62658:59;;62699:18;;-1:-1:-1;;;62699:18:0;;;;;;;;;;;62658:59;62732:20;;-1:-1:-1;;;;;62732:20:0;:34;62728:66;;62775:19;;-1:-1:-1;;;62775:19:0;;;;;;;;;;;62728:66;62805:20;:37;;-1:-1:-1;;;;;62805:37:0;;;-1:-1:-1;;;;;;62805:37:0;;;;;;;;62853:21;:54;;;;;;;;62348:743::o;113035:187::-;113120:13;;-1:-1:-1;;;;;113120:13:0;113106:10;:27;113102:59;;113142:19;;-1:-1:-1;;;113142:19:0;;;;;;;;;;;113102:59;113184:17;:28;;;;;;;113035:187::o;103205:1256::-;7071:1;7669:7;;:19;;7661:63;;;;-1:-1:-1;;;7661:63:0;;;;;;;:::i;:::-;7071:1;7802:7;:18;103347:14:::1;::::0;:41:::1;::::0;-1:-1:-1;;;103347:41:0;;103321:23:::1;::::0;-1:-1:-1;;;;;103347:14:0::1;::::0;:25:::1;::::0;:41:::1;::::0;103373:5;;103380:7;;103347:41:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;103321:67;;103486:25;103514:5;:12;;;:132;;103623:5;:17;;;103606:5;:14;;;:34;103643:3;103606:40;103514:132;;;103563:5;:17;;;103546:5;:14;;;:34;103583:3;103546:40;103514:132;103486:160;;103707:17;103685:19;:17;:19::i;:::-;:39;:75;;;;103759:1;103745:5;:11;;;:15;103685:75;:111;;;;103781:5;:15;;;103685:111;:154;;;-1:-1:-1::0;103817:17:0::1;::::0;::::1;::::0;:22;103685:154:::1;103663:250;;;103881:16;;-1:-1:-1::0;;;103881:16:0::1;;;;;;;;;;;103663:250;103929:37;103986:65;104001:5;104008;104015:7;104024:17;104043:7;103986:14;:65::i;:::-;103929:122;;104072:7;:68;;;;;104083:57;104096:10;54552:27;-1:-1:-1::0;;;104135:1:0::1;104138::::0;104083:12:::1;:57::i;:::-;104068:145;;;104161:13;::::0;:36:::1;::::0;-1:-1:-1;;;104161:36:0;;-1:-1:-1;;;;;104161:13:0;;::::1;::::0;:21:::1;::::0;:36:::1;::::0;104183:10:::1;::::0;104161:13;;:36:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;104068:145;104229:213;104244:5;104251:7;104260:12;:36;;;104315:12;:34;;;104351:12;:31;;;104401:12;:33;;;104436:5;104229:14;:213::i;:::-;-1:-1:-1::0;;7027:1:0;7981:7;:22;-1:-1:-1;;;;103205:1256:0:o;43265:645::-;43509:8;43490:15;:27;;43482:69;;;;-1:-1:-1;;;43482:69:0;;19243:2:1;43482:69:0;;;19225:21:1;19282:2;19262:18;;;19255:30;19321:31;19301:18;;;19294:59;19370:18;;43482:69:0;19215:179:1;43482:69:0;43564:18;42440:95;43624:5;43631:7;43640:5;43647:16;43657:5;43647:9;:16::i;:::-;43595:79;;;;;;14578:25:1;;;;-1:-1:-1;;;;;14677:15:1;;;14657:18;;;14650:43;14729:15;;;;14709:18;;;14702:43;14761:18;;;14754:34;14804:19;;;14797:35;14848:19;;;14841:35;;;14550:19;;43595:79:0;;;;;;;;;;;;43585:90;;;;;;43564:111;;43688:12;43703:28;43720:10;43703:16;:28::i;:::-;43688:43;;43744:14;43761:28;43775:4;43781:1;43784;43787;43761:13;:28::i;:::-;43744:45;;43818:5;-1:-1:-1;;;;;43808:15:0;:6;-1:-1:-1;;;;;43808:15:0;;43800:58;;;;-1:-1:-1;;;43800:58:0;;20814:2:1;43800:58:0;;;20796:21:1;20853:2;20833:18;;;20826:30;20892:32;20872:18;;;20865:60;20942:18;;43800:58:0;20786:180:1;43800:58:0;43871:31;43880:5;43887:7;43896:5;43871:8;:31::i;:::-;43265:645;;;;;;;;;;:::o;69993:349::-;70177:37;;-1:-1:-1;;9404:2:1;9400:15;;;9396:53;70177:37:0;;;9384:66:1;9466:12;;;9459:28;;;70135:4:0;;;;9503:12:1;;70177:37:0;;;-1:-1:-1;;70177:37:0;;;;;;;;;70167:48;;70177:37;70167:48;;;;-1:-1:-1;;;;;70247:20:0;;;;;;:7;:20;;;;;;70167:48;;-1:-1:-1;70247:20:0;;70246:21;:88;;;;;70284:50;70303:11;;70284:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55881:66:0;;-1:-1:-1;70329:4:0;;-1:-1:-1;70284:18:0;;-1:-1:-1;70284:50:0:i;:::-;70226:108;69993:349;-1:-1:-1;;;;;;69993:349:0:o;13737:151::-;-1:-1:-1;;;;;13853:18:0;;;13826:7;13853:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;13737:151::o;111868:202::-;111963:15;;-1:-1:-1;;;;;111963:15:0;111949:10;:29;111945:88;;112002:19;;-1:-1:-1;;;112002:19:0;;;;;;;;;;;112460:188;112545:14;;-1:-1:-1;;;;;112545:14:0;112531:10;:28;112527:60;;112568:19;;-1:-1:-1;;;112568:19:0;;;;;;;;;;;112527:60;112610:17;:28;;;;;;;;112460:188::o;97269:4756::-;7071:1;7669:7;;:19;;7661:63;;;;-1:-1:-1;;;7661:63:0;;;;;;;:::i;:::-;7071:1;7802:7;:18;97969:14:::1;::::0;:41:::1;::::0;-1:-1:-1;;;97969:41:0;;97943:23:::1;::::0;-1:-1:-1;;;;;97969:14:0::1;::::0;:25:::1;::::0;:41:::1;::::0;97995:5;;98002:7;;97969:41:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98302:17;::::0;::::1;::::0;98285:14:::1;::::0;::::1;::::0;97943:67;;-1:-1:-1;98285:34:0::1;98261:21;98348:19;:17;:19::i;:::-;98334:33;;98487:5;:15;;;:40;;;;;98506:5;:21;;;98487:40;98483:123;;;98555:35;;-1:-1:-1::0;;;98555:35:0::1;;;;;;;;;;;98483:123;98656:1;98642:5;:11;;;:15;:57;;;;98698:1;98678:5;:17;;;:21;98642:57;:97;;;;98726:13;98720:3;:19;98642:97;:140;;;-1:-1:-1::0;98760:17:0::1;::::0;::::1;::::0;:22;98642:140:::1;98620:246;;;98824:26;;-1:-1:-1::0;;;98824:26:0::1;;;;;;;;;;;98620:246;98933:14;::::0;:60:::1;::::0;-1:-1:-1;;;98933:60:0;;-1:-1:-1;;;;;13355:32:1;;;98933:60:0::1;::::0;::::1;13337:51:1::0;13404:18;;;13397:34;;;13447:18;;;13440:34;;;98933:14:0;;::::1;::::0;:39:::1;::::0;13310:18:1;;98933:60:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;99051:12;99082:5;:12;;;99078:360;;;-1:-1:-1::0;;;99173:62:0::1;99216:3;99212:1;54838:28;99182:5;:15;;;:27;:31;;;-1:-1:-1::0;;;99182:31:0::1;;;;;;;;;;:37;;;-1:-1:-1::0;;;99182:37:0::1;;;;;;;;;;-1:-1:-1::0;;;99173:8:0::1;:62::i;:::-;:78;;;-1:-1:-1::0;;;99173:78:0::1;;;;;;;;;;99166:85;;99078:360;;;-1:-1:-1::0;;;99350:56:0::1;99387:3;99383:1;54265:28;99359:5;:15;;;:21;:25;;;-1:-1:-1::0;;;99359:25:0::1;;;;;;;;99350:56;:72;;;-1:-1:-1::0;;;99350:72:0::1;;;;;;;;;;99343:79;;99078:360;99695:15;::::0;::::1;::::0;99663:24:::1;::::0;99690:125:::1;::::0;99787:27:::1;99695:15:::0;99809:4;99787::::1;:27::i;:::-;99719:13;99735:1;99719:17;99713:3;:23;:53;;99765:1;99713:53;;;99761:1;99745:13;99739:3;:19;:23;99713:53;99712:102;99690:4;:125::i;:::-;99663:152;;99919:5;:15;;;99915:193;;;99959:12;::::0;:47:::1;::::0;-1:-1:-1;;;99959:47:0;;-1:-1:-1;;;;;99959:12:0;;::::1;::::0;:31:::1;::::0;:47:::1;::::0;99991:5;;99998:7;;99959:47:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99955:138;;;100031:12;::::0;:42:::1;::::0;-1:-1:-1;;;100031:42:0;;-1:-1:-1;;;;;100031:12:0;;::::1;::::0;:26:::1;::::0;:42:::1;::::0;100058:5;;100065:7;;100031:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;99955:138;100344:8;::::0;:20:::1;::::0;;-1:-1:-1;;;100344:20:0;;;;100329:12:::1;::::0;-1:-1:-1;;;;;100344:8:0::1;::::0;:18:::1;::::0;:20:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:8;:20;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100329:35;;100390:5;:14;;;100407:1;100390:18;100383:4;:25;100379:146;;;100429:8;::::0;100462:14:::1;::::0;::::1;::::0;100429:80:::1;::::0;-1:-1:-1;;;100429:80:0;;-1:-1:-1;;;;;100429:8:0;;::::1;::::0;:32:::1;::::0;:80:::1;::::0;100462:25;;;;100429:8;100462:25;;100489:10:::1;::::0;100501:7;;100429:80:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;100379:146;100545:12:::0;;100541:286:::1;;;100597:15;::::0;::::1;::::0;100578::::1;:34:::0;;;;;::::1;::::0;;100631:8:::1;::::0;100653:18:::1;::::0;::::1;::::0;100631:41:::1;::::0;-1:-1:-1;;;100631:41:0;;-1:-1:-1;;;;;100631:8:0;;::::1;::::0;:21:::1;::::0;:41:::1;::::0;::::1;;14255:25:1::0;;;14243:2;14228:18;;14210:76;100631:41:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;100541:286;;;100734:15;::::0;::::1;::::0;100713:17:::1;:36:::0;;;;;::::1;::::0;;100768:8:::1;::::0;100792:18:::1;::::0;::::1;::::0;100768:43:::1;::::0;-1:-1:-1;;;100768:43:0;;-1:-1:-1;;;;;100768:8:0;;::::1;::::0;:23:::1;::::0;:43:::1;::::0;::::1;;14255:25:1::0;;;14243:2;14228:18;;14210:76;100768:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;100541:286;100891:19;::::0;::::1;::::0;100843:29:::1;::::0;100891:23;100887:742:::1;;100939:20:::0;;100935:410:::1;;101003:21;::::0;:56:::1;::::0;-1:-1:-1;;;101003:56:0;;100984:16:::1;::::0;-1:-1:-1;;;;;101003:21:0::1;::::0;:40:::1;::::0;:56:::1;::::0;101044:5;;101051:7;;101003:56:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101131:21;::::0;101216:14:::1;::::0;::::1;::::0;101131:107:::1;::::0;-1:-1:-1;;;101131:107:0;;101170:10:::1;101131:107;::::0;::::1;11166:34:1::0;-1:-1:-1;;;;;11236:15:1;;;11216:18;;;11209:43;11268:18;;;11261:34;;;101210:20:0;;::::1;11311:18:1::0;;;11304:34;101131:21:0::1;11354:19:1::0;;;11347:51;100984:75:0;;-1:-1:-1;101131:21:0::1;::::0;:38:::1;::::0;11100:19:1;;101131:107:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;101082:156;;101280:45;101285:21;101308:16;101280:4;:45::i;:::-;101261:64;;100935:410;;100887:742;;;101385:8;::::0;101415:15:::1;::::0;::::1;::::0;-1:-1:-1;;;;;101385:8:0;;::::1;::::0;:29:::1;::::0;101415:34;-1:-1:-1;101415:75:0::1;;101489:1;101415:75;;;101470:16;101452:5;:15;;;:34;101415:75;101385:106;;;;;;;;;;;;;14255:25:1::0;;14243:2;14228:18;;14210:76;101385:106:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;101533:1;101514:16;:20;101510:104;;;101559:35;101565:10;101577:16;101559:5;:35::i;:::-;101649:7;:68;;;;;101660:57;101673:10;54552:27;-1:-1:-1::0;;;101712:1:0::1;101715::::0;101660:12:::1;:57::i;:::-;101645:145;;;101738:13;::::0;:36:::1;::::0;-1:-1:-1;;;101738:36:0;;-1:-1:-1;;;;;101738:13:0;;::::1;::::0;:21:::1;::::0;:36:::1;::::0;101760:10:::1;::::0;101738:13;;:36:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;101645:145;101945:61;::::0;;-1:-1:-1;;;;;13355:32:1;;13337:51;;13419:2;13404:18;;13397:34;;;13447:18;;;13440:34;;;101961:10:0::1;::::0;101945:61:::1;::::0;13325:2:1;13310:18;101945:61:0::1;;;;;;;-1:-1:-1::0;;7027:1:0;7981:7;:22;-1:-1:-1;;;;;;;;97269:4756:0:o;20068:380::-;-1:-1:-1;;;;;20204:19:0;;20196:68;;;;-1:-1:-1;;;20196:68:0;;21981:2:1;20196:68:0;;;21963:21:1;22020:2;22000:18;;;21993:30;22059:34;22039:18;;;22032:62;-1:-1:-1;;;22110:18:1;;;22103:34;22154:19;;20196:68:0;21953:226:1;20196:68:0;-1:-1:-1;;;;;20283:21:0;;20275:68;;;;-1:-1:-1;;;20275:68:0;;18482:2:1;20275:68:0;;;18464:21:1;18521:2;18501:18;;;18494:30;18560:34;18540:18;;;18533:62;-1:-1:-1;;;18611:18:1;;;18604:32;18653:19;;20275:68:0;18454:224:1;20275:68:0;-1:-1:-1;;;;;20356:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;20408:32;;14255:25:1;;;20408:32:0;;14228:18:1;20408:32:0;;;;;;;;20068:380;;;:::o;67449:247::-;67501:7;55523:10;67525:15;:34;67521:68;;;67568:21;;-1:-1:-1;;;67568:21:0;;;;;;;;;;;67521:68;-1:-1:-1;67671:6:0;67633:15;-1:-1:-1;;67633:34:0;67632:45;;67449:247::o;18307:399::-;-1:-1:-1;;;;;18391:21:0;;18383:65;;;;-1:-1:-1;;;18383:65:0;;23152:2:1;18383:65:0;;;23134:21:1;23191:2;23171:18;;;23164:30;23230:33;23210:18;;;23203:61;23281:18;;18383:65:0;23124:181:1;18383:65:0;18539:6;18523:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;18556:18:0;;:9;:18;;;;;;;;;;:28;;18578:6;;18556:9;:28;;18578:6;;18556:28;:::i;:::-;;;;-1:-1:-1;;18600:37:0;;14255:25:1;;;-1:-1:-1;;;;;18600:37:0;;;18617:1;;18600:37;;14243:2:1;14228:18;18600:37:0;;;;;;;70437:164;;:::o;20739:453::-;20874:24;20901:25;20911:5;20918:7;20901:9;:25::i;:::-;20874:52;;-1:-1:-1;;20941:16:0;:37;20937:248;;21023:6;21003:16;:26;;20995:68;;;;-1:-1:-1;;;20995:68:0;;18885:2:1;20995:68:0;;;18867:21:1;18924:2;18904:18;;;18897:30;18963:31;18943:18;;;18936:59;19012:18;;20995:68:0;18857:179:1;20995:68:0;21107:51;21116:5;21123:7;21151:6;21132:16;:25;21107:8;:51::i;:::-;20739:453;;;;:::o;17349:671::-;-1:-1:-1;;;;;17480:18:0;;17472:68;;;;-1:-1:-1;;;17472:68:0;;21575:2:1;17472:68:0;;;21557:21:1;21614:2;21594:18;;;21587:30;21653:34;21633:18;;;21626:62;-1:-1:-1;;;21704:18:1;;;21697:35;21749:19;;17472:68:0;21547:227:1;17472:68:0;-1:-1:-1;;;;;17559:16:0;;17551:64;;;;-1:-1:-1;;;17551:64:0;;17315:2:1;17551:64:0;;;17297:21:1;17354:2;17334:18;;;17327:30;17393:34;17373:18;;;17366:62;-1:-1:-1;;;17444:18:1;;;17437:33;17487:19;;17551:64:0;17287:225:1;17551:64:0;-1:-1:-1;;;;;17701:15:0;;17679:19;17701:15;;;;;;;;;;;17735:21;;;;17727:72;;;;-1:-1:-1;;;17727:72:0;;19601:2:1;17727:72:0;;;19583:21:1;19640:2;19620:18;;;19613:30;19679:34;19659:18;;;19652:62;-1:-1:-1;;;19730:18:1;;;19723:36;19776:19;;17727:72:0;19573:228:1;17727:72:0;-1:-1:-1;;;;;17835:15:0;;;:9;:15;;;;;;;;;;;17853:20;;;17835:38;;17895:13;;;;;;;;:23;;17867:6;;17835:9;17895:23;;17867:6;;17895:23;:::i;:::-;;;;;;;;17951:2;-1:-1:-1;;;;;17936:26:0;17945:4;-1:-1:-1;;;;;17936:26:0;;17955:6;17936:26;;;;14255:25:1;;14243:2;14228:18;;14210:76;17936:26:0;;;;;;;;17975:37;19039:591;120850:1307;120985:4;121109:10;;121105:155;;121160:15;;:35;;-1:-1:-1;;;121160:35:0;;;;;14255:25:1;;;55729:13:0;;-1:-1:-1;;;;;121160:15:0;;:27;;14228:18:1;;121160:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;121150:7;:45;:94;;;-1:-1:-1;;;121150:94:0;;;;;;;;;;121140:104;;121105:155;121291:6;121280:7;:17;121276:69;;-1:-1:-1;121325:4:0;121318:11;;121276:69;121636:14;121679:6;121653:23;121661:7;121670:5;121653:7;:23::i;:::-;:32;;;-1:-1:-1;;;121653:32:0;;;;;;;;;122122:16;;;121653:32;;;122112:26;;;-1:-1:-1;;120850:1307:0;;;;;;;;:::o;39993:314::-;40046:7;40078:4;-1:-1:-1;;;;;40087:12:0;40070:29;;:66;;;;;40120:16;40103:13;:33;40070:66;40066:234;;;-1:-1:-1;40160:24:0;;39993:314::o;40066:234::-;-1:-1:-1;40496:73:0;;;40246:10;40496:73;;;;15146:25:1;;;;40258:12:0;15187:18:1;;;15180:34;40272:15:0;15230:18:1;;;15223:34;40540:13:0;15273:18:1;;;15266:34;40563:4:0;15316:19:1;;;;15309:61;;;;40496:73:0;;;;;;;;;;15118:19:1;;;;40496:73:0;;;40486:84;;;;;;44234:115::o;79604:6162::-;79878:14;;:44;;-1:-1:-1;;;79878:44:0;;79752:26;;;;;;;;-1:-1:-1;;;;;79878:14:0;;;;:25;;:44;;79904:5;;79911:10;;79878:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;79852:70;;79958:24;79985:19;:17;:19::i;:::-;80236:14;;;;80096:17;;;;79958:46;;-1:-1:-1;80019:18:0;;80079:34;;80059:55;;:155;;80196:5;:17;;;80179:5;:14;;;:34;80059:155;;;80138:16;80059:155;80040:210;80019:231;;80289:25;80317:15;;;;;;;;;-1:-1:-1;;;;;80317:15:0;-1:-1:-1;;;;;80317:33:0;;80351:5;80358:10;80370:16;80388:7;80317:79;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;80289:107;;80452:5;:17;;;80439:10;:30;80435:4029;;;80556:76;80572:5;80579:7;80588:6;:22;;;80612:6;:19;;;80556:15;:76::i;:::-;80538:94;;80657:7;80653:521;;;80693:112;80706:5;80720;:12;;;:23;;80740:3;80720:23;;;80735:2;80720:23;80713:31;;54265:28;80713:31;;;-1:-1:-1;;;80713:31:0;;;;;;;;;;-1:-1:-1;;;80786:5:0;:15;;;80803:1;80693:12;:112::i;:::-;80689:466;;;80855:13;;:31;;-1:-1:-1;;;80855:31:0;;-1:-1:-1;;;;;80855:13:0;;;;:21;;:31;;80877:5;;80855:13;;:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80435:4029;;80689:466;80941:11;:109;;;;;80981:69;80994:5;-1:-1:-1;;;55062:28:0;81031:5;:15;;;81048:1;80981:12;:69::i;:::-;80937:218;;;81100:13;;:31;;-1:-1:-1;;;81100:31:0;;-1:-1:-1;;;;;81100:13:0;;;;:21;;:31;;81122:5;;81100:13;;:31;;;:::i;80937:218::-;80435:4029;;;81254:5;:17;;;81237:5;:14;;;:34;81274:1;81237:38;81218:16;:57;81214:3235;;;81395:76;81411:5;81418:7;81427:6;:22;;;81451:6;:19;;;81395:15;:76::i;:::-;81377:94;;81500:7;81496:754;;;81536:11;81586;81582:293;;;81634:65;81647:5;81660:2;54265:28;81654:8;-1:-1:-1;;;81679:5:0;:15;;;81696:2;81634:12;:65::i;:::-;81630:218;;;81736:13;;;;;;;;;-1:-1:-1;;;;;81736:13:0;-1:-1:-1;;;;;81736:21:0;;81758:5;81765:2;81736:32;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81812:4;81803:13;;81630:218;81908:6;81903:324;;81951:120;81964:5;81978;:12;;;:23;;81998:3;81978:23;;;81993:2;81978:23;81971:31;;54265:28;81971:31;;;-1:-1:-1;;;81971:31:0;;;;;;;;;;-1:-1:-1;;;82052:5:0;:15;;;82069:1;81951:12;:120::i;:::-;81947:253;;;82137:13;;;;;;;;;-1:-1:-1;;;;;82137:13:0;-1:-1:-1;;;;;82137:21:0;;82159:5;82166:1;82137:31;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81947:253;81496:754;81214:3235;;;82440:7;82436:1994;;;82573:2;82553:5;:17;;;:22;82549:1858;;;82828:102;82841:5;-1:-1:-1;;;55062:28:0;82911:5;:15;;;82928:1;82828:12;:102::i;:::-;82824:235;;;82996:13;;:31;;-1:-1:-1;;;82996:31:0;;-1:-1:-1;;;;;82996:13:0;;;;:21;;:31;;83018:5;;82996:13;;:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82824:235;83254:11;83250:334;;;83306:106;83319:5;-1:-1:-1;;;55062:28:0;83393:5;:15;;;83410:1;83306:12;:106::i;:::-;83302:251;;;83486:13;;:31;;-1:-1:-1;;;83486:31:0;;-1:-1:-1;;;;;83486:13:0;;;;:21;;:31;;83508:5;;83515:1;;83486:31;;;:::i;82549:1858::-;83646:94;83659:5;83672:3;54265:28;83666:9;;83646:94;83642:765;;;83931:13;;:31;;-1:-1:-1;;;83931:31:0;;-1:-1:-1;;;;;83931:13:0;;;;:21;;:31;;83953:5;;83931:13;;:31;;;:::i;83642:765::-;84025:11;:115;;;;;84040:100;84083:5;-1:-1:-1;;;55062:28:0;84120:5;:15;;;84137:2;84040:12;:100::i;:::-;84021:386;;;84348:13;;:31;;-1:-1:-1;;;84348:31:0;;-1:-1:-1;;;;;84348:13:0;;;;:21;;:31;;84370:5;;84348:13;;:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84021:386;84523:191;84561:5;84585:16;84620:6;:17;;;84656:6;:17;;;84692:7;84523:19;:191::i;:::-;84735:19;;;;:23;84731:1017;;84873:160;84920:5;84927;84934:10;84946:7;84976:6;:22;;;85000:6;:19;;;85021:11;84873:24;:160::i;:::-;84832:201;;-1:-1:-1;84832:201:0;-1:-1:-1;84731:1017:0;;;85266:15;85284:7;85266:25;;85310:16;85329:11;85310:30;;85400:332;85442:5;85470;85498:6;:22;;;85543:6;:22;;;85588:6;:19;;;85630:6;:19;;;85672:7;85702:11;85400:19;:332::i;:::-;85359:373;;-1:-1:-1;85359:373:0;-1:-1:-1;;;84731:1017:0;79604:6162;;;;;;;;;;;;;:::o;19039:591::-;-1:-1:-1;;;;;19123:21:0;;19115:67;;;;-1:-1:-1;;;19115:67:0;;21173:2:1;19115:67:0;;;21155:21:1;21212:2;21192:18;;;21185:30;21251:34;21231:18;;;21224:62;-1:-1:-1;;;21302:18:1;;;21295:31;21343:19;;19115:67:0;21145:223:1;19115:67:0;-1:-1:-1;;;;;19282:18:0;;19257:22;19282:18;;;;;;;;;;;19319:24;;;;19311:71;;;;-1:-1:-1;;;19311:71:0;;17719:2:1;19311:71:0;;;17701:21:1;17758:2;17738:18;;;17731:30;17797:34;17777:18;;;17770:62;-1:-1:-1;;;17848:18:1;;;17841:32;17890:19;;19311:71:0;17691:224:1;19311:71:0;-1:-1:-1;;;;;19418:18:0;;:9;:18;;;;;;;;;;19439:23;;;19418:44;;19484:12;:22;;19456:6;;19418:9;19484:22;;19456:6;;19484:22;:::i;:::-;;;;-1:-1:-1;;19524:37:0;;14255:25:1;;;19550:1:0;;-1:-1:-1;;;;;19524:37:0;;;;;14243:2:1;14228:18;19524:37:0;14210:76:1;104469:5144:0;104660:37;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104660:37:0;104760:14;;:61;;-1:-1:-1;;;104760:61:0;;-1:-1:-1;;;;;13355:32:1;;;104760:61:0;;;13337:51:1;13404:18;;;13397:34;;;104805:15:0;13447:18:1;;;13440:34;104760:14:0;;;;:28;;13310:18:1;;104760:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;104846:15:0;104832:11;;;:29;-1:-1:-1;;104872:15:0;;104907;;;;104872:51;;-1:-1:-1;;;104872:51:0;;-1:-1:-1;;;;;104872:15:0;;;;:34;;:51;;;;14255:25:1;;;14243:2;14228:18;;14210:76;104872:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;104955:15:0;;:37;;-1:-1:-1;;;104955:37:0;;104934:18;;-1:-1:-1;;;;;;104955:15:0;;;;-1:-1:-1;104955:30:0;;:37;;104986:5;;104955:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105497:8;;105538:14;;;;105567:17;;;;105497:97;;-1:-1:-1;;;105497:97:0;;105526:10;105497:97;;;13710:51:1;13777:18;;;13770:34;;;;13820:18;;;13813:34;13890:14;;13883:22;13863:18;;;13856:50;104934:58:0;;-1:-1:-1;;;;;;105497:8:0;;:28;;13682:19:1;;105497:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105630:20;105671:10;105653:5;:15;;;:28;:63;;105715:1;105653:63;;;105702:10;105684:5;:15;;;:28;105653:63;105787:8;;105810:14;;;;105843:17;;;;105866:12;;105787:92;;-1:-1:-1;;;105787:92:0;;;;;26748:25:1;;;105826:34:0;;;;-1:-1:-1;;105826:38:0;26789:18:1;;;26782:34;26859:14;;26852:22;26832:18;;;26825:50;105630:86:0;;-1:-1:-1;105731:15:0;;55603:19;;-1:-1:-1;;;;;105787:8:0;;:22;;26721:18:1;;105787:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;105749:5;:18;;;:130;:165;;;-1:-1:-1;;;105749:165:0;;;;;;;;;;;-1:-1:-1;105949:22:0;;;106022:61;106049:5;106056:17;105749:165;106022:26;:61::i;:::-;-1:-1:-1;;;54552:27:0;106155:22;;:38;106242:32;106247:12;106155:38;106242:4;:32::i;:::-;106208:31;;;:66;106295:19;;;;:23;106291:3302;;106856:21;;106950:58;;-1:-1:-1;;;106950:58:0;;106675:5;;106715:7;;106758:5;;106801:7;;106647:24;;-1:-1:-1;;;;;106856:21:0;;:38;;106917:10;;106856:21;;106950:40;;:58;;106758:5;;106801:7;;106950:58;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107031:12;:31;;;107107:6;:15;;;107085:19;:17;:19::i;:::-;106856:316;;-1:-1:-1;;;;;;106856:316:0;;;;;;;-1:-1:-1;;;;;11184:15:1;;;106856:316:0;;;11166:34:1;11236:15;;;;11216:18;;;11209:43;11268:18;;;11261:34;;;;107085:37:0;;11311:18:1;;;11304:34;11382:14;;11375:22;11354:19;;;11347:51;11100:19;;106856:316:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107220:21;;106829:343;;-1:-1:-1;107193:24:0;;-1:-1:-1;;;;;107220:21:0;:37;107280:6;107288;107296:8;107193:24;107339:19;:17;:19::i;:::-;107360:4;107220:145;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;107193:172;;107437:16;107422:12;:31;:69;;107490:1;107422:69;;;107471:16;107456:12;:31;107422:69;107386:33;;;:105;107510:31;;;:51;;;;;;;;;107914:35;;;:69;108006:23;;;108002:313;;;108093:23;;;108054:62;;;108139:8;;:67;;-1:-1:-1;;;108139:67:0;;;;;14255:25:1;;;;-1:-1:-1;;;;;108139:8:0;;:29;;14228:18:1;;108139:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108002:313;;;108294:1;108255:40;;108002:313;108380:12;:33;;;108370:7;:43;:93;;108462:1;108370:93;;;108426:12;:33;;;108416:7;:43;108370:93;108333:34;;;:130;108488:18;;;;108484:270;;108540:13;;108536:199;;;108601:16;;;;108582:15;:35;;;;;;;;108536:199;;;108695:16;;;;108674:17;:37;;;;;;;;108536:199;106291:3302;;;;;;;;;;108869:12;108854;:27;:61;;108914:1;108854:61;;;108899:12;108884;:27;108854:61;108818:33;;;:97;108988:31;;;;108973:46;;:99;;109071:1;108973:99;;;109037:12;:31;;;109022:12;:46;108973:99;108934:138;;109138:33;;;;109128:43;;:93;;109220:1;109128:93;;;109184:12;:33;;;109174:7;:43;109128:93;109091:34;;;:130;109246:17;;;;109242:336;;109294:8;;109324:15;;;;109294:46;;-1:-1:-1;;;109294:46:0;;-1:-1:-1;;;;;109294:8:0;;;;:29;;:46;;;;14255:25:1;;;14243:2;14228:18;;14210:76;109294:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109367:5;:12;;;109363:196;;;109427:15;;;;109408;:34;;;;;;;;109363:196;;;109520:15;;;;109499:17;:36;;;;;;;;109363:196;104469:5144;;;;;;;;;;;;:::o;109621:1518::-;109963:47;;;109938:22;54265:28;-1:-1:-1;;;110058:30:0;;110109:8;;:50;;-1:-1:-1;;;110109:50:0;;110058:36;;;;110109:50;;;14255:25:1;;;110058:36:0;-1:-1:-1;;;;;;110109:8:0;;:26;;14228:18:1;;110109:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110174:12;-1:-1:-1;;;54552:27:0;110232:14;:27;:43;;;-1:-1:-1;;;110232:43:0;;;;;;;;;;110189:39;;;:87;;-1:-1:-1;110314:25:0;;;:48;;110383:16;;110379:100;;110420:8;;:43;;-1:-1:-1;;;110420:43:0;;;;;14255:25:1;;;-1:-1:-1;;;;;110420:8:0;;;;:29;;14228:18:1;;110420:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110379:100;110499:8;;110495:75;;110534:13;;110528:26;;-1:-1:-1;;;;;110534:13:0;110549:4;110528:5;:26::i;:::-;110806:60;110812:10;110847:18;110824:20;:41;110806:5;:60::i;:::-;110918:10;-1:-1:-1;;;;;110888:232:0;;;110909:7;110947:18;110967:20;111006:22;111030:4;-1:-1:-1;;;54552:27:0;111037;;:43;111100:5;110888:232;;;;;;;;;;;;:::i;:::-;;;;;;;;109621:1518;;;;;;;;;;;:::o;44487:207::-;-1:-1:-1;;;;;44608:14:0;;44547:15;44608:14;;;:7;:14;;;;;4735;;4872:1;4854:19;;;;4735:14;44669:17;44487:207;;;;:::o;41220:167::-;41297:7;41324:55;41346:20;:18;:20::i;:::-;41368:10;36669:57;;-1:-1:-1;;;36669:57:0;;;9784:27:1;9827:11;;;9820:27;;;9863:12;;;9856:28;;;36632:7:0;;9900:12:1;;36669:57:0;;;;;;;;;;;;36659:68;;;;;;36652:75;;36539:196;;;;;34848:279;34976:7;34997:17;35016:18;35038:25;35049:4;35055:1;35058;35061;35038:10;:25::i;:::-;34996:67;;;;35074:18;35086:5;35074:11;:18::i;:::-;-1:-1:-1;35110:9:0;34848:279;-1:-1:-1;;;;;34848:279:0:o;45944:190::-;46069:4;46122;46093:25;46106:5;46113:4;46093:12;:25::i;:::-;:33;;45944:190;-1:-1:-1;;;;45944:190:0:o;102270:209::-;102333:7;102459:1;102440;102436;:5;;;-1:-1:-1;;;102436:5:0;;;;;;;;;;:10;:18;;102453:1;102436:18;;;102449:1;102436:18;102427:28;;102431:1;102427;:5;;;-1:-1:-1;;;102427:5:0;;;;;;;;;;:28;102426:34;;102270:209;-1:-1:-1;;;102270:209:0:o;102644:107::-;102703:7;102734:1;102730;:5;:13;;102742:1;102730:13;;;102738:1;102730:13;102723:20;102644:107;-1:-1:-1;;;102644:107:0:o;119717:406::-;119788:7;119948:15;119941:4;:22;120000:12;119990:23;120040:7;119898:172;;;;;;;;;10108:19:1;;;10152:2;10143:12;;10136:28;;;;10202:2;10198:15;-1:-1:-1;;10194:53:1;10189:2;10180:12;;10173:75;10273:2;10264:12;;10098:184;119898:172:0;;;;-1:-1:-1;;119898:172:0;;;;;;;;;119866:223;;119898:172;119866:223;;;;;119717:406;-1:-1:-1;;;119717:406:0:o;113710:1391::-;113891:30;113959:22;114022:1;114000:5;:19;;;:23;113996:680;;;114061:51;114066:7;114096:15;114075:18;:36;114061:4;:51::i;:::-;114044:68;;114149:14;114131:32;;114203:1;114182:22;;113996:680;;;114249:17;;;;114245:344;;114300:12;;114296:202;;;114341:15;:37;;;;;;;114296:202;;;114435:17;:39;;;;;;;114296:202;114520:8;;:49;;-1:-1:-1;;;114520:49:0;;;;;14255:25:1;;;-1:-1:-1;;;;;114520:8:0;;;;:29;;14228:18:1;;114520:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114245:344;-1:-1:-1;114624:36:0;;;113996:680;114768:8;;:50;;-1:-1:-1;;;114768:50:0;;54265:28;-1:-1:-1;;;114717:30:0;;:36;114768:50;;;14255:25:1;;;114717:36:0;-1:-1:-1;;;;;;114768:8:0;;;;:26;;14228:18:1;;114768:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114833:25;-1:-1:-1;;;54552:27:0;114920:14;:27;:43;;;-1:-1:-1;;;114920:43:0;;;;;;;;;114986:13;;114920:43;;;114861:39;;;:102;;-1:-1:-1;114980:39:0;;-1:-1:-1;;;;;114986:13:0;114861:102;114980:5;:39::i;:::-;115034:8;;:48;;-1:-1:-1;;;115034:48:0;;;;;14255:25:1;;;-1:-1:-1;;;;;115034:8:0;;;;:29;;14228:18:1;;115034:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113710:1391;;;;;;;;:::o;72208:1112::-;72421:17;;;;72417:233;;72465:12;;72460:179;;72498:8;;72522:18;;;;72498:43;;-1:-1:-1;;;72498:43:0;;-1:-1:-1;;;;;72498:8:0;;;;:23;;:43;;;;14255:25:1;;;14243:2;14228:18;;14210:76;72498:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72460:179;;;72582:8;;72604:18;;;;72582:41;;-1:-1:-1;;;72582:41:0;;-1:-1:-1;;;;;72582:8:0;;;;:21;;:41;;;;14255:25:1;;;14243:2;14228:18;;14210:76;72582:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72460:179;72685:18;72788:5;:17;;;72771:5;:14;;;:34;72752:16;:53;:70;;72821:1;72752:70;;;72808:10;72752:70;72724:7;72706:5;:15;;;:25;:117;72685:138;;73150:5;:15;;;73136:10;:29;73132:170;;73231:8;;-1:-1:-1;;;;;73231:8:0;:21;73253:32;73267:5;73274:10;73253:13;:32::i;:::-;73231:55;;;;;;;;;;;;;14255:25:1;;14243:2;14228:18;;14210:76;73231:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73132:170;72208:1112;;;;;;:::o;85774:1823::-;86051:26;86079:24;86143:23;86169:54;86174:8;86206:16;86184:19;:38;86169:4;:54::i;:::-;86143:80;;86238:24;86265:19;:17;:19::i;:::-;86238:46;;86328:6;:18;;;86350:1;86328:23;86324:99;;;86391:16;;;;86372:15;:35;;;;;;;;86324:99;86713:13;86729:6;86713:22;;86750:29;86782:21;;;;;;;;;-1:-1:-1;;;;;86782:21:0;-1:-1:-1;;;;;86782:37:0;;86838:6;86846:5;86853:11;86866:5;86890:16;86908:12;86782:139;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;86750:171;;87105:21;87086:6;:16;;;:40;:104;;87189:1;87086:104;;;87165:21;87146:6;:16;;;:40;87086:104;87065:125;;87460:15;87449:8;:26;87430:45;;87490:88;87520:5;87527:18;87547:16;87565:12;87490:29;:88::i;:::-;85774:1823;;;;;;;;;;;;;;:::o;74216:4679::-;74511:26;74539:24;74601:26;74630:78;74635:15;74670;;;;;;;;;-1:-1:-1;;;;;74670:15:0;-1:-1:-1;;;;;74670:30:0;;74701:5;74670:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74652:15;:55;74630:4;:78::i;:::-;74601:107;;74723:23;74749:32;74754:12;74768;74749:4;:32::i;:::-;74723:58;;74835:18;74817:5;:15;;;:36;:79;;74895:1;74817:79;;;74874:18;74856:5;:15;;;:36;74817:79;74796:100;;74940:15;74930:7;:25;:57;;74986:1;74930:57;;;74968:15;74958:7;:25;74930:57;74911:76;;75008:5;:17;;;75029:1;75008:22;75004:3226;;;75477:12;;75473:824;;;75821:15;;;;75802;:34;;;;;;;;75473:824;;;76262:15;;;;76241:17;:36;;;;;;;;75473:824;76340:1;76321:16;:20;:36;;;;;76346:11;76345:12;76321:36;76317:132;;;76382:8;;:47;;-1:-1:-1;;;76382:47:0;;;;;14255:25:1;;;-1:-1:-1;;;;;76382:8:0;;;;:29;;14228:18:1;;76382:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76317:132;76613:11;76609:623;;;76649:8;;76679:15;;;;76649:46;;-1:-1:-1;;;76649:46:0;;-1:-1:-1;;;;;76649:8:0;;;;:29;;:46;;;;14255:25:1;;;14243:2;14228:18;;14210:76;76649:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75004:3226;;76609:623;77163:8;;:49;;-1:-1:-1;;;77163:49:0;;;;;14255:25:1;;;-1:-1:-1;;;;;77163:8:0;;;;:29;;14228:18:1;;77163:49:0;14210:76:1;75004:3226:0;78146:8;;:68;;-1:-1:-1;;;78146:68:0;;78176:37;;;78146:68;;;14255:25:1;-1:-1:-1;;;;;78146:8:0;;;;:29;;14228:18:1;;78146:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75004:3226;78733:11;78732:12;:57;;;;;78788:1;78769:16;78748:18;:37;:41;78732:57;78728:149;;;78810:51;78816:5;78844:16;78823:18;:37;78810:5;:51::i;:::-;74216:4679;;;;;;;;;;;;;:::o;111228:498::-;111373:17;;;;111369:233;;111417:12;;111412:179;;111450:8;;111474:18;;;;111450:43;;-1:-1:-1;;;111450:43:0;;-1:-1:-1;;;;;111450:8:0;;;;:23;;:43;;;;14255:25:1;;;14243:2;14228:18;;14210:76;111450:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111412:179;;;111534:8;;111556:18;;;;111534:41;;-1:-1:-1;;;111534:41:0;;-1:-1:-1;;;;;111534:8:0;;;;:21;;:41;;;;14255:25:1;;;14243:2;14228:18;;14210:76;111534:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111412:179;111637:8;;111680:15;;;;-1:-1:-1;;;;;111637:8:0;;;;:21;;111659:47;;111673:5;;111680:25;;111659:13;:47::i;:::-;111637:70;;;;;;;;;;;;;14255:25:1;;14243:2;14228:18;;14210:76;111637:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111228:498;;;:::o;33077:1632::-;33208:7;;34142:66;34129:79;;34125:163;;;-1:-1:-1;34241:1:0;;-1:-1:-1;34245:30:0;34225:51;;34125:163;34302:1;:7;;34307:2;34302:7;;:18;;;;;34313:1;:7;;34318:2;34313:7;;34302:18;34298:102;;;-1:-1:-1;34353:1:0;;-1:-1:-1;34357:30:0;34337:51;;34298:102;34514:24;;;34497:14;34514:24;;;;;;;;;15608:25:1;;;15681:4;15669:17;;15649:18;;;15642:45;;;;15703:18;;;15696:34;;;15746:18;;;15739:34;;;34514:24:0;;15580:19:1;;34514:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;34514:24:0;;-1:-1:-1;;34514:24:0;;;-1:-1:-1;;;;;;;34553:20:0;;34549:103;;34606:1;34610:29;34590:50;;;;;;;34549:103;34672:6;-1:-1:-1;34680:20:0;;-1:-1:-1;33077:1632:0;;;;;;;;:::o;27786:643::-;27864:20;27855:5;:29;;;;;;-1:-1:-1;;;27855:29:0;;;;;;;;;;27851:571;;;27786:643;:::o;27851:571::-;27962:29;27953:5;:38;;;;;;-1:-1:-1;;;27953:38:0;;;;;;;;;;27949:473;;;28008:34;;-1:-1:-1;;;28008:34:0;;16962:2:1;28008:34:0;;;16944:21:1;17001:2;16981:18;;;16974:30;17040:26;17020:18;;;17013:54;17084:18;;28008:34:0;16934:174:1;27949:473:0;28073:35;28064:5;:44;;;;;;-1:-1:-1;;;28064:44:0;;;;;;;;;;28060:362;;;28125:41;;-1:-1:-1;;;28125:41:0;;18122:2:1;28125:41:0;;;18104:21:1;18161:2;18141:18;;;18134:30;18200:33;18180:18;;;18173:61;18251:18;;28125:41:0;18094:181:1;28060:362:0;28197:30;28188:5;:39;;;;;;-1:-1:-1;;;28188:39:0;;;;;;;;;;28184:238;;;28244:44;;-1:-1:-1;;;28244:44:0;;20008:2:1;28244:44:0;;;19990:21:1;20047:2;20027:18;;;20020:30;20086:34;20066:18;;;20059:62;-1:-1:-1;;;20137:18:1;;;20130:32;20179:19;;28244:44:0;19980:224:1;28184:238:0;28319:30;28310:5;:39;;;;;;-1:-1:-1;;;28310:39:0;;;;;;;;;;28306:116;;;28366:44;;-1:-1:-1;;;28366:44:0;;20411:2:1;28366:44:0;;;20393:21:1;20450:2;20430:18;;;20423:30;20489:34;20469:18;;;20462:62;-1:-1:-1;;;20540:18:1;;;20533:32;20582:19;;28366:44:0;20383:224:1;28306:116:0;27786:643;:::o;46495:675::-;46578:7;46621:4;46578:7;46636:497;46660:5;:12;46656:1;:16;46636:497;;;46694:20;46717:5;46723:1;46717:8;;;;;;-1:-1:-1;;;46717:8:0;;;;;;;;;;;;;;;46694:31;;46760:12;46744;:28;46740:382;;47246:13;47296:15;;;47332:4;47325:15;;;47379:4;47363:21;;46872:57;;46740:382;;;47246:13;47296:15;;;47332:4;47325:15;;;47379:4;47363:21;;47049:57;;46740:382;-1:-1:-1;46674:3:0;;;;:::i;:::-;;;;46636:497;;;-1:-1:-1;47150:12:0;46495:675;-1:-1:-1;;;46495:675:0:o;71186:924::-;71276:20;-1:-1:-1;;;72006:5:0;:18;;;71979:6;71930:46;-1:-1:-1;;;71935:10:0;:26;54265:28;71969:6;71963:12;71930:4;:46::i;:::-;71917:10;:59;:68;;;-1:-1:-1;;;71917:68:0;;;;;;;;;;71396:501;54983:28;71423:10;:24;71874:4;71509:336;-1:-1:-1;;;71544:4:0;:20;-1:-1:-1;;;71595:207:0;54552:27;-1:-1:-1;;;71696:26:0;71638:5;:17;;;:85;-1:-1:-1;;;71595:8:0;:207::i;:::-;:223;71509:4;:336::i;:::-;71471:10;:374;71470:408;;;-1:-1:-1;;;71470:408:0;;;;;;;;;;71396:4;:501::i;:::-;-1:-1:-1;;;71350:10:0;:26;:547;:635;71349:675;;;-1:-1:-1;;;71349:675:0;;;;;;;;;;:708;;;-1:-1:-1;;;71349:708:0;;;;;;;;;;;71186:924;-1:-1:-1;;;71186:924:0:o;73406:735::-;73600:11;73595:539;;73727:22;;73723:166;;73803:51;73809:5;73837:16;73816:18;:37;73803:5;:51::i;:::-;74019:20;;74015:108;;74060:8;;:47;;-1:-1:-1;;;74060:47:0;;;;;14255:25:1;;;-1:-1:-1;;;;;74060:8:0;;;;:29;;14228:18:1;;74060:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73406:735;;;;:::o;102916:107::-;102975:7;103006:1;103002;:5;:13;;103014:1;103002:13;;14:395:1;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:2;;166:8;156;149:26;108:2;-1:-1:-1;196:20:1;;239:18;228:30;;225:2;;;278:8;268;261:26;225:2;322:4;314:6;310:17;298:29;;382:3;375:4;365:6;362:1;358:14;350:6;346:27;342:38;339:47;336:2;;;399:1;396;389:12;336:2;98:311;;;;;:::o;414:132::-;490:13;;512:28;490:13;512:28;:::i;:::-;471:75;;;:::o;551:257::-;610:6;663:2;651:9;642:7;638:23;634:32;631:2;;;684:6;676;669:22;631:2;728:9;715:23;747:31;772:5;747:31;:::i;813:261::-;883:6;936:2;924:9;915:7;911:23;907:32;904:2;;;957:6;949;942:22;904:2;994:9;988:16;1013:31;1038:5;1013:31;:::i;1079:398::-;1147:6;1155;1208:2;1196:9;1187:7;1183:23;1179:32;1176:2;;;1229:6;1221;1214:22;1176:2;1273:9;1260:23;1292:31;1317:5;1292:31;:::i;:::-;1342:5;-1:-1:-1;1399:2:1;1384:18;;1371:32;1412:33;1371:32;1412:33;:::i;:::-;1464:7;1454:17;;;1166:311;;;;;:::o;1482:466::-;1559:6;1567;1575;1628:2;1616:9;1607:7;1603:23;1599:32;1596:2;;;1649:6;1641;1634:22;1596:2;1693:9;1680:23;1712:31;1737:5;1712:31;:::i;:::-;1762:5;-1:-1:-1;1819:2:1;1804:18;;1791:32;1832:33;1791:32;1832:33;:::i;:::-;1586:362;;1884:7;;-1:-1:-1;;;1938:2:1;1923:18;;;;1910:32;;1586:362::o;1953:849::-;2064:6;2072;2080;2088;2096;2104;2112;2165:3;2153:9;2144:7;2140:23;2136:33;2133:2;;;2187:6;2179;2172:22;2133:2;2231:9;2218:23;2250:31;2275:5;2250:31;:::i;:::-;2300:5;-1:-1:-1;2357:2:1;2342:18;;2329:32;2370:33;2329:32;2370:33;:::i;:::-;2422:7;-1:-1:-1;2476:2:1;2461:18;;2448:32;;-1:-1:-1;2527:2:1;2512:18;;2499:32;;-1:-1:-1;2583:3:1;2568:19;;2555:33;2632:4;2619:18;;2607:31;;2597:2;;2657:6;2649;2642:22;2597:2;2123:679;;;;-1:-1:-1;2123:679:1;;;;2685:7;2739:3;2724:19;;2711:33;;-1:-1:-1;2791:3:1;2776:19;;;2763:33;;2123:679;-1:-1:-1;;2123:679:1:o;2807:325::-;2875:6;2883;2936:2;2924:9;2915:7;2911:23;2907:32;2904:2;;;2957:6;2949;2942:22;2904:2;3001:9;2988:23;3020:31;3045:5;3020:31;:::i;:::-;3070:5;3122:2;3107:18;;;;3094:32;;-1:-1:-1;;;2894:238:1:o;3137:660::-;3241:6;3249;3257;3265;3318:2;3306:9;3297:7;3293:23;3289:32;3286:2;;;3339:6;3331;3324:22;3286:2;3383:9;3370:23;3402:31;3427:5;3402:31;:::i;:::-;3452:5;-1:-1:-1;3504:2:1;3489:18;;3476:32;;-1:-1:-1;3559:2:1;3544:18;;3531:32;3586:18;3575:30;;3572:2;;;3623:6;3615;3608:22;3572:2;3667:70;3729:7;3720:6;3709:9;3705:22;3667:70;:::i;:::-;3276:521;;;;-1:-1:-1;3756:8:1;-1:-1:-1;;;;3276:521:1:o;3802:796::-;3912:6;3920;3928;3936;3944;3997:3;3985:9;3976:7;3972:23;3968:33;3965:2;;;4019:6;4011;4004:22;3965:2;4063:9;4050:23;4082:31;4107:5;4082:31;:::i;:::-;4132:5;-1:-1:-1;4184:2:1;4169:18;;4156:32;;-1:-1:-1;4239:2:1;4224:18;;4211:32;4266:18;4255:30;;4252:2;;;4303:6;4295;4288:22;4252:2;4347:70;4409:7;4400:6;4389:9;4385:22;4347:70;:::i;:::-;4436:8;;-1:-1:-1;4321:96:1;-1:-1:-1;;4523:2:1;4508:18;;4495:32;4536:30;4495:32;4536:30;:::i;:::-;4585:7;4575:17;;;3955:643;;;;;;;;:::o;4603:460::-;4677:6;4685;4693;4746:2;4734:9;4725:7;4721:23;4717:32;4714:2;;;4767:6;4759;4752:22;4714:2;4811:9;4798:23;4830:31;4855:5;4830:31;:::i;:::-;4880:5;-1:-1:-1;4932:2:1;4917:18;;4904:32;;-1:-1:-1;4988:2:1;4973:18;;4960:32;5001:30;4960:32;5001:30;:::i;:::-;5050:7;5040:17;;;4704:359;;;;;:::o;5068:255::-;5135:6;5188:2;5176:9;5167:7;5163:23;5159:32;5156:2;;;5209:6;5201;5194:22;5156:2;5246:9;5240:16;5265:28;5287:5;5265:28;:::i;5328:1109::-;5426:6;5479:3;5467:9;5458:7;5454:23;5450:33;5447:2;;;5501:6;5493;5486:22;5447:2;5532:17;;:::i;:::-;5572:37;5599:9;5572:37;:::i;:::-;5565:5;5558:52;5642:46;5684:2;5673:9;5669:18;5642:46;:::i;:::-;5637:2;5630:5;5626:14;5619:70;5721:46;5763:2;5752:9;5748:18;5721:46;:::i;:::-;5716:2;5709:5;5705:14;5698:70;5821:2;5810:9;5806:18;5800:25;5795:2;5788:5;5784:14;5777:49;5880:3;5869:9;5865:19;5859:26;5853:3;5846:5;5842:15;5835:51;5940:3;5929:9;5925:19;5919:26;5913:3;5906:5;5902:15;5895:51;6000:3;5989:9;5985:19;5979:26;5973:3;5966:5;5962:15;5955:51;6060:3;6049:9;6045:19;6039:26;6033:3;6026:5;6022:15;6015:51;6085:3;6120:46;6162:2;6151:9;6147:18;6120:46;:::i;:::-;6104:14;;;6097:70;6186:3;6227:18;;;6221:25;6205:14;;;6198:49;6266:3;6307:18;;;6301:25;6285:14;;;6278:49;6346:3;6387:18;;;6381:25;6365:14;;;6358:49;;;;-1:-1:-1;6108:5:1;5437:1000;-1:-1:-1;5437:1000:1:o;6442:864::-;6541:6;6594:3;6582:9;6573:7;6569:23;6565:33;6562:2;;;6616:6;6608;6601:22;6562:2;6654;6648:9;6696:3;6688:6;6684:16;6766:6;6754:10;6751:22;6730:18;6718:10;6715:34;6712:62;6709:2;;;-1:-1:-1;;;6797:36:1;;6856:4;6853:1;6846:15;6889:4;6804:6;6874:20;6709:2;6924:10;6920:2;6913:22;;6965:9;6959:16;6951:6;6944:32;7030:2;7019:9;7015:18;7009:25;7004:2;6996:6;6992:15;6985:50;7089:2;7078:9;7074:18;7068:25;7063:2;7055:6;7051:15;7044:50;7148:2;7137:9;7133:18;7127:25;7122:2;7114:6;7110:15;7103:50;7208:3;7197:9;7193:19;7187:26;7181:3;7173:6;7169:16;7162:52;7269:3;7258:9;7254:19;7248:26;7242:3;7234:6;7230:16;7223:52;7294:6;7284:16;;;6552:754;;;;:::o;7311:190::-;7370:6;7423:2;7411:9;7402:7;7398:23;7394:32;7391:2;;;7444:6;7436;7429:22;7391:2;-1:-1:-1;7472:23:1;;7381:120;-1:-1:-1;7381:120:1:o;7506:194::-;7576:6;7629:2;7617:9;7608:7;7604:23;7600:32;7597:2;;;7650:6;7642;7635:22;7597:2;-1:-1:-1;7678:16:1;;7587:113;-1:-1:-1;7587:113:1:o;7705:454::-;7776:6;7784;7792;7845:2;7833:9;7824:7;7820:23;7816:32;7813:2;;;7866:6;7858;7851:22;7813:2;7907:9;7894:23;7884:33;;7967:2;7956:9;7952:18;7939:32;7980:28;8002:5;7980:28;:::i;:::-;8027:5;-1:-1:-1;8084:2:1;8069:18;;8056:32;8097:30;8056:32;8097:30;:::i;8260:962::-;8340:12;;8234:13;8227:21;8215:34;;8404:4;8397:5;8393:16;8387:23;8419:45;8458:4;8453:3;8449:14;8435:12;8234:13;8227:21;8215:34;;8205:50;8419:45;;8512:4;8505:5;8501:16;8495:23;8527:47;8568:4;8563:3;8559:14;8543;8234:13;8227:21;8215:34;;8205:50;8527:47;;8623:4;8616:5;8612:16;8606:23;8599:4;8594:3;8590:14;8583:47;8679:4;8672:5;8668:16;8662:23;8655:4;8650:3;8646:14;8639:47;8735:4;8728:5;8724:16;8718:23;8711:4;8706:3;8702:14;8695:47;8791:4;8784:5;8780:16;8774:23;8767:4;8762:3;8758:14;8751:47;8847:4;8840:5;8836:16;8830:23;8823:4;8818:3;8814:14;8807:47;8873:6;8927:2;8920:5;8916:14;8910:21;8940:45;8981:2;8976:3;8972:12;8956:14;8234:13;8227:21;8215:34;;8205:50;8940:45;-1:-1:-1;;9004:6:1;9046:14;;;9040:21;9026:12;;;9019:43;9081:6;9123:14;;;9117:21;9103:12;;;9096:43;9158:6;9200:14;;;9194:21;9180:12;;9173:43;8314:908::o;11409:282::-;-1:-1:-1;;;;;11609:32:1;;;;11591:51;;11673:2;11658:18;;11651:34;11579:2;11564:18;;11546:145::o;15784:363::-;15988:25;;;-1:-1:-1;;;;;16049:32:1;;;;16044:2;16029:18;;16022:60;16125:14;16118:22;16113:2;16098:18;;16091:50;15976:2;15961:18;;15943:204::o;16152:603::-;16264:4;16293:2;16322;16311:9;16304:21;16354:6;16348:13;16397:6;16392:2;16381:9;16377:18;16370:34;16422:4;16435:140;16449:6;16446:1;16443:13;16435:140;;;16544:14;;;16540:23;;16534:30;16510:17;;;16529:2;16506:26;16499:66;16464:10;;16435:140;;;16593:6;16590:1;16587:13;16584:2;;;16663:4;16658:2;16649:6;16638:9;16634:22;16630:31;16623:45;16584:2;-1:-1:-1;16739:2:1;16718:15;-1:-1:-1;;16714:29:1;16699:45;;;;16746:2;16695:54;;16273:482;-1:-1:-1;;;16273:482:1:o;22184:355::-;22386:2;22368:21;;;22425:2;22405:18;;;22398:30;22464:33;22459:2;22444:18;;22437:61;22530:2;22515:18;;22358:181::o;23310:256::-;23500:3;23485:19;;23513:47;23489:9;23542:6;23513:47;:::i;23571:682::-;23895:3;23880:19;;23908:47;23884:9;23937:6;23908:47;:::i;:::-;-1:-1:-1;;;;;24030:15:1;;;24024:3;24009:19;;24002:44;24077:3;24062:19;;24055:35;;;;24127:15;;;;24121:3;24106:19;;24099:44;24174:3;24159:19;;24152:35;24231:14;;24224:22;24218:3;24203:19;;;24196:51;;;;23862:391;;-1:-1:-1;23862:391:1:o;24258:570::-;24560:3;24545:19;;24573:47;24549:9;24602:6;24573:47;:::i;:::-;-1:-1:-1;;;;;24657:32:1;;;;24651:3;24636:19;;24629:61;24721:3;24706:19;;24699:35;;;;24765:3;24750:19;;24743:35;;;;24809:3;24794:19;;;24787:35;24527:301;;-1:-1:-1;24527:301:1:o;24833:472::-;25107:3;25092:19;;25120:47;25096:9;25149:6;25120:47;:::i;:::-;25204:6;25198:3;25187:9;25183:19;25176:35;25248:6;25242:3;25231:9;25227:19;25220:35;25292:6;25286:3;25275:9;25271:19;25264:35;25074:231;;;;;;;:::o;25852:695::-;26162:4;26204:3;26193:9;26189:19;26181:27;;26235:6;26224:9;26217:25;26292:6;26285:14;26278:22;26273:2;26262:9;26258:18;26251:50;26337:6;26332:2;26321:9;26317:18;26310:34;26380:6;26375:2;26364:9;26360:18;26353:34;26424:6;26418:3;26407:9;26403:19;26396:35;26468:6;26462:3;26451:9;26447:19;26440:35;26484:57;26536:3;26525:9;26521:19;26513:6;26484:57;:::i;:::-;26171:376;;;;;;;;;;:::o;26886:685::-;27202:4;27244:3;27233:9;27229:19;27221:27;;27275:6;27264:9;27257:25;27318:6;27313:2;27302:9;27298:18;27291:34;27361:6;27356:2;27345:9;27341:18;27334:34;27404:6;27399:2;27388:9;27384:18;27377:34;27448:6;27442:3;27431:9;27427:19;27420:35;27492:6;27486:3;27475:9;27471:19;27464:35;27508:57;27560:3;27549:9;27545:19;27537:6;27508:57;:::i;27765:344::-;27832:2;27826:9;27874:3;27862:16;;27908:18;27893:34;;27929:22;;;27890:62;27887:2;;;27994:10;27989:3;27985:20;27982:1;27975:31;28029:4;28026:1;28019:15;28057:4;28054:1;28047:15;27887:2;28088;28081:22;27806:303;:::o;28114:128::-;28154:3;28185:1;28181:6;28178:1;28175:13;28172:2;;;28191:18;;:::i;:::-;-1:-1:-1;28227:9:1;;28162:80::o;28247:125::-;28287:4;28315:1;28312;28309:8;28306:2;;;28320:18;;:::i;:::-;-1:-1:-1;28357:9:1;;28296:76::o;28377:380::-;28456:1;28452:12;;;;28499;;;28520:2;;28574:4;28566:6;28562:17;28552:27;;28520:2;28627;28619:6;28616:14;28596:18;28593:38;28590:2;;;28673:10;28668:3;28664:20;28661:1;28654:31;28708:4;28705:1;28698:15;28736:4;28733:1;28726:15;28762:135;28801:3;-1:-1:-1;;28822:17:1;;28819:2;;;28842:18;;:::i;:::-;-1:-1:-1;28889:1:1;28878:13;;28809:88::o;28902:127::-;28963:10;28958:3;28954:20;28951:1;28944:31;28994:4;28991:1;28984:15;29018:4;29015:1;29008:15;29034:131;-1:-1:-1;;;;;29109:31:1;;29099:42;;29089:2;;29155:1;29152;29145:12;29170:118;29256:5;29249:13;29242:21;29235:5;29232:32;29222:2;;29278:1;29275;29268:12

Swarm Source

ipfs://cf7fec9b990305171b472ea11addeeab57dabb8532cd6cde4b8907984b8c9518

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

Genius encapsulates human attention and intentions (ie. commitments and promises) to create a Store of Value utility token for traders and savers.

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.