Token xStella MAI Vault

Overview

TokenID:
207

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
stableQiVault

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

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

// 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/access/[email protected]

// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}


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

// 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]

// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

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

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


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

// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;


/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

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

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

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

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

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

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

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


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

// 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/token/ERC20/[email protected]

// 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/security/[email protected]

// 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 contracts/interfaces/IPriceSourceAll.sol

pragma solidity 0.8.11;
interface IPriceSource {
    function latestRoundData() external view returns (uint256);
    function latestAnswer() external view returns (uint256);
    function decimals() external view returns (uint8);
}


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

// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


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

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}


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

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


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

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


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

// 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/introspection/[email protected]

// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}


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

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;







/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` 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 tokenId
    ) 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.
     * - `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 tokenId
    ) internal virtual {}
}


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

// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


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

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


// File contracts/token/MyVaultV4.sol

// contracts/MyVaultNFT.sol
pragma solidity 0.8.11;


contract VaultNFTv4 is ERC721, ERC721Enumerable {

    string public uri;

    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    constructor(string memory name, string memory symbol, string memory _uri)
        ERC721(name, symbol)
    {
        uri = _uri;
    }

    function tokenURI(uint256 tokenId) public override view returns (string memory) {
        require(_exists(tokenId));

        return uri;
    }
}


// File contracts/fixedInterestVaults/fixedVault.sol

pragma solidity 0.8.11;




contract fixedVault is ReentrancyGuard, VaultNFTv4 {
    using SafeERC20 for ERC20;

    /// @dev Constants used across the contract.
    uint256 constant TEN_THOUSAND = 10000;
    uint256 constant ONE_YEAR = 31556952;
    uint256 constant THOUSAND = 1000;

    IPriceSource public ethPriceSource;

    uint256 public _minimumCollateralPercentage;

    uint256 public vaultCount;
    
    uint256 public closingFee;
    uint256 public openingFee;

    uint256 public minDebt;
    uint256 public maxDebt;

    uint256 constant public tokenPeg = 1e8; // $1

    uint256 public iR;

    mapping(uint256 => uint256) public vaultCollateral;
    mapping(uint256 => uint256) public accumulatedVaultDebt;

    mapping(uint256 => uint256) public lastInterest;
    mapping(uint256 => uint256) public promoter;

    uint256 public adminFee; // 10% of the earned interest
    uint256 public refFee; // 90% of the earned interest

    uint256 public debtRatio;
    uint256 public gainRatio;

    ERC20 public collateral;
    ERC20 public mai;

    uint256 public decimalDifferenceRaisedToTen;

    uint256 public priceSourceDecimals;
    uint256 public totalBorrowed;

    mapping(address => uint256) public maticDebt;
    uint256 public maiDebt;

    address public stabilityPool;
    address public adm;
    address public ref;
    uint8 public version = 6;

    event CreateVault(uint256 vaultID, address creator);
    event DestroyVault(uint256 vaultID);
    event DepositCollateral(uint256 vaultID, uint256 amount);
    event WithdrawCollateral(uint256 vaultID, uint256 amount);
    event BorrowToken(uint256 vaultID, uint256 amount);
    event PayBackToken(uint256 vaultID, uint256 amount, uint256 closingFee);
    event LiquidateVault(
        uint256 vaultID,
        address owner,
        address buyer,
        uint256 debtRepaid,
        uint256 collateralLiquidated,
        uint256 closingFee
    );
    event BoughtRiskyDebtVault(uint256 riskyVault, uint256 newVault, address riskyVaultBuyer, uint256 amountPaidtoBuy);

    constructor(
        address ethPriceSourceAddress,
        uint256 minimumCollateralPercentage,
        string memory name,
        string memory symbol,
        address _mai,
        address _collateral,
        string memory baseURI
    ) VaultNFTv4(name, symbol, baseURI) {
        
        require(ethPriceSourceAddress != address(0));
        require(minimumCollateralPercentage != 0);

        closingFee = 50; // 0.5%
        openingFee = 0; // 0.0% 

        ethPriceSource = IPriceSource(ethPriceSourceAddress);
        stabilityPool = address(0);
        
        maxDebt = 500000 ether; //Keeping maxDebt at 500K * 10^(18)


        debtRatio = 2; // 1/2, pay back 50%
        gainRatio = 1100; // /10 so 1.1

        _minimumCollateralPercentage = minimumCollateralPercentage;

        collateral = ERC20(_collateral);
        mai = ERC20(_mai);
        priceSourceDecimals = 8;
        
        /*
            This works only for collaterals with decimals < 18
        */
        decimalDifferenceRaisedToTen =
            10**(mai.decimals() - collateral.decimals());
        
        adm = msg.sender;
        ref = msg.sender;
    }

    modifier onlyVaultOwner(uint256 vaultID) {
        require(_exists(vaultID), "Vault does not exist");
        require(ownerOf(vaultID) == msg.sender, "Vault is not owned by you");
        _;
    }

    modifier vaultExists(uint256 vaultID) {
        require(_exists(vaultID), "Vault does not exist");
        _;
    }

    modifier frontExists(uint256 vaultID) {
        require(_exists(vaultID), "front end vault does not exist");
        require(promoter[vaultID] <= TEN_THOUSAND && promoter[vaultID] > 0, "Front end not added");
        _;
    }

    /// @notice Return the current debt available to borrow.
    /// @dev checks the outstanding balance of the borrowable asset within the contract.
    /// @return available balance of borrowable asset.
    function getDebtCeiling() public view returns (uint256) {
        return mai.balanceOf(address(this));
    }

    /// @param vaultID is the token id of the vault being checked.
    /// @notice Returns true if a vault exists
    /// @dev the erc721 spec allows users to burn/destroy their nft
    /// @return boolean if the vault exists
    function exists(uint256 vaultID) external view returns (bool) {
        return _exists(vaultID);
    }

    /// @notice Returns the total value locked in the vault, based on the oracle price.
    /// @return uint256 total value locked in vault
    function getTotalValueLocked() external view returns (uint256) {
        return ( getEthPriceSource() * decimalDifferenceRaisedToTen * collateral.balanceOf(address(this)) ) ; //extra 1e8, to get fraction in ui
                // 1e8 * 1eDelta 
    }

    /// @notice Return the fee charged when repaying a vault.
    /// @return uint256 is the fee charged to a vault when repaying.
    function getClosingFee() external view returns (uint256) {
        return closingFee;
    }

    /// @notice Return the peg maintained by the vault.
    /// @return uint256 is the value with 8 decimals used to calculate borrowable debt.
    function getTokenPriceSource() public view returns (uint256) {
        return tokenPeg;
    }

    /// @notice Return the collateral value
    /// @return uint256 is the value retrieved from the oracle used
    /// to calculate the available borrowable amounts.
    function getEthPriceSource() public view returns (uint256) {
        return ethPriceSource.latestAnswer();
    }

    /// @param vaultID is the token id of the vault being checked.
    /// @notice Returns the debt owned by the vault and the interest accrued over time.
    /// @return uint256 fee earned in the time between updates
    /// @return uint256 debt owed by the vault for further calculation.
    function _vaultDebtAndFee(uint256 vaultID)
        internal
        view
        returns (uint256, uint256)
    {
        uint256 currentTime = block.timestamp;
        uint256 debt = accumulatedVaultDebt[vaultID];
        uint256 fee = 0;
        if (lastInterest[vaultID] != 0 && iR > 0) {
            uint256 timeDelta = currentTime - lastInterest[vaultID];

            uint256 feeAccrued = (((iR * debt) * timeDelta) / ONE_YEAR) / TEN_THOUSAND;
            fee = feeAccrued;
            debt = feeAccrued + debt;
        }
        return (fee, debt);
    }

    /// @param vaultID is the token id of the vault being checked.
    /// @notice Returns the debt owned by the vault without tracking the interest
    /// @return uint256 debt owed by the vault for further calculation.
    function vaultDebt(uint256 vaultID) public view returns (uint256) {
        (, uint256 debt) = _vaultDebtAndFee(vaultID);
        return debt;
    }

    /// @param vaultID is the token id of the vault being checked.
    /// @notice Adds the interest charged to the vault over the previous time called.
    /// @return uint256 latest vault debt
    function updateVaultDebt(uint256 vaultID) public returns (uint256) {
        (uint256 fee, uint256 debt) = _vaultDebtAndFee(vaultID);

        maiDebt = maiDebt + fee;

        totalBorrowed = totalBorrowed + fee;

        lastInterest[vaultID] = block.timestamp;

        // we can just update the current vault debt here instead
        accumulatedVaultDebt[vaultID] = debt;

        return debt;
    }

    /// @param _collateral is the amount of collateral tokens to be valued.
    /// @param _debt is the debt owed by the vault.
    /// @notice Returns collateral value and debt based on the oracle prices
    /// @return uint256 coolateral value * 100. used to calculate the CDR
    /// @return uint256 debt value. Uses token price source to derive.
    function calculateCollateralProperties(uint256 _collateral, uint256 _debt)
        private
        view
        returns (uint256, uint256)
    {
        require(getEthPriceSource() != 0);
        require(getTokenPriceSource() != 0);

        uint256 collateralValue = _collateral *
            getEthPriceSource() *
            decimalDifferenceRaisedToTen;

        require(collateralValue >= _collateral);

        uint256 debtValue = _debt * getTokenPriceSource();

        require(debtValue >= _debt);

        uint256 collateralValueTimes100 = collateralValue * 100;
        require(collateralValueTimes100 > collateralValue);

        return (collateralValueTimes100, debtValue);
    }

    
    /// @param _collateral is the amount of collateral tokens held by vault.
    /// @param debt is the debt owed by the vault.
    /// @notice Calculates if the CDR is valid before taking a further action with a user
    /// @return boolean describing if the new CDR is valid.
    function isValidCollateral(uint256 _collateral, uint256 debt)
        public
        view
        returns (bool)
    {
        (
            uint256 collateralValueTimes100,
            uint256 debtValue
        ) = calculateCollateralProperties(_collateral, debt);

        uint256 collateralPercentage = collateralValueTimes100 / debtValue;
        return collateralPercentage >= _minimumCollateralPercentage;
    }

    

    /// @param fee is the amount of basis points (BP) to charge
    /// @param amount is the total value to calculate the BPs from
    /// @param promoFee is the fee charged by the front end
    /// @notice Returns fee to charge based on the collateral amount
    /// @return uint256 fee to charge the collateral.
    /// @dev fee can be called on web app to compare charges.
    function calculateFee(
        uint256 fee,
        uint256 amount,
        uint256 promoFee
    ) public view returns (uint256) {
        uint256 _fee;
        if (promoFee>0) {
            _fee = ((amount * fee * getTokenPriceSource() * promoFee) /
                (getEthPriceSource() * TEN_THOUSAND * TEN_THOUSAND));
        } else {
            _fee = (amount * fee * getTokenPriceSource()) /
                (getEthPriceSource() * TEN_THOUSAND);
        }
        return _fee / decimalDifferenceRaisedToTen;
    }

    /// @notice Creates a new ERC721 Vault NFT
    /// @return uint256 the token id of the vault created.
    function createVault() public returns (uint256) {
        uint256 id = vaultCount;
        vaultCount = vaultCount + 1;
        require(vaultCount >= id);
        _mint(msg.sender, id);
        emit CreateVault(id, msg.sender);
        return id;
    }

    /// @notice Destroys an ERC721 Vault NFT
    /// @param vaultID the vault ID to destroy
    /// @dev vault must not have any debt owed to be able to be destroyed.
    function destroyVault(uint256 vaultID)
        external
        onlyVaultOwner(vaultID)
        nonReentrant
    {
        require(vaultDebt(vaultID) == 0, "Vault has outstanding debt");

        if (vaultCollateral[vaultID] != 0) {
            // withdraw leftover collateral
            collateral.safeTransfer(ownerOf(vaultID), vaultCollateral[vaultID]);
        }

        _burn(vaultID);

        delete vaultCollateral[vaultID];
        delete accumulatedVaultDebt[vaultID];
        delete lastInterest[vaultID];
        emit DestroyVault(vaultID);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @param amount is the amount of collateral to deposit from msg.sender
    /// @notice Adds collateral to a specific vault by token id
    /// @dev Any address can deposit into a vault
    function depositCollateral(uint256 vaultID, uint256 amount)
        external
        vaultExists(vaultID)
    {
        uint256 newCollateral = vaultCollateral[vaultID] + (amount);

        require(newCollateral >= vaultCollateral[vaultID]);

        vaultCollateral[vaultID] = newCollateral;

        collateral.safeTransferFrom(msg.sender, address(this), amount);

        emit DepositCollateral(vaultID, amount);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @param amount is the amount of collateral to withdraw
    /// @notice withdraws collateral to a specific vault by token id
    /// @dev If there is debt, then it can only withdraw up to the min CDR.
    function withdrawCollateral(uint256 vaultID, uint256 amount)
        external
        onlyVaultOwner(vaultID)
        nonReentrant
    {
        require(
            vaultCollateral[vaultID] >= amount,
            "Vault does not have enough collateral"
        );

        uint256 newCollateral = vaultCollateral[vaultID] - amount;
        uint256 debt = updateVaultDebt(vaultID);

        if (debt != 0) {
            require(
                isValidCollateral(newCollateral, debt),
                "Withdrawal would put vault below minimum collateral percentage"
            );
        }

        vaultCollateral[vaultID] = newCollateral;
        collateral.safeTransfer(msg.sender, amount);

        emit WithdrawCollateral(vaultID, amount);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @param amount is the amount of borrowable asset to borrow
    /// @notice borrows asset based on the collateral held and the price of the collateral.
    /// @dev Borrowing is limited by the CDR of the vault
    /// If there's opening fee, it will be charged here.
    function borrowToken(
        uint256 vaultID,
        uint256 amount,
        uint256 _front
    ) external 
    frontExists(_front) 
    onlyVaultOwner(vaultID) 
    nonReentrant
    {

        require(amount > 0, "Must borrow non-zero amount");
        require(
            amount <= getDebtCeiling(),
            "borrowToken: Cannot mint over available supply."
        );

        uint256 newDebt = updateVaultDebt(vaultID) + amount;

        require(newDebt<=maxDebt, "borrowToken: max loan cap reached.");

        require(newDebt > vaultDebt(vaultID));


        require(
            isValidCollateral(vaultCollateral[vaultID], newDebt),
            "Borrow would put vault below minimum collateral percentage"
        );

        require(
            ((vaultDebt(vaultID)) + amount) >= minDebt,
            "Vault debt can't be under minDebt"
        );

        accumulatedVaultDebt[vaultID] = newDebt;

        uint256 _openingFee = calculateFee(openingFee, newDebt, promoter[_front]);

        vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_openingFee);
        vaultCollateral[_front] = vaultCollateral[_front] + (_openingFee);
        
        // mai
        mai.safeTransfer(msg.sender, amount);
        totalBorrowed = totalBorrowed + (amount);

        emit BorrowToken(vaultID, amount);
    }

    function paybackTokenAll(
        uint256 vaultID,
        uint256 deadline,
        uint256 _front
    ) external frontExists(_front) vaultExists(vaultID) {
        require(
            deadline >= block.timestamp,
            "paybackTokenAll: deadline expired."
        );
        uint256 _amount = updateVaultDebt(vaultID);
        payBackToken(vaultID, _amount, _front);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @param amount is the amount of borrowable asset to repay
    /// @param _front is the front end that will get the opening
    /// @notice payback asset to close loan.
    /// @dev If there is debt, then it can only withdraw up to the min CDR.
    function payBackToken(
        uint256 vaultID,
        uint256 amount,
        uint256 _front
    ) public frontExists(_front) vaultExists(vaultID) {
        require(mai.balanceOf(msg.sender) >= amount, "Token balance too low");

        uint256 vaultDebtNow = updateVaultDebt(vaultID);

        require(
            vaultDebtNow >= amount,
            "Vault debt less than amount to pay back"
        );

        require(
            ((vaultDebtNow) - amount) >= minDebt || amount == (vaultDebtNow),
            "Vault debt can't be under minDebt"
        );

        uint256 _closingFee = calculateFee(
            closingFee,
            amount,
            promoter[_front]
        );

        accumulatedVaultDebt[vaultID] = vaultDebtNow - amount;

        vaultCollateral[vaultID] = vaultCollateral[vaultID] - _closingFee;
        vaultCollateral[_front] = vaultCollateral[_front] + _closingFee;

        totalBorrowed = totalBorrowed - amount;

        //mai
        mai.safeTransferFrom(msg.sender, address(this), amount);
        
        emit PayBackToken(vaultID, amount, _closingFee);
    }

    /// @notice withdraws liquidator earnings.
    /// @dev reverts if there's no collateral to withdraw.
    function getPaid() external nonReentrant {
        require(maticDebt[msg.sender] != 0, "Don't have anything for you.");
        uint256 amount = maticDebt[msg.sender];
        maticDebt[msg.sender] = 0;
        collateral.safeTransfer(msg.sender, amount);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Calculates cost to liquidate a vault
    /// @dev Can be used to calculate balance required to liquidate a vault. 
    function checkCost(uint256 vaultID) public view returns (uint256) {
        uint256 vaultDebtNow = vaultDebt(vaultID);

        if (
            vaultCollateral[vaultID] == 0 ||
            vaultDebtNow == 0 ||
            !checkLiquidation(vaultID)
        ) {
            return 0;
        }

        (,
            uint256 debtValue
        ) = calculateCollateralProperties(
                vaultCollateral[vaultID],
                vaultDebtNow
            );

        if (debtValue == 0) {
            return 0;
        }

        debtValue = debtValue / (10**priceSourceDecimals);

        uint256 halfDebt = debtValue / debtRatio; //debtRatio (2)

        if (halfDebt <= minDebt) {
            halfDebt = debtValue;
        }

        return (halfDebt);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Calculates collateral to extract when liquidating a vault
    /// @dev Can be used to calculate earnings from liquidating a vault. 
    function checkExtract(uint256 vaultID) public view returns (uint256) {
        if (vaultCollateral[vaultID] == 0 || !checkLiquidation(vaultID)) {
            return 0;
        }
        uint256 vaultDebtNow = vaultDebt(vaultID);

        (, uint256 debtValue) = calculateCollateralProperties(
            vaultCollateral[vaultID],
            vaultDebtNow
        );

        uint256 halfDebt = debtValue / debtRatio; //debtRatio (2)

        if (halfDebt == 0) {
            return 0;
        }
        if ((halfDebt) / (10**priceSourceDecimals) <= minDebt) {
            // full liquidation if under the min debt.
            return (debtValue * ( gainRatio)) / (THOUSAND) / (getEthPriceSource()) / decimalDifferenceRaisedToTen;
        } else {
            return (halfDebt * (gainRatio)) / THOUSAND / (getEthPriceSource()) / decimalDifferenceRaisedToTen;
        }
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Calculates the collateral percentage of a vault.
    function checkCollateralPercentage(uint256 vaultID)
        public
        view
        vaultExists(vaultID)
        returns (uint256)
    {
        uint256 vaultDebtNow = vaultDebt(vaultID);

        if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) {
            return 0;
        }
        (
            uint256 collateralValueTimes100,
            uint256 debtValue
        ) = calculateCollateralProperties(
                vaultCollateral[vaultID],
                vaultDebtNow
            );

        return collateralValueTimes100 / (debtValue);
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Calculates if a vault is liquidatable.
    /// @return bool if vault is liquidatable or not.
    function checkLiquidation(uint256 vaultID)
        public
        view
        vaultExists(vaultID)
        returns (bool)
    {
        uint256 vaultDebtNow = vaultDebt(vaultID);

        if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) {
            return false;
        }

        (
            uint256 collateralValueTimes100,
            uint256 debtValue
        ) = calculateCollateralProperties(
                vaultCollateral[vaultID],
                vaultDebtNow
            );

        uint256 collateralPercentage = collateralValueTimes100 / (debtValue);
        if (collateralPercentage < _minimumCollateralPercentage) {
            return true;
        } else {
            return false;
        }
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Pays back the part of the debt owed by the vault and removes a 
    /// comparable amount of collateral plus bonus
    /// @dev if vault CDR is under the bonus ratio,
    /// then it will only be able to be bought through buy risky.
    /// Amount to pay back is based on debtRatio variable.
    function liquidateVault(uint256 vaultID, uint256 _front)
        external
        frontExists(_front)
        vaultExists(vaultID)
    {
        require(
            stabilityPool == address(0) || msg.sender == stabilityPool,
            "liquidation is disabled for public"
        );

        uint256 vaultDebtNow = updateVaultDebt(vaultID);
        (
            uint256 collateralValueTimes100,
            uint256 debtValue
        ) = calculateCollateralProperties(
                vaultCollateral[vaultID],
                vaultDebtNow
            );
        require(vaultDebtNow != 0, "Vault debt is 0");

        uint256 collateralPercentage = collateralValueTimes100 / (debtValue);

        require(
            collateralPercentage < _minimumCollateralPercentage,
            "Vault is not below minimum collateral percentage"
        );

        require(collateralPercentage * 10 > gainRatio , "Vault is not above gain ratio");

        debtValue = debtValue / (10**priceSourceDecimals);

        uint256 halfDebt = debtValue / (debtRatio); //debtRatio (2)

        if (halfDebt <= minDebt) {
            halfDebt = debtValue;
        }

        require(
            mai.balanceOf(msg.sender) >= halfDebt,
            "Token balance too low to pay off outstanding debt"
        );

        totalBorrowed = totalBorrowed - (halfDebt);

        uint256 maticExtract = checkExtract(vaultID);

        accumulatedVaultDebt[vaultID] = vaultDebtNow - (halfDebt); // we paid back half of its debt.

        uint256 _closingFee = calculateFee(closingFee, halfDebt, promoter[_front]);
        vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_closingFee);
        vaultCollateral[_front] = vaultCollateral[_front] + (_closingFee);

        
        // deduct the amount from the vault's collateral
        vaultCollateral[vaultID] = vaultCollateral[vaultID] - (maticExtract);

        // let liquidator take the collateral
        maticDebt[msg.sender] = maticDebt[msg.sender] + (maticExtract);

        //mai
        mai.safeTransferFrom(msg.sender, address(this), halfDebt);

        emit LiquidateVault(
            vaultID,
            ownerOf(vaultID),
            msg.sender,
            halfDebt,
            maticExtract,
            _closingFee
        );
    }

    /// @param vaultID is the token id of the vault being interacted with.
    /// @notice Pays back the debt owed to bring it back to min CDR. 
    /// And transfers ownership of it to the liquidator with a new vault
    /// @return uint256 new vault created with the debt and collateral.
    /// @dev this function can only be called if vault CDR is under the bonus ratio.
    /// address who calls it will now own the debt and the collateral.
    function buyRiskDebtVault(uint256 vaultID) external vaultExists(vaultID) returns(uint256) {
      
        uint256 vaultDebtNow = updateVaultDebt(vaultID);

        require(vaultDebtNow != 0, "Vault debt is 0");

        (
            uint256 collateralValueTimes100,
            uint256 debtValue
        ) = calculateCollateralProperties(
                vaultCollateral[vaultID],
                vaultDebtNow
            );

        uint256 collateralPercentage = collateralValueTimes100 / (debtValue);
        require(
            (collateralPercentage*10) <= gainRatio,
            "Vault is not below risky collateral percentage" 
        );

        uint256 maiDebtTobePaid = (debtValue / (10**priceSourceDecimals)) - 
                                    (collateralValueTimes100 / 
                                    ( _minimumCollateralPercentage * (10**priceSourceDecimals)));

        //have enough MAI to bring vault to X CDR (presumably min)
        require(mai.balanceOf(msg.sender) >= maiDebtTobePaid, "Not enough mai to buy the risky vault");
        //mai
        mai.safeTransferFrom(msg.sender, address(this), maiDebtTobePaid);
        totalBorrowed = totalBorrowed - (maiDebtTobePaid);
        // newVault for msg.sender
        uint256 newVault = createVault();
        // updating vault collateral and debt details for the transfer of risky vault
        vaultCollateral[newVault] = vaultCollateral[vaultID];
        accumulatedVaultDebt[newVault] = vaultDebtNow - maiDebtTobePaid;
        lastInterest[newVault] = block.timestamp;
        // resetting the vaultID vault info
        delete vaultCollateral[vaultID];
        delete accumulatedVaultDebt[vaultID];
        // lastInterest of vaultID would be block.timestamp, not reseting its timestamp
        emit BoughtRiskyDebtVault(vaultID, newVault, msg.sender, maiDebtTobePaid);
        return newVault;

    }
}


// File contracts/fixedInterestVaults/fixedQiVault.sol

pragma solidity 0.8.11;


/// @title Fixed Interest Vault
/// @notice Single collateral lending manager with fixed rate interest.
contract stableQiVault is fixedVault, Ownable {

    /// @dev Used to restrain the fee. Can only be up to 5% of the amount.
    uint256 constant FEE_MAX = 500;
    
    string private oracleType;
    
    constructor(
        address ethPriceSourceAddress,
        uint256 minimumCollateralPercentage,
        string memory name,
        string memory symbol,
        address _mai,
        address _collateral,
        string memory baseURI
    )
        fixedVault(
            ethPriceSourceAddress,
            minimumCollateralPercentage,
            name,
            symbol,
            _mai,
            _collateral,
            baseURI
        )
    {
        createVault();
        addFrontEnd(0);
    }

    event UpdatedClosingFee(uint256 newFee);
    event UpdatedOpeningFee(uint256 newFee);
    event WithdrawInterest(uint256 earned);
    event UpdatedMinDebt(uint256 newMinDebt);
    event UpdatedMaxDebt(uint256 newMaxDebt);
    event UpdatedDebtRatio(uint256 _debtRatio);
    event UpdatedGainRatio(uint256 _gainRatio);
    event UpdatedEthPriceSource(address _ethPriceSourceAddress);
    
    event AddedFrontEnd(uint256 promoter);
    event RemovedFrontEnd(uint256 promoter);
    event UpdatedFrontEnd(uint256 promoter, uint256 newFee);

    event UpdatedFees(uint256 _adminFee, uint256 _refFee);

    event UpdatedMinCollateralRatio(uint256 newMinCollateralRatio);
    event UpdatedStabilityPool(address pool);
    event UpdatedInterestRate(uint256 interestRate);
    event BurnedToken(uint256 amount);
    event UpdatedTokenURI(string uri);

    event UpdatedAdmin(address newAdmin);
    event UpdatedRef(address newRef);
    event UpdatedOracleName(string oracle);

    modifier onlyOperators() {
        require(ref == msg.sender || adm == msg.sender || owner() == msg.sender, "Needs to be called by operators");
        _;
    }

    modifier onlyAdmin() {
        require(adm == msg.sender, "Needs to be called by admin");
        _;
    }

    /// @param _oracle name of the oracle used by the contract
    /// @notice sets the oracle name used by the contract. for visual purposes.
    function updateOracleName(string memory _oracle) external onlyOwner {
        oracleType = _oracle;
        emit UpdatedOracleName(_oracle);
    }

    /// @param _gainRatio sets the bonus earned from a liquidator
    /// @notice implements a setter for the bonus earned by a liquidator
    /// @dev fails if the bonus is less than 1
    function setGainRatio(uint256 _gainRatio) external onlyOwner {
        require(_gainRatio >= 1000, "gainRatio cannot be less than or equal to 1000");
        gainRatio = _gainRatio;
        emit UpdatedGainRatio(gainRatio);
    }

    /// @param _debtRatio sets the ratio of debt paid back by a liquidator
    /// @notice sets the ratio of the debt to be paid back
    /// @dev it divides the debt. 1/debtRatio.
    function setDebtRatio(uint256 _debtRatio) external onlyOwner {
        require(debtRatio != 0, "Debt Ratio cannot be 0");
        debtRatio = _debtRatio;
        emit UpdatedDebtRatio(debtRatio);
    }

        /// @param ethPriceSourceAddress is the address that provides the price of the collateral
    /// @notice sets the address used as oracle
    /// @dev Oracle price feed is used in here. Interface's available in the at /interfaces/IPriceSourceAll.sol
    function changeEthPriceSource(address ethPriceSourceAddress)
        external
        onlyOwner
    {
        require(ethPriceSourceAddress != address(0), "Ethpricesource cannot be zero address" );
        ethPriceSource = IPriceSource(ethPriceSourceAddress);
        emit UpdatedEthPriceSource(ethPriceSourceAddress);
    }

    /// @param _pool is the address that can execute liquidations
    /// @notice sets the address used as stability pool for liquidations
    /// @dev if not set to address(0) then _pool is the only address able to liquidate
    function setStabilityPool(address _pool) external onlyOwner {
        require(_pool != address(0), "StabilityPool cannot be zero address" );
        stabilityPool = _pool;
        emit UpdatedStabilityPool(stabilityPool);
    }

    /// @param _admin is the ratio earned by the address that maintains the market
    /// @param _ref is the ratio earned by the address that provides the borrowable asset
    /// @notice sets the interest rate split between the admin and ref
    /// @dev if not set to address(0) then _pool is the only address able to liquidate
    function setFees(uint256 _admin, uint256 _ref) external onlyOwner {
        require((_admin+_ref)==TEN_THOUSAND, "setFees: must equal 10000.");
        adminFee=_admin;
        refFee=_ref;
        emit UpdatedFees(adminFee, refFee);
    }

    /// @param minimumCollateralPercentage is the CDR that limits the amount borrowed
    /// @notice sets the CDR
    /// @dev only callable by owner of the contract
    function setMinCollateralRatio(uint256 minimumCollateralPercentage)
        external
        onlyOwner
    {
        _minimumCollateralPercentage = minimumCollateralPercentage;
        emit UpdatedMinCollateralRatio(_minimumCollateralPercentage);
    }

    /// @param _minDebt is minimum debt able to be borrowed by a vault.
    /// @notice sets the minimum debt.
    /// @dev dust protection
    function setMinDebt(uint256 _minDebt)
        external
        onlyOwner
    {
        require(_minDebt >=0, "setMinDebt: must be over 0.");
        minDebt = _minDebt;
        emit UpdatedMinDebt(minDebt);
    }

    /// @param _maxDebt is maximum debt able to be borrowed by a vault.
    /// @notice sets the maximum debt.
    /// @dev whale and liquidity protection.
    function setMaxDebt(uint256 _maxDebt)
        external
        onlyOwner
    {
        require(_maxDebt >=0, "setMaxDebt: must be over 0.");
        maxDebt = _maxDebt;
        emit UpdatedMaxDebt(maxDebt);
    }

    /// @param _ref is the address that provides the borrowable asset
    /// @notice sets the address that earns interest for providing a borrowable asset
    /// @dev cannot be address(0)
    function setRef(address _ref) external onlyOwner {
        require(_ref != address(0), "Reference Address cannot be zero");
        ref = _ref;
        emit UpdatedRef(ref);
    }

    /// @param _adm is the ratio earned by the address that maintains the market
    /// @notice sets the address that earns interest for maintaining the market
    /// @dev cannot be address(0)
    function setAdmin(address _adm) external onlyOwner {
        require(_adm != address(0), "Admin Address cannot be zero");
        adm = _adm;
        emit UpdatedAdmin(adm);
    }

    /// @param _openingFee is the fee charged to a vault when borrowing.
    /// @notice sets opening fee.
    /// @dev can only be up to 5% (FEE_MAX) of the amount.
    function setOpeningFee(uint256 _openingFee) external onlyOwner {
        require(_openingFee >= 0 && _openingFee <= FEE_MAX, "setOpeningFee: cannot be more than 5%");
        openingFee = _openingFee;
        // emit event
        emit UpdatedOpeningFee(openingFee);
    }

    /// @param _closingFee is the fee charged to a vault when repaying.
    /// @notice sets closing fee.
    /// @dev can only be up to 5% (FEE_MAX) of the amount.
    function setClosingFee(uint256 _closingFee) external onlyOwner {
        require(_closingFee >= 0 && _closingFee <= FEE_MAX, "setClosingFee: cannot be more than 5%");
        closingFee = _closingFee;
        // emit event
        emit UpdatedClosingFee(closingFee);
    }

    /// @param _promoter is a front end for the contract
    /// @notice adds a front end to earn opening/closing fees from borrowing/repaying.
    /// @dev can only be up to 5% (FEE_MAX) of the amount.
    function addFrontEnd(uint256 _promoter) public onlyOwner {
        require(_exists(_promoter), "addFrontEnd: Vault does not exist");    
        require(promoter[_promoter] == 0, "addFrontEnd: already added");
        promoter[_promoter] = TEN_THOUSAND;
        emit AddedFrontEnd(_promoter);
    }

    /// @param _promoter is a front end for the contract
    /// @param cashback is the amount of fee not taken from a user.
    /// @notice updates the cashback variable for a given front end
    /// @dev can only be updated by the front end vault's owner
    function updateFrontEnd(uint256 _promoter, uint256 cashback) external frontExists(_promoter) onlyVaultOwner(_promoter) {
        require(cashback > 0 && cashback <= TEN_THOUSAND, "updateFrontEnd: cannot be 0");
        promoter[_promoter] = cashback;
        emit UpdatedFrontEnd(_promoter, cashback);
    }

    /// @param _promoter is a front end for the contract
    /// @notice removes the ability for a front end to earn fees
    function removeFrontEnd(uint256 _promoter) external frontExists(_promoter) onlyOwner {
        require(_exists(_promoter), "removeFrontEnd: Vault does not exist");
        require(promoter[_promoter] > 0, "removeFrontEnd: not a front end");
        promoter[_promoter] = 0;
        emit RemovedFrontEnd(_promoter);
    }

    /// @notice withdraws earned interest by vault.
    function withdrawInterest() external onlyOperators nonReentrant {

        uint256 adm_fee = maiDebt*adminFee / TEN_THOUSAND;

        // Transfer
        mai.transfer(ref, (maiDebt-adm_fee) ); // cheaper and equivalent.
        mai.transfer(adm, adm_fee);
        emit WithdrawInterest(maiDebt);
        maiDebt = 0;
    }

    /// @param _iR is the fixed interest charged by a vault
    /// @notice sets the interest charged by a vault.
    function setInterestRate(uint256 _iR) external onlyOwner {
        require(_iR != 0, "InterestRate cannot be zero address" );
        iR = _iR;
        emit UpdatedInterestRate(iR);
    }

    /// @param amountToken is the amount of borrowable asset that is removed from the debt ceiling.
    /// @notice removes debt ceiling from the vault.
    /// @dev returns the asset to the owner so it can be redeployed at a later time.
    function burn(uint256 amountToken) external onlyAdmin {
        // Burn
        require(amountToken < mai.balanceOf(address(this)), "burn: Balance not enough");
        mai.transfer(ref, amountToken);
        emit BurnedToken(amountToken);
    }

    /// @param _uri is the url for the nft metadata
    /// @notice updates the metadata
    /// @dev it currently uses an ipfs json
    function setTokenURI(string calldata _uri) external onlyOwner {
        uri = _uri;
        emit UpdatedTokenURI(uri);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"},{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_mai","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"string","name":"baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"AddedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BorrowToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"riskyVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVault","type":"uint256"},{"indexed":false,"internalType":"address","name":"riskyVaultBuyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountPaidtoBuy","type":"uint256"}],"name":"BoughtRiskyDebtVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"CreateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"DestroyVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRepaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralLiquidated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"LiquidateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"PayBackToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"RemovedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"UpdatedAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedClosingFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"UpdatedDebtRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ethPriceSourceAddress","type":"address"}],"name":"UpdatedEthPriceSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_adminFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_refFee","type":"uint256"}],"name":"UpdatedFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"UpdatedGainRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestRate","type":"uint256"}],"name":"UpdatedInterestRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxDebt","type":"uint256"}],"name":"UpdatedMaxDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinCollateralRatio","type":"uint256"}],"name":"UpdatedMinCollateralRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinDebt","type":"uint256"}],"name":"UpdatedMinDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedOpeningFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"oracle","type":"string"}],"name":"UpdatedOracleName","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRef","type":"address"}],"name":"UpdatedRef","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"UpdatedStabilityPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"UpdatedTokenURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"earned","type":"uint256"}],"name":"WithdrawInterest","type":"event"},{"inputs":[],"name":"_minimumCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accumulatedVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"addFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"borrowToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"buyRiskDebtVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"promoFee","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"}],"name":"changeEthPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkExtract","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkLiquidation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalDifferenceRaisedToTen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"destroyVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethPriceSource","outputs":[{"internalType":"contract IPriceSource","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gainRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClosingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebtCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTokenPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalValueLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateral","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"name":"isValidCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"liquidateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mai","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maiDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maticDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"payBackToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"paybackTokenAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceSourceDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"promoter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ref","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"removeFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adm","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_closingFee","type":"uint256"}],"name":"setClosingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"setDebtRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_admin","type":"uint256"},{"internalType":"uint256","name":"_ref","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"setGainRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_iR","type":"uint256"}],"name":"setInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDebt","type":"uint256"}],"name":"setMaxDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"}],"name":"setMinCollateralRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minDebt","type":"uint256"}],"name":"setMinDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_openingFee","type":"uint256"}],"name":"setOpeningFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ref","type":"address"}],"name":"setRef","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setStabilityPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stabilityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPeg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"},{"internalType":"uint256","name":"cashback","type":"uint256"}],"name":"updateFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_oracle","type":"string"}],"name":"updateOracleName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"updateVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"vaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawInterest","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526025805460ff60a01b1916600360a11b1790553480156200002457600080fd5b506040516200653038038062006530833981016040819052620000479162000af7565b868686868686868484828282600160008190555081600190805190602001906200007392919062000967565b5080516200008990600290602084019062000967565b50508151620000a19150600b90602084019062000967565b505050506001600160a01b038716620000b957600080fd5b85620000c457600080fd5b6032600f556000601055600c80546001600160a01b03808a166001600160a01b03199283161790925560238054821690556969e10de76676d08000006012556002601a5561044c601b55600d889055601c80548584169083168117909155601d8054938716939092169290921790556008601f556040805163313ce56760e01b8152905163313ce567916004818101926020929091908290030181865afa15801562000174573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019a919062000bcb565b601d60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000214919062000bcb565b62000220919062000c0d565b6200022d90600a62000d32565b601e55505060248054336001600160a01b03199182168117909255602580549091169091179055506200027093506200026a925062000294915050565b62000298565b6200027a620002ea565b5062000287600062000358565b5050505050505062000de1565b3390565b602680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600e54600090620002fd81600162000d43565b600e8190558111156200030f57600080fd5b6200031b3382620004d7565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b6026546001600160a01b03163314620003b85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6000818152600360205260409020546001600160a01b0316620004285760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401620003af565b60008181526017602052604090205415620004865760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401620003af565b600081815260176020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90620004cc9083815260200190565b60405180910390a150565b6001600160a01b0382166200052f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401620003af565b6000818152600360205260409020546001600160a01b031615620005965760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003af565b620005a4600083836200062d565b6001600160a01b0382166000908152600460205260408120805460019290620005cf90849062000d43565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b620006458383836200064a60201b62003f1b1760201c565b505050565b620006628383836200064560201b620010d51760201c565b6001600160a01b038316620006c057620006ba81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b620006e6565b816001600160a01b0316836001600160a01b031614620006e657620006e6838262000726565b6001600160a01b03821662000700576200064581620007d3565b826001600160a01b0316826001600160a01b03161462000645576200064582826200088d565b600060016200074084620008de60201b620022251760201c565b6200074c919062000d5e565b600083815260086020526040902054909150808214620007a0576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090620007e79060019062000d5e565b6000838152600a60205260408120546009805493945090928490811062000812576200081262000d78565b90600052602060002001549050806009838154811062000836576200083662000d78565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548062000871576200087162000d8e565b6001900381819060005260206000200160009055905550505050565b6000620008a583620008de60201b620022251760201c565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160a01b0382166200094b5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401620003af565b506001600160a01b031660009081526004602052604090205490565b828054620009759062000da4565b90600052602060002090601f016020900481019282620009995760008555620009e4565b82601f10620009b457805160ff1916838001178555620009e4565b82800160010185558215620009e4579182015b82811115620009e4578251825591602001919060010190620009c7565b50620009f2929150620009f6565b5090565b5b80821115620009f25760008155600101620009f7565b80516001600160a01b038116811462000a2557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000a5257600080fd5b81516001600160401b038082111562000a6f5762000a6f62000a2a565b604051601f8301601f19908116603f0116810190828211818310171562000a9a5762000a9a62000a2a565b8160405283815260209250868385880101111562000ab757600080fd5b600091505b8382101562000adb578582018301518183018401529082019062000abc565b8382111562000aed5760008385830101525b9695505050505050565b600080600080600080600060e0888a03121562000b1357600080fd5b62000b1e8862000a0d565b602089015160408a015191985096506001600160401b038082111562000b4357600080fd5b62000b518b838c0162000a40565b965060608a015191508082111562000b6857600080fd5b62000b768b838c0162000a40565b955062000b8660808b0162000a0d565b945062000b9660a08b0162000a0d565b935060c08a015191508082111562000bad57600080fd5b5062000bbc8a828b0162000a40565b91505092959891949750929550565b60006020828403121562000bde57600080fd5b815160ff8116811462000bf057600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168082101562000c2a5762000c2a62000bf7565b90039392505050565b600181815b8085111562000c7457816000190482111562000c585762000c5862000bf7565b8085161562000c6657918102915b93841c939080029062000c38565b509250929050565b60008262000c8d5750600162000d2c565b8162000c9c5750600062000d2c565b816001811462000cb5576002811462000cc05762000ce0565b600191505062000d2c565b60ff84111562000cd45762000cd462000bf7565b50506001821b62000d2c565b5060208310610133831016604e8410600b841016171562000d05575081810a62000d2c565b62000d11838362000c33565b806000190482111562000d285762000d2862000bf7565b0290505b92915050565b600062000bf060ff84168362000c7c565b6000821982111562000d595762000d5962000bf7565b500190565b60008282101562000d735762000d7362000bf7565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600181811c9082168062000db957607f821691505b6020821081141562000ddb57634e487b7160e01b600052602260045260246000fd5b50919050565b61573f8062000df16000396000f3fe608060405234801561001057600080fd5b50600436106105035760003560e01c80638637599411610299578063cc02ce2211610167578063df987846116100d9578063ec2e0ab311610092578063ec2e0ab314610b22578063ece1373214610b2b578063f17336d714610b3e578063f1c91fa614610b47578063f2fde38b14610b50578063ffc73da714610b6357600080fd5b8063df98784614610a9c578063e0df5b6f14610aaf578063e5f4dc9214610ac2578063e985e9c514610acb578063eac989f814610b07578063eb6a887d14610b0f57600080fd5b8063cf5f0f3c1161012b578063cf5f0f3c14610a1a578063d0064c0014610a2d578063d310f49b14610a36578063d4a9b2c514610a49578063d73464cc14610a69578063d8dfeb4514610a8957600080fd5b8063cc02ce22146109e1578063cd44db1b146109f4578063cdfedd63146109fe578063cea55f5714610a09578063cf41d6f814610a1257600080fd5b8063a0be06f91161020b578063b165ff0b116101c4578063b165ff0b14610977578063b26025aa14610997578063b86f6aef1461099f578063b88d4fde146109b2578063c71abb32146109c5578063c87b56dd146109ce57600080fd5b8063a0be06f91461092e578063a22cb46514610937578063a57ff5031461094a578063a5e9883714610953578063a7c6a1001461095b578063a9c904b51461096457600080fd5b8063952cc86a1161025d578063952cc86a146108c557806395d89b41146108d857806397a41b8e146108e057806397ff37b9146108f357806398c3f2db1461091357806398d721e01461091b57600080fd5b806386375994146108735780638da5cb5b146108865780639035e4cb1461089757806393ee476a146108aa57806394cd4ba7146108bd57600080fd5b806342966c68116103d65780635ff09ac211610348578063704b6c0211610301578063704b6c021461081657806370a0823114610829578063715018a61461083c578063728bbbb514610844578063767a7b051461084d57806385e290a31461086057600080fd5b80635ff09ac2146107a45780636234dc21146107b75780636352211e146107ca5780636526941b146107dd578063687e8c17146107f05780636bc855cc1461080357600080fd5b80635357b9891161039a5780635357b9891461072a57806354fd4d501461073d57806356572ac014610763578063570b2b84146107765780635d12928b146107895780635f84f3021461079157600080fd5b806342966c68146106d557806342f371c6146106e85780634c19386c146106fb5780634f558e79146107045780634f6ccce71461071757600080fd5b80631c883e7b1161047a578063311f392a11610433578063311f392a1461066d5780633128ef271461067657806338536275146106895780633db991771461069c57806340803854146106af57806342842e0e146106c257600080fd5b80631c883e7b1461060257806321a78f681461060b57806323b872dd1461061e578063241a545a146106315780632df875731461063a5780632f745c591461065a57600080fd5b806307960532116104cc578063079605321461058d578063081812fc146105a0578063095ea7b3146105b35780630b78f9c0146105c657806311b4a832146105d957806318160ddd146105fa57600080fd5b806263750c1461050857806301ffc9a714610512578063048c661d1461053a57806304d7aef21461056557806306fdde0314610578575b600080fd5b610510610b76565b005b610525610520366004614e08565b610db6565b60405190151581526020015b60405180910390f35b60235461054d906001600160a01b031681565b6040516001600160a01b039091168152602001610531565b60245461054d906001600160a01b031681565b610580610dc7565b6040516105319190614e7d565b61051061059b366004614eac565b610e59565b61054d6105ae366004614ec7565b610f3c565b6105106105c1366004614ee0565b610fc4565b6105106105d4366004614f0a565b6110da565b6105ec6105e7366004614ec7565b6111a6565b604051908152602001610531565b6009546105ec565b6105ec600f5481565b60255461054d906001600160a01b031681565b61051061062c366004614f2c565b611258565b6105ec60135481565b6105ec610648366004614ec7565b60156020526000908152604090205481565b6105ec610668366004614ee0565b611289565b6105ec601b5481565b610510610684366004614f68565b61131f565b610510610697366004614ec7565b611602565b6105106106aa366004614ec7565b611661565b6105106106bd366004614ec7565b611720565b6105106106d0366004614f2c565b61184a565b6105106106e3366004614ec7565b611865565b600c5461054d906001600160a01b031681565b6105ec60205481565b610525610712366004614ec7565b611a23565b6105ec610725366004614ec7565b611a2e565b6105ec610738366004614f68565b611ac1565b60255461075190600160a01b900460ff1681565b60405160ff9091168152602001610531565b6105ec610771366004614ec7565b611b72565b601d5461054d906001600160a01b031681565b6105ec611c6c565b61051061079f366004614ec7565b611cd5565b6105106107b2366004614ec7565b611d8d565b6105106107c5366004614ec7565b611f25565b61054d6107d8366004614ec7565b611f84565b6105106107eb366004614ec7565b611ffb565b6105256107fe366004614f0a565b61205a565b610510610811366004614eac565b612089565b610510610824366004614eac565b612157565b6105ec610837366004614eac565b612225565b6105106122ac565b6105ec60105481565b61051061085b366004614f0a565b6122e2565b61051061086e366004614ec7565b6124e4565b610510610881366004614ec7565b612665565b6026546001600160a01b031661054d565b6105ec6108a5366004614ec7565b612724565b6105ec6108b8366004614ec7565b612a2d565b6105ec612a86565b6105106108d3366004614f0a565b612af8565b610580612fdc565b6105106108ee366004614f68565b612feb565b6105ec610901366004614ec7565b60166020526000908152604090205481565b6105ec6133ca565b610510610929366004614eac565b613414565b6105ec60185481565b610510610945366004614fa2565b6134ee565b6105ec601e5481565b600f546105ec565b6105ec600e5481565b610510610972366004615065565b6134fd565b6105ec610985366004614eac565b60216020526000908152604090205481565b6105ec61356a565b6105256109ad366004614ec7565b6135f6565b6105106109c03660046150ae565b6136a6565b6105ec601f5481565b6105806109dc366004614ec7565b6136de565b6105106109ef366004614f0a565b613784565b6305f5e1006105ec565b6105ec6305f5e10081565b6105ec601a5481565b6105106138f9565b610510610a28366004614f68565b6139b1565b6105ec60125481565b6105ec610a44366004614ec7565b613ac1565b6105ec610a57366004614ec7565b60146020526000908152604090205481565b6105ec610a77366004614ec7565b60176020526000908152604090205481565b601c5461054d906001600160a01b031681565b6105ec610aaa366004614ec7565b613acd565b610510610abd36600461512a565b613b5f565b6105ec600d5481565b610525610ad936600461519c565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b610580613bc6565b610510610b1d366004614ec7565b613c54565b6105ec60195481565b610510610b39366004614f0a565b613cfb565b6105ec60115481565b6105ec60225481565b610510610b5e366004614eac565b613db8565b610510610b71366004614ec7565b613e53565b6025546001600160a01b0316331480610b9957506024546001600160a01b031633145b80610bbd575033610bb26026546001600160a01b031690565b6001600160a01b0316145b610c0e5760405162461bcd60e51b815260206004820152601f60248201527f4e6565647320746f2062652063616c6c6564206279206f70657261746f72730060448201526064015b60405180910390fd5b60026000541415610c315760405162461bcd60e51b8152600401610c05906151cf565b6002600090815560185460225461271091610c4b9161521c565b610c55919061523b565b601d546025546022549293506001600160a01b039182169263a9059cbb9290911690610c8290859061525d565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610ccd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf19190615274565b50601d546024805460405163a9059cbb60e01b81526001600160a01b0391821660048201529182018490529091169063a9059cbb906044016020604051808303816000875af1158015610d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6c9190615274565b507fc73fb14682b9d51008c1faff296cc9b351c0597de5e25b4ffa158f47f8254e4c602254604051610da091815260200190565b60405180910390a1506000602281905560019055565b6000610dc182613fd3565b92915050565b606060018054610dd690615291565b80601f0160208091040260200160405190810160405280929190818152602001828054610e0290615291565b8015610e4f5780601f10610e2457610100808354040283529160200191610e4f565b820191906000526020600020905b815481529060010190602001808311610e3257829003601f168201915b5050505050905090565b6026546001600160a01b03163314610e835760405162461bcd60e51b8152600401610c05906152c6565b6001600160a01b038116610ee75760405162461bcd60e51b815260206004820152602560248201527f4574687072696365736f757263652063616e6e6f74206265207a65726f206164604482015264647265737360d81b6064820152608401610c05565b600c80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc525e5fed1508c998d3f14bf52f933df1dd16dbf48e2944c426be721e268b755906020015b60405180910390a150565b6000610f4782613ff8565b610fa85760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610c05565b506000908152600560205260409020546001600160a01b031690565b6000610fcf82611f84565b9050806001600160a01b0316836001600160a01b0316141561103d5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610c05565b336001600160a01b038216148061105957506110598133610ad9565b6110cb5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610c05565b6110d58383614015565b505050565b6026546001600160a01b031633146111045760405162461bcd60e51b8152600401610c05906152c6565b61271061111182846152fb565b1461115e5760405162461bcd60e51b815260206004820152601a60248201527f736574466565733a206d75737420657175616c2031303030302e0000000000006044820152606401610c05565b6018829055601981905560408051838152602081018390527f4d32f38862d5eb71edfefb7955873bd55920dc98159b6f53f8be62fbf0bebb4b91015b60405180910390a15050565b6000806111b283613ac1565b60008481526014602052604090205490915015806111ce575080155b806111df57506111dd836135f6565b155b156111ed5750600092915050565b6000838152601460205260408120546112069083614083565b91505080611218575060009392505050565b601f5461122690600a6153f7565b611230908261523b565b90506000601a5482611242919061523b565b905060115481116112505750805b949350505050565b611262338261410c565b61127e5760405162461bcd60e51b8152600401610c0590615403565b6110d58383836141f5565b600061129483612225565b82106112f65760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610c05565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b8061132981613ff8565b6113455760405162461bcd60e51b8152600401610c0590615454565b60008181526017602052604090205461271010801590611372575060008181526017602052604090205415155b61138e5760405162461bcd60e51b8152600401610c059061548b565b8361139881613ff8565b6113b45760405162461bcd60e51b8152600401610c05906154b8565b601d546040516370a0823160e01b815233600482015285916001600160a01b0316906370a0823190602401602060405180830381865afa1580156113fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142091906154e6565b10156114665760405162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b6044820152606401610c05565b600061147186612a2d565b9050848110156114d35760405162461bcd60e51b815260206004820152602760248201527f5661756c742064656274206c657373207468616e20616d6f756e7420746f20706044820152666179206261636b60c81b6064820152608401610c05565b6011546114e0868361525d565b1015806114ec57508085145b6115085760405162461bcd60e51b8152600401610c05906154ff565b600f546000858152601760205260408120549091611527918890611ac1565b9050611533868361525d565b60008881526015602090815260408083209390935560149052205461155990829061525d565b60008881526014602052604080822092909255868152205461157c9082906152fb565b6000868152601460209081526040909120919091555461159d90879061525d565b602055601d546115b8906001600160a01b031633308961439c565b60408051888152602081018890529081018290527f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9060600160405180910390a150505050505050565b6026546001600160a01b0316331461162c5760405162461bcd60e51b8152600401610c05906152c6565b600d8190556040518181527fc0880963f3abc486dbb8b8f04ba4ce47c5b5cd3c59b6b7655f6011da0bf3365090602001610f31565b6026546001600160a01b0316331461168b5760405162461bcd60e51b8152600401610c05906152c6565b6101f48111156116eb5760405162461bcd60e51b815260206004820152602560248201527f736574436c6f73696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c05565b600f8190556040518181527fc1b83121984ef8e824a0babc08fc162077c0716a4dc307121f306e6dfb13806c90602001610f31565b6026546001600160a01b0316331461174a5760405162461bcd60e51b8152600401610c05906152c6565b61175381613ff8565b6117a95760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401610c05565b600081815260176020526040902054156118055760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401610c05565b600081815260176020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90610f319083815260200190565b6110d5838383604051806020016040528060008152506136a6565b6024546001600160a01b031633146118bf5760405162461bcd60e51b815260206004820152601b60248201527f4e6565647320746f2062652063616c6c65642062792061646d696e00000000006044820152606401610c05565b601d546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611907573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192b91906154e6565b81106119795760405162461bcd60e51b815260206004820152601860248201527f6275726e3a2042616c616e6365206e6f7420656e6f75676800000000000000006044820152606401610c05565b601d5460255460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af11580156119ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f29190615274565b506040518181527fb1f67ade07cda330ac167f4fcc4c01b94fdfc04d401cf85e487f0a5b8b98e75f90602001610f31565b6000610dc182613ff8565b6000611a3960095490565b8210611a9c5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610c05565b60098281548110611aaf57611aaf615540565b90600052602060002001549050919050565b6000808215611b1f5761271080611ad66133ca565b611ae0919061521c565b611aea919061521c565b836305f5e100611afa888861521c565b611b04919061521c565b611b0e919061521c565b611b18919061523b565b9050611b5a565b612710611b2a6133ca565b611b34919061521c565b6305f5e100611b43878761521c565b611b4d919061521c565b611b57919061523b565b90505b601e54611b67908261523b565b9150505b9392505050565b6000818152601460205260408120541580611b935750611b91826135f6565b155b15611ba057506000919050565b6000611bab83613ac1565b60008481526014602052604081205491925090611bc89083614083565b9150506000601a5482611bdb919061523b565b905080611bed57506000949350505050565b601154601f54611bfe90600a6153f7565b611c08908361523b565b11611c5057601e54611c186133ca565b6103e8601b5485611c29919061521c565b611c33919061523b565b611c3d919061523b565b611c47919061523b565b95945050505050565b601e54611c5b6133ca565b6103e8601b5484611c29919061521c565b600e54600090611c7d8160016152fb565b600e819055811115611c8e57600080fd5b611c983382614407565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b6026546001600160a01b03163314611cff5760405162461bcd60e51b8152600401610c05906152c6565b80611d585760405162461bcd60e51b815260206004820152602360248201527f496e746572657374526174652063616e6e6f74206265207a65726f206164647260448201526265737360e81b6064820152608401610c05565b60138190556040518181527f323264e3ca065ee856fe1b11204d8896a783bccf148380ac5d7362eb5c4c36a890602001610f31565b80611d9781613ff8565b611db35760405162461bcd60e51b8152600401610c0590615454565b60008181526017602052604090205461271010801590611de0575060008181526017602052604090205415155b611dfc5760405162461bcd60e51b8152600401610c059061548b565b6026546001600160a01b03163314611e265760405162461bcd60e51b8152600401610c05906152c6565b611e2f82613ff8565b611e875760405162461bcd60e51b8152602060048201526024808201527f72656d6f766546726f6e74456e643a205661756c7420646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608401610c05565b600082815260176020526040902054611ee25760405162461bcd60e51b815260206004820152601f60248201527f72656d6f766546726f6e74456e643a206e6f7420612066726f6e7420656e64006044820152606401610c05565b60008281526017602052604080822091909155517f9b9f950fb3755096dbbe8b1519e73f7c6d1a0507f514fced444919530c00d7199061119a9084815260200190565b6026546001600160a01b03163314611f4f5760405162461bcd60e51b8152600401610c05906152c6565b60118190556040518181527f4533506fbaba6b18743358b6e6fb9392e8cb21757487b68d232a01b140bbec0190602001610f31565b6000818152600360205260408120546001600160a01b031680610dc15760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610c05565b6026546001600160a01b031633146120255760405162461bcd60e51b8152600401610c05906152c6565b60128190556040518181527f1dd8f42ee4750a70f6662d1383372472422592497256d506437e35b3fa914d9b90602001610f31565b60008060006120698585614083565b9092509050600061207a828461523b565b600d5411159695505050505050565b6026546001600160a01b031633146120b35760405162461bcd60e51b8152600401610c05906152c6565b6001600160a01b0381166121095760405162461bcd60e51b815260206004820181905260248201527f5265666572656e636520416464726573732063616e6e6f74206265207a65726f6044820152606401610c05565b602580546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ed6553fa1e634b0152cd3539c572bee8c662e446820646d73a0e1b47776af9390602001610f31565b6026546001600160a01b031633146121815760405162461bcd60e51b8152600401610c05906152c6565b6001600160a01b0381166121d75760405162461bcd60e51b815260206004820152601c60248201527f41646d696e20416464726573732063616e6e6f74206265207a65726f000000006044820152606401610c05565b602480546001600160a01b0319166001600160a01b0383169081179091556040519081527ffce52dd00c7849a7f2602c1f189745238d6a2db16fabf54376ce24cc2fa3d57f90602001610f31565b60006001600160a01b0382166122905760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610c05565b506001600160a01b031660009081526004602052604090205490565b6026546001600160a01b031633146122d65760405162461bcd60e51b8152600401610c05906152c6565b6122e06000614546565b565b816122ec81613ff8565b6123085760405162461bcd60e51b8152600401610c05906154b8565b3361231282611f84565b6001600160a01b0316146123385760405162461bcd60e51b8152600401610c0590615556565b6002600054141561235b5760405162461bcd60e51b8152600401610c05906151cf565b60026000908155838152601460205260409020548211156123cc5760405162461bcd60e51b815260206004820152602560248201527f5661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c616044820152641d195c985b60da1b6064820152608401610c05565b6000838152601460205260408120546123e690849061525d565b905060006123f385612a2d565b9050801561247757612405828261205a565b6124775760405162461bcd60e51b815260206004820152603e60248201527f5769746864726177616c20776f756c6420707574207661756c742062656c6f7760448201527f206d696e696d756d20636f6c6c61746572616c2070657263656e7461676500006064820152608401610c05565b6000858152601460205260409020829055601c5461249f906001600160a01b03163386614598565b60408051868152602081018690527f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9910160405180910390a150506001600055505050565b806124ee81613ff8565b61250a5760405162461bcd60e51b8152600401610c05906154b8565b3361251482611f84565b6001600160a01b03161461253a5760405162461bcd60e51b8152600401610c0590615556565b6002600054141561255d5760405162461bcd60e51b8152600401610c05906151cf565b600260005561256b82613ac1565b156125b85760405162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e6720646562740000000000006044820152606401610c05565b600082815260146020526040902054156125fa576125fa6125d883611f84565b600084815260146020526040902054601c546001600160a01b03169190614598565b612603826145c8565b600082815260146020908152604080832083905560158252808320839055601682528083209290925590518381527f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b465910160405180910390a150506001600055565b6026546001600160a01b0316331461268f5760405162461bcd60e51b8152600401610c05906152c6565b6101f48111156126ef5760405162461bcd60e51b815260206004820152602560248201527f7365744f70656e696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610c05565b60108190556040518181527fc4ced91ca77dc4287a54d9bd9b15c69b3aba262e30eba7c93301c48606019c9490602001610f31565b60008161273081613ff8565b61274c5760405162461bcd60e51b8152600401610c05906154b8565b600061275784612a2d565b9050806127985760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c05565b60008481526014602052604081205481906127b39084614083565b909250905060006127c4828461523b565b601b549091506127d582600a61521c565b111561283a5760405162461bcd60e51b815260206004820152602e60248201527f5661756c74206973206e6f742062656c6f77207269736b7920636f6c6c61746560448201526d72616c2070657263656e7461676560901b6064820152608401610c05565b6000601f54600a61284b91906153f7565b600d54612858919061521c565b612862908561523b565b601f5461287090600a6153f7565b61287a908561523b565b612884919061525d565b601d546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156128d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f591906154e6565b10156129515760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206d616920746f2062757920746865207269736b79206044820152641d985d5b1d60da1b6064820152608401610c05565b601d54612969906001600160a01b031633308461439c565b80602054612977919061525d565b6020556000612984611c6c565b60008a8152601460205260408082205483835291205590506129a6828761525d565b600082815260156020818152604080842094909455601681528383204290558c8352601481528383208390559081528282209190915581518b815290810183905233818301526060810184905290517fa4cf7276e26bb566de2c7540759e85736eb743807343fd27e6e679b20e8814419181900360800190a1965050505050505b50919050565b6000806000612a3b8461466f565b9150915081602254612a4d91906152fb565b602255602054612a5e9083906152fb565b6020908155600094855260168152604080862042905560159091529093208390555090919050565b601d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612acf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612af391906154e6565b905090565b80612b0281613ff8565b612b1e5760405162461bcd60e51b8152600401610c0590615454565b60008181526017602052604090205461271010801590612b4b575060008181526017602052604090205415155b612b675760405162461bcd60e51b8152600401610c059061548b565b82612b7181613ff8565b612b8d5760405162461bcd60e51b8152600401610c05906154b8565b6023546001600160a01b03161580612baf57506023546001600160a01b031633145b612c065760405162461bcd60e51b815260206004820152602260248201527f6c69717569646174696f6e2069732064697361626c656420666f72207075626c604482015261696360f01b6064820152608401610c05565b6000612c1185612a2d565b600086815260146020526040812054919250908190612c309084614083565b915091508260001415612c775760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610c05565b6000612c83828461523b565b9050600d548110612cef5760405162461bcd60e51b815260206004820152603060248201527f5661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c6160448201526f746572616c2070657263656e7461676560801b6064820152608401610c05565b601b54612cfd82600a61521c565b11612d4a5760405162461bcd60e51b815260206004820152601d60248201527f5661756c74206973206e6f742061626f7665206761696e20726174696f0000006044820152606401610c05565b601f54612d5890600a6153f7565b612d62908361523b565b91506000601a5483612d74919061523b565b90506011548111612d825750815b601d546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612dca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dee91906154e6565b1015612e565760405162461bcd60e51b815260206004820152603160248201527f546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666604482015270081bdd5d1cdd185b991a5b99c81919589d607a1b6064820152608401610c05565b80602054612e64919061525d565b6020556000612e728a611b72565b9050612e7e828761525d565b60008b815260156020908152604080832093909355600f548c83526017909152918120549091612eaf918590611ac1565b60008c815260146020526040902054909150612ecc90829061525d565b60008c815260146020526040808220929092558b81522054612eef9082906152fb565b60008b815260146020526040808220929092558c81522054612f1290839061525d565b60008c815260146020908152604080832093909355338252602190522054612f3b9083906152fb565b33600081815260216020526040902091909155601d54612f68916001600160a01b0390911690308661439c565b7f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d58b612f938d611f84565b604080519283526001600160a01b0390911660208301523390820152606081018590526080810184905260a0810183905260c00160405180910390a15050505050505050505050565b606060028054610dd690615291565b80612ff581613ff8565b6130115760405162461bcd60e51b8152600401610c0590615454565b6000818152601760205260409020546127101080159061303e575060008181526017602052604090205415155b61305a5760405162461bcd60e51b8152600401610c059061548b565b8361306481613ff8565b6130805760405162461bcd60e51b8152600401610c05906154b8565b3361308a82611f84565b6001600160a01b0316146130b05760405162461bcd60e51b8152600401610c0590615556565b600260005414156130d35760405162461bcd60e51b8152600401610c05906151cf565b6002600055836131255760405162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e7400000000006044820152606401610c05565b61312d612a86565b8411156131945760405162461bcd60e51b815260206004820152602f60248201527f626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617660448201526e30b4b630b136329039bab838363c9760891b6064820152608401610c05565b6000846131a087612a2d565b6131aa91906152fb565b90506012548111156132095760405162461bcd60e51b815260206004820152602260248201527f626f72726f77546f6b656e3a206d6178206c6f616e2063617020726561636865604482015261321760f11b6064820152608401610c05565b61321286613ac1565b811161321d57600080fd5b600086815260146020526040902054613236908261205a565b6132a85760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e60448201527f696d756d20636f6c6c61746572616c2070657263656e746167650000000000006064820152608401610c05565b601154856132b588613ac1565b6132bf91906152fb565b10156132dd5760405162461bcd60e51b8152600401610c05906154ff565b6000868152601560209081526040808320849055601054878452601790925282205461330b91908490611ac1565b60008881526014602052604090205490915061332890829061525d565b60008881526014602052604080822092909255868152205461334b9082906152fb565b600086815260146020526040902055601d54613371906001600160a01b03163388614598565b8560205461337f91906152fb565b6020908155604080518981529182018890527f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca910160405180910390a1505060016000555050505050565b600c54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd9160048083019260209291908290030181865afa158015612acf573d6000803e3d6000fd5b6026546001600160a01b0316331461343e5760405162461bcd60e51b8152600401610c05906152c6565b6001600160a01b0381166134a05760405162461bcd60e51b8152602060048201526024808201527f53746162696c697479506f6f6c2063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610c05565b602380546001600160a01b0319166001600160a01b0383169081179091556040519081527f0644c4f539d7f787d2287c12d9425e80aefc8bdae99c70af4ca66fb0742577e890602001610f31565b6134f9338383614714565b5050565b6026546001600160a01b031633146135275760405162461bcd60e51b8152600401610c05906152c6565b805161353a906027906020840190614ce5565b507f0d82453dd4ad18b5ce3db08c34a39340ad2bf15046a7d0e86aa075483eb121d881604051610f319190614e7d565b601c546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156135b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135d791906154e6565b601e546135e26133ca565b6135ec919061521c565b612af3919061521c565b60008161360281613ff8565b61361e5760405162461bcd60e51b8152600401610c05906154b8565b600061362984613ac1565b6000858152601460205260409020549091501580613645575080155b15613654576000925050612a27565b600084815260146020526040812054819061366f9084614083565b90925090506000613680828461523b565b9050600d54811015613699576001955050505050612a27565b6000955050505050612a27565b6136b0338361410c565b6136cc5760405162461bcd60e51b8152600401610c0590615403565b6136d8848484846147e3565b50505050565b60606136e982613ff8565b6136f257600080fd5b600b80546136ff90615291565b80601f016020809104026020016040519081016040528092919081815260200182805461372b90615291565b80156137785780601f1061374d57610100808354040283529160200191613778565b820191906000526020600020905b81548152906001019060200180831161375b57829003601f168201915b50505050509050919050565b8161378e81613ff8565b6137aa5760405162461bcd60e51b8152600401610c0590615454565b600081815260176020526040902054612710108015906137d7575060008181526017602052604090205415155b6137f35760405162461bcd60e51b8152600401610c059061548b565b826137fd81613ff8565b6138195760405162461bcd60e51b8152600401610c05906154b8565b3361382382611f84565b6001600160a01b0316146138495760405162461bcd60e51b8152600401610c0590615556565b60008311801561385b57506127108311155b6138a75760405162461bcd60e51b815260206004820152601b60248201527f75706461746546726f6e74456e643a2063616e6e6f74206265203000000000006044820152606401610c05565b60008481526017602090815260409182902085905581518681529081018590527fbfdd5aecf44aa804bf11f070a41765d280dab82adbfd1c55e1e85b7d5b7920b491015b60405180910390a150505050565b6002600054141561391c5760405162461bcd60e51b8152600401610c05906151cf565b600260009081553381526021602052604090205461397c5760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610c05565b3360008181526021602052604081208054919055601c5490916139a9916001600160a01b03169083614598565b506001600055565b806139bb81613ff8565b6139d75760405162461bcd60e51b8152600401610c0590615454565b60008181526017602052604090205461271010801590613a04575060008181526017602052604090205415155b613a205760405162461bcd60e51b8152600401610c059061548b565b83613a2a81613ff8565b613a465760405162461bcd60e51b8152600401610c05906154b8565b42841015613aa15760405162461bcd60e51b815260206004820152602260248201527f7061796261636b546f6b656e416c6c3a20646561646c696e6520657870697265604482015261321760f11b6064820152608401610c05565b6000613aac86612a2d565b9050613ab986828661131f565b505050505050565b6000806112508361466f565b600081613ad981613ff8565b613af55760405162461bcd60e51b8152600401610c05906154b8565b6000613b0084613ac1565b6000858152601460205260409020549091501580613b1c575080155b15613b2b576000925050612a27565b6000848152601460205260408120548190613b469084614083565b9092509050613b55818361523b565b9695505050505050565b6026546001600160a01b03163314613b895760405162461bcd60e51b8152600401610c05906152c6565b613b95600b8383614d69565b507ffda45751019c07e08a3ebf7d73a4aea1a6c36bee12d87089096012911a756ab5600b60405161119a919061558d565b600b8054613bd390615291565b80601f0160208091040260200160405190810160405280929190818152602001828054613bff90615291565b8015613c4c5780601f10613c2157610100808354040283529160200191613c4c565b820191906000526020600020905b815481529060010190602001808311613c2f57829003601f168201915b505050505081565b6026546001600160a01b03163314613c7e5760405162461bcd60e51b8152600401610c05906152c6565b601a54613cc65760405162461bcd60e51b815260206004820152601660248201527504465627420526174696f2063616e6e6f7420626520360541b6044820152606401610c05565b601a8190556040518181527f199e93b2fae27b389e2d09761871573f60121b8521be96b8f28c83bf94846ac290602001610f31565b81613d0581613ff8565b613d215760405162461bcd60e51b8152600401610c05906154b8565b600083815260146020526040812054613d3b9084906152fb565b600085815260146020526040902054909150811015613d5957600080fd5b6000848152601460205260409020819055601c54613d82906001600160a01b031633308661439c565b60408051858152602081018590527f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d91016138eb565b6026546001600160a01b03163314613de25760405162461bcd60e51b8152600401610c05906152c6565b6001600160a01b038116613e475760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c05565b613e5081614546565b50565b6026546001600160a01b03163314613e7d5760405162461bcd60e51b8152600401610c05906152c6565b6103e8811015613ee65760405162461bcd60e51b815260206004820152602e60248201527f6761696e526174696f2063616e6e6f74206265206c657373207468616e206f7260448201526d020657175616c20746f20313030360941b6064820152608401610c05565b601b8190556040518181527fb6d384ad48d9c5c042c81fa0f88d8061ef87b38475101d6aa5f9ae5a8274a64e90602001610f31565b6001600160a01b038316613f7657613f7181600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b613f99565b816001600160a01b0316836001600160a01b031614613f9957613f998382614816565b6001600160a01b038216613fb0576110d5816148b3565b826001600160a01b0316826001600160a01b0316146110d5576110d58282614962565b60006001600160e01b0319821663780e9d6360e01b1480610dc15750610dc1826149a6565b6000908152600360205260409020546001600160a01b0316151590565b600081815260056020526040902080546001600160a01b0319166001600160a01b038416908117909155819061404a82611f84565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061408e6133ca565b61409757600080fd5b6000601e546140a46133ca565b6140ae908761521c565b6140b8919061521c565b9050848110156140c757600080fd5b60006140d76305f5e1008661521c565b9050848110156140e657600080fd5b60006140f383606461521c565b905082811161410157600080fd5b969095509350505050565b600061411782613ff8565b6141785760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610c05565b600061418383611f84565b9050806001600160a01b0316846001600160a01b031614806141ca57506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806112505750836001600160a01b03166141e384610f3c565b6001600160a01b031614949350505050565b826001600160a01b031661420882611f84565b6001600160a01b03161461426c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610c05565b6001600160a01b0382166142ce5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c05565b6142d98383836149f6565b6142e4600082614015565b6001600160a01b038316600090815260046020526040812080546001929061430d90849061525d565b90915550506001600160a01b038216600090815260046020526040812080546001929061433b9084906152fb565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516001600160a01b03808516602483015283166044820152606481018290526136d89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a01565b6001600160a01b03821661445d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c05565b61446681613ff8565b156144b35760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c05565b6144bf600083836149f6565b6001600160a01b03821660009081526004602052604081208054600192906144e89084906152fb565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b602680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6040516001600160a01b0383166024820152604481018290526110d590849063a9059cbb60e01b906064016143d0565b60006145d382611f84565b90506145e1816000846149f6565b6145ec600083614015565b6001600160a01b038116600090815260046020526040812080546001929061461590849061525d565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60008181526015602090815260408083205460169092528220548291429183901580159061469f57506000601354115b1561470a576000868152601660205260408120546146bd908561525d565b905060006127106301e1855883866013546146d8919061521c565b6146e2919061521c565b6146ec919061523b565b6146f6919061523b565b925082905061470584826152fb565b935050505b9590945092505050565b816001600160a01b0316836001600160a01b031614156147765760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c05565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6147ee8484846141f5565b6147fa84848484614ad3565b6136d85760405162461bcd60e51b8152600401610c0590615635565b6000600161482384612225565b61482d919061525d565b600083815260086020526040902054909150808214614880576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906148c59060019061525d565b6000838152600a6020526040812054600980549394509092849081106148ed576148ed615540565b90600052602060002001549050806009838154811061490e5761490e615540565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548061494657614946615687565b6001900381819060005260206000200160009055905550505050565b600061496d83612225565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160e01b031982166380ac58cd60e01b14806149d757506001600160e01b03198216635b5e139f60e01b145b80610dc157506301ffc9a760e01b6001600160e01b0319831614610dc1565b6110d5838383613f1b565b6000614a56826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614bd19092919063ffffffff16565b8051909150156110d55780806020019051810190614a749190615274565b6110d55760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610c05565b60006001600160a01b0384163b15614bc657604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614b1790339089908890889060040161569d565b6020604051808303816000875af1925050508015614b52575060408051601f3d908101601f19168201909252614b4f918101906156d0565b60015b614bac573d808015614b80576040519150601f19603f3d011682016040523d82523d6000602084013e614b85565b606091505b508051614ba45760405162461bcd60e51b8152600401610c0590615635565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611250565b506001949350505050565b60606112508484600085856001600160a01b0385163b614c335760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c05565b600080866001600160a01b03168587604051614c4f91906156ed565b60006040518083038185875af1925050503d8060008114614c8c576040519150601f19603f3d011682016040523d82523d6000602084013e614c91565b606091505b5091509150614ca1828286614cac565b979650505050505050565b60608315614cbb575081611b6b565b825115614ccb5782518084602001fd5b8160405162461bcd60e51b8152600401610c059190614e7d565b828054614cf190615291565b90600052602060002090601f016020900481019282614d135760008555614d59565b82601f10614d2c57805160ff1916838001178555614d59565b82800160010185558215614d59579182015b82811115614d59578251825591602001919060010190614d3e565b50614d65929150614ddd565b5090565b828054614d7590615291565b90600052602060002090601f016020900481019282614d975760008555614d59565b82601f10614db05782800160ff19823516178555614d59565b82800160010185558215614d59579182015b82811115614d59578235825591602001919060010190614dc2565b5b80821115614d655760008155600101614dde565b6001600160e01b031981168114613e5057600080fd5b600060208284031215614e1a57600080fd5b8135611b6b81614df2565b60005b83811015614e40578181015183820152602001614e28565b838111156136d85750506000910152565b60008151808452614e69816020860160208601614e25565b601f01601f19169290920160200192915050565b602081526000611b6b6020830184614e51565b80356001600160a01b0381168114614ea757600080fd5b919050565b600060208284031215614ebe57600080fd5b611b6b82614e90565b600060208284031215614ed957600080fd5b5035919050565b60008060408385031215614ef357600080fd5b614efc83614e90565b946020939093013593505050565b60008060408385031215614f1d57600080fd5b50508035926020909101359150565b600080600060608486031215614f4157600080fd5b614f4a84614e90565b9250614f5860208501614e90565b9150604084013590509250925092565b600080600060608486031215614f7d57600080fd5b505081359360208301359350604090920135919050565b8015158114613e5057600080fd5b60008060408385031215614fb557600080fd5b614fbe83614e90565b91506020830135614fce81614f94565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561500a5761500a614fd9565b604051601f8501601f19908116603f0116810190828211818310171561503257615032614fd9565b8160405280935085815286868601111561504b57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561507757600080fd5b813567ffffffffffffffff81111561508e57600080fd5b8201601f8101841361509f57600080fd5b61125084823560208401614fef565b600080600080608085870312156150c457600080fd5b6150cd85614e90565b93506150db60208601614e90565b925060408501359150606085013567ffffffffffffffff8111156150fe57600080fd5b8501601f8101871361510f57600080fd5b61511e87823560208401614fef565b91505092959194509250565b6000806020838503121561513d57600080fd5b823567ffffffffffffffff8082111561515557600080fd5b818501915085601f83011261516957600080fd5b81358181111561517857600080fd5b86602082850101111561518a57600080fd5b60209290920196919550909350505050565b600080604083850312156151af57600080fd5b6151b883614e90565b91506151c660208401614e90565b90509250929050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600081600019048311821515161561523657615236615206565b500290565b60008261525857634e487b7160e01b600052601260045260246000fd5b500490565b60008282101561526f5761526f615206565b500390565b60006020828403121561528657600080fd5b8151611b6b81614f94565b600181811c908216806152a557607f821691505b60208210811415612a2757634e487b7160e01b600052602260045260246000fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000821982111561530e5761530e615206565b500190565b600181815b8085111561534e57816000190482111561533457615334615206565b8085161561534157918102915b93841c9390800290615318565b509250929050565b60008261536557506001610dc1565b8161537257506000610dc1565b81600181146153885760028114615392576153ae565b6001915050610dc1565b60ff8411156153a3576153a3615206565b50506001821b610dc1565b5060208310610133831016604e8410600b84101617156153d1575081810a610dc1565b6153db8383615313565b80600019048211156153ef576153ef615206565b029392505050565b6000611b6b8383615356565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601e908201527f66726f6e7420656e64207661756c7420646f6573206e6f742065786973740000604082015260600190565b602080825260139082015272119c9bdb9d08195b99081b9bdd081859191959606a1b604082015260600190565b60208082526014908201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6000602082840312156154f857600080fd5b5051919050565b60208082526021908201527f5661756c7420646562742063616e277420626520756e646572206d696e4465626040820152601d60fa1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526019908201527f5661756c74206973206e6f74206f776e656420627920796f7500000000000000604082015260600190565b600060208083526000845481600182811c9150808316806155af57607f831692505b8583108114156155cd57634e487b7160e01b85526022600452602485fd5b8786018381526020018180156155ea57600181146155fb57615626565b60ff19861682528782019650615626565b60008b81526020902060005b8681101561562057815484820152908501908901615607565b83019750505b50949998505050505050505050565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613b5590830184614e51565b6000602082840312156156e257600080fd5b8151611b6b81614df2565b600082516156ff818460208701614e25565b919091019291505056fea26469706673582212205969f6371bd10e54f12be697d33f6f10295954d960c25267ecb120a2f7204dbf64736f6c634300080b00330000000000000000000000007f9dd991e8fd0cbb52cb8eb35dd35c474a9a7a7000000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b0200000000000000000000000006a3b410b681c82417a906993acefb91bab6a08000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000011785374656c6c61204d4149205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000578534d5654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d66517639455744553166374562454b4b48506a5a3571476b7a394a623957646f5847567037486e6638597666000000000000000000000000000000000000

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

0000000000000000000000007f9dd991e8fd0cbb52cb8eb35dd35c474a9a7a7000000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b0200000000000000000000000006a3b410b681c82417a906993acefb91bab6a08000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000011785374656c6c61204d4149205661756c74000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000578534d5654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e516d66517639455744553166374562454b4b48506a5a3571476b7a394a623957646f5847567037486e6638597666000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : ethPriceSourceAddress (address): 0x7f9dd991e8fd0cbb52cb8eb35dd35c474a9a7a70
Arg [1] : minimumCollateralPercentage (uint256): 250
Arg [2] : name (string): xStella MAI Vault
Arg [3] : symbol (string): xSMVT
Arg [4] : _mai (address): 0xdfa46478f9e5ea86d57387849598dbfb2e964b02
Arg [5] : _collateral (address): 0x06a3b410b681c82417a906993acefb91bab6a080
Arg [6] : baseURI (string): QmfQv9EWDU1f7EbEKKHPjZ5qGkz9Jb9WdoXGVp7Hnf8Yvf

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 0000000000000000000000007f9dd991e8fd0cbb52cb8eb35dd35c474a9a7a70
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000fa
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [4] : 000000000000000000000000dfa46478f9e5ea86d57387849598dbfb2e964b02
Arg [5] : 00000000000000000000000006a3b410b681c82417a906993acefb91bab6a080
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000011
Arg [8] : 785374656c6c61204d4149205661756c74000000000000000000000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [10] : 78534d5654000000000000000000000000000000000000000000000000000000
Arg [11] : 000000000000000000000000000000000000000000000000000000000000002e
Arg [12] : 516d66517639455744553166374562454b4b48506a5a3571476b7a394a623957
Arg [13] : 646f5847567037486e6638597666000000000000000000000000000000000000


Deployed ByteCode Sourcemap

96505:10717:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105802:332;;;:::i;:::-;;69554:171;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;69554:171:0;;;;;;;;71410:28;;;;;-1:-1:-1;;;;;71410:28:0;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;71410:28:0;592:203:1;71445:18:0;;;;;-1:-1:-1;;;;;71445:18:0;;;48764:100;;;:::i;:::-;;;;;;;:::i;99929:331::-;;;;;;:::i;:::-;;:::i;50324:221::-;;;;;;:::i;:::-;;:::i;49847:411::-;;;;;;:::i;:::-;;:::i;101071:244::-;;;;;;:::i;:::-;;:::i;87555:799::-;;;;;;:::i;:::-;;:::i;:::-;;;2918:25:1;;;2906:2;2891:18;87555:799:0;2772:177:1;63673:113:0;63761:10;:17;63673:113;;70527:25;;;;;;71470:18;;;;;-1:-1:-1;;;;;71470:18:0;;;51074:339;;;;;;:::i;:::-;;:::i;70706:17::-;;;;;;70789:55;;;;;;:::i;:::-;;;;;;;;;;;;;;63341:256;;;;;;:::i;:::-;;:::i;71110:24::-;;;;;;85816:1140;;;;;;:::i;:::-;;:::i;101493:258::-;;;;;;:::i;:::-;;:::i;103910:277::-;;;;;;:::i;:::-;;:::i;104401:303::-;;;;;;:::i;:::-;;:::i;51484:185::-;;;;;;:::i;:::-;;:::i;106698:250::-;;;;;;:::i;:::-;;:::i;70394:34::-;;;;;-1:-1:-1;;;;;70394:34:0;;;71291:28;;;;;;74541:104;;;;;;:::i;:::-;;:::i;63863:233::-;;;;;;:::i;:::-;;:::i;79906:533::-;;;;;;:::i;:::-;;:::i;71495:24::-;;;;;-1:-1:-1;;;71495:24:0;;;;;;;;;4009:4:1;3997:17;;;3979:36;;3967:2;3952:18;71495:24:0;3837:184:1;88588:896:0;;;;;;:::i;:::-;;:::i;71173:16::-;;;;;-1:-1:-1;;;;;71173:16:0;;;80555:259;;;:::i;106258:191::-;;;;;;:::i;:::-;;:::i;105416:325::-;;;;;;:::i;:::-;;:::i;101902:219::-;;;;;;:::i;:::-;;:::i;48458:239::-;;;;;;:::i;:::-;;:::i;102288:219::-;;;;;;:::i;:::-;;:::i;79079:429::-;;;;;;:::i;:::-;;:::i;102708:183::-;;;;;;:::i;:::-;;:::i;103097:::-;;;;;;:::i;:::-;;:::i;48188:208::-;;;;;;:::i;:::-;;:::i;2614:103::-;;;:::i;70559:25::-;;;;;;82576:775;;;;;;:::i;:::-;;:::i;80992:578::-;;;;;;:::i;:::-;;:::i;103457:277::-;;;;;;:::i;:::-;;:::i;1963:87::-;2036:6;;-1:-1:-1;;;;;2036:6:0;1963:87;;94373:1930;;;;;;:::i;:::-;;:::i;77290:417::-;;;;;;:::i;:::-;;:::i;74193:110::-;;;:::i;91564:2349::-;;;;;;:::i;:::-;;:::i;48933:104::-;;;:::i;83712:1365::-;;;;;;:::i;:::-;;:::i;70853:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;75708:114;;;:::i;100497:231::-;;;;;;:::i;:::-;;:::i;70959:23::-;;;;;;50617:155;;;;;;:::i;:::-;;:::i;71198:43::-;;;;;;75188:93;75263:10;;75188:93;;70489:25;;;;;;98684:149;;;;;;:::i;:::-;;:::i;71328:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;74795:252;;;:::i;90414:753::-;;;;;;:::i;:::-;;:::i;51740:328::-;;;;;;:::i;:::-;;:::i;71250:34::-;;;;;;69879:147;;;;;;:::i;:::-;;:::i;104973:311::-;;;;;;:::i;:::-;;:::i;75435:95::-;70688:3;75435:95;;70653:38;;70688:3;70653:38;;71079:24;;;;;;87072:266;;;:::i;85085:392::-;;;;;;:::i;:::-;;:::i;70622:22::-;;;;;;76933:151;;;;;;:::i;:::-;;:::i;70732:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;70907:43;;;;;;:::i;:::-;;;;;;;;;;;;;;71143:23;;;;;-1:-1:-1;;;;;71143:23:0;;;89634:585;;;;;;:::i;:::-;;:::i;107092:127::-;;;;;;:::i;:::-;;:::i;70437:43::-;;;;;;50843:164;;;;;;:::i;:::-;-1:-1:-1;;;;;50964:25:0;;;50940:4;50964:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;50843:164;69339:17;;;:::i;99455:205::-;;;;;;:::i;:::-;;:::i;71019:21::-;;;;;;81848:434;;;;;;:::i;:::-;;:::i;70593:22::-;;;;;;71379;;;;;;2872:201;;;;;;:::i;:::-;;:::i;99030:233::-;;;;;;:::i;:::-;;:::i;105802:332::-;98295:3;;-1:-1:-1;;;;;98295:3:0;98302:10;98295:17;;:38;;-1:-1:-1;98316:3:0;;-1:-1:-1;;;;;98316:3:0;98323:10;98316:17;98295:38;:63;;;-1:-1:-1;98348:10:0;98337:7;2036:6;;-1:-1:-1;;;;;2036:6:0;;1963:87;98337:7;-1:-1:-1;;;;;98337:21:0;;98295:63;98287:107;;;;-1:-1:-1;;;98287:107:0;;7652:2:1;98287:107:0;;;7634:21:1;7691:2;7671:18;;;7664:30;7730:33;7710:18;;;7703:61;7781:18;;98287:107:0;;;;;;;;;34324:1:::1;34922:7;;:19;;34914:63;;;;-1:-1:-1::0;;;34914:63:0::1;;;;;;;:::i;:::-;34324:1;35055:7;:18:::0;;;105905:8:::2;::::0;105897:7:::2;::::0;70298:5:::2;::::0;105897:16:::2;::::0;::::2;:::i;:::-;:31;;;;:::i;:::-;105962:3;::::0;105975::::2;::::0;105981:7:::2;::::0;105879:49;;-1:-1:-1;;;;;;105962:3:0;;::::2;::::0;:12:::2;::::0;105975:3;;::::2;::::0;105981:15:::2;::::0;105879:49;;105981:15:::2;:::i;:::-;105962:37;::::0;-1:-1:-1;;;;;;105962:37:0::2;::::0;;;;;;-1:-1:-1;;;;;9019:32:1;;;105962:37:0::2;::::0;::::2;9001:51:1::0;9068:18;;;9061:34;8974:18;;105962:37:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;106037:3:0::2;::::0;106050::::2;::::0;;106037:26:::2;::::0;-1:-1:-1;;;106037:26:0;;-1:-1:-1;;;;;106050:3:0;;::::2;106037:26;::::0;::::2;9001:51:1::0;9068:18;;;9061:34;;;106037:3:0;;::::2;::::0;:12:::2;::::0;8974:18:1;;106037:26:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;106079:25;106096:7;;106079:25;;;;2918::1::0;;2906:2;2891:18;;2772:177;106079:25:0::2;;;;;;;;-1:-1:-1::0;106125:1:0::2;106115:7;:11:::0;;;34280:1:::1;35234:22:::0;;105802:332::o;69554:171::-;69657:4;69681:36;69705:11;69681:23;:36::i;:::-;69674:43;69554:171;-1:-1:-1;;69554:171:0:o;48764:100::-;48818:13;48851:5;48844:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48764:100;:::o;99929:331::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;100051:35:0;::::1;100043:86;;;::::0;-1:-1:-1;;;100043:86:0;;10304:2:1;100043:86:0::1;::::0;::::1;10286:21:1::0;10343:2;10323:18;;;10316:30;10382:34;10362:18;;;10355:62;-1:-1:-1;;;10433:18:1;;;10426:35;10478:19;;100043:86:0::1;10102:401:1::0;100043:86:0::1;100140:14;:52:::0;;-1:-1:-1;;;;;;100140:52:0::1;-1:-1:-1::0;;;;;100140:52:0;::::1;::::0;;::::1;::::0;;;100208:44:::1;::::0;738:51:1;;;100208:44:0::1;::::0;726:2:1;711:18;100208:44:0::1;;;;;;;;99929:331:::0;:::o;50324:221::-;50400:7;50428:16;50436:7;50428;:16::i;:::-;50420:73;;;;-1:-1:-1;;;50420:73:0;;10710:2:1;50420:73:0;;;10692:21:1;10749:2;10729:18;;;10722:30;10788:34;10768:18;;;10761:62;-1:-1:-1;;;10839:18:1;;;10832:42;10891:19;;50420:73:0;10508:408:1;50420:73:0;-1:-1:-1;50513:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;50513:24:0;;50324:221::o;49847:411::-;49928:13;49944:23;49959:7;49944:14;:23::i;:::-;49928:39;;49992:5;-1:-1:-1;;;;;49986:11:0;:2;-1:-1:-1;;;;;49986:11:0;;;49978:57;;;;-1:-1:-1;;;49978:57:0;;11123:2:1;49978:57:0;;;11105:21:1;11162:2;11142:18;;;11135:30;11201:34;11181:18;;;11174:62;-1:-1:-1;;;11252:18:1;;;11245:31;11293:19;;49978:57:0;10921:397:1;49978:57:0;763:10;-1:-1:-1;;;;;50070:21:0;;;;:62;;-1:-1:-1;50095:37:0;50112:5;763:10;50843:164;:::i;50095:37::-;50048:168;;;;-1:-1:-1;;;50048:168:0;;11525:2:1;50048:168:0;;;11507:21:1;11564:2;11544:18;;;11537:30;11603:34;11583:18;;;11576:62;11674:26;11654:18;;;11647:54;11718:19;;50048:168:0;11323:420:1;50048:168:0;50229:21;50238:2;50242:7;50229:8;:21::i;:::-;49917:341;49847:411;;:::o;101071:244::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;70298:5:::1;101157:11;101164:4:::0;101157:6;:11:::1;:::i;:::-;101156:27;101148:66;;;::::0;-1:-1:-1;;;101148:66:0;;12083:2:1;101148:66:0::1;::::0;::::1;12065:21:1::0;12122:2;12102:18;;;12095:30;12161:28;12141:18;;;12134:56;12207:18;;101148:66:0::1;11881:350:1::0;101148:66:0::1;101225:8;:15:::0;;;101251:6:::1;:11:::0;;;101278:29:::1;::::0;;12410:25:1;;;12466:2;12451:18;;12444:34;;;101278:29:0::1;::::0;12383:18:1;101278:29:0::1;;;;;;;;101071:244:::0;;:::o;87555:799::-;87612:7;87632:20;87655:18;87665:7;87655:9;:18::i;:::-;87704:24;;;;:15;:24;;;;;;87632:41;;-1:-1:-1;87704:29:0;;:63;;-1:-1:-1;87750:17:0;;87704:63;:106;;;;87785:25;87802:7;87785:16;:25::i;:::-;87784:26;87704:106;87686:171;;;-1:-1:-1;87844:1:0;;87555:799;-1:-1:-1;;87555:799:0:o;87686:171::-;87885:17;87964:24;;;:15;:24;;;;;;87916:118;;88007:12;87916:29;:118::i;:::-;87869:165;-1:-1:-1;;88051:14:0;88047:55;;-1:-1:-1;88089:1:0;;87555:799;-1:-1:-1;;;87555:799:0:o;88047:55::-;88143:19;;88139:23;;:2;:23;:::i;:::-;88126:37;;:9;:37;:::i;:::-;88114:49;;88176:16;88207:9;;88195;:21;;;;:::i;:::-;88176:40;;88261:7;;88249:8;:19;88245:72;;-1:-1:-1;88296:9:0;88245:72;88337:8;87555:799;-1:-1:-1;;;;87555:799:0:o;51074:339::-;51269:41;763:10;51302:7;51269:18;:41::i;:::-;51261:103;;;;-1:-1:-1;;;51261:103:0;;;;;;;:::i;:::-;51377:28;51387:4;51393:2;51397:7;51377:9;:28::i;63341:256::-;63438:7;63474:23;63491:5;63474:16;:23::i;:::-;63466:5;:31;63458:87;;;;-1:-1:-1;;;63458:87:0;;14483:2:1;63458:87:0;;;14465:21:1;14522:2;14502:18;;;14495:30;14561:34;14541:18;;;14534:62;-1:-1:-1;;;14612:18:1;;;14605:41;14663:19;;63458:87:0;14281:407:1;63458:87:0;-1:-1:-1;;;;;;63563:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;63341:256::o;85816:1140::-;85940:6;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;85960:7:::1;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1::0;;;73671:49:0::1;;;;;;;:::i;:::-;85988:3:::2;::::0;:25:::2;::::0;-1:-1:-1;;;85988:25:0;;86002:10:::2;85988:25;::::0;::::2;738:51:1::0;86017:6:0;;-1:-1:-1;;;;;85988:3:0::2;::::0;:13:::2;::::0;711:18:1;;85988:25:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;;85980:69;;;::::0;-1:-1:-1;;;85980:69:0;;16140:2:1;85980:69:0::2;::::0;::::2;16122:21:1::0;16179:2;16159:18;;;16152:30;-1:-1:-1;;;16198:18:1;;;16191:51;16259:18;;85980:69:0::2;15938:345:1::0;85980:69:0::2;86062:20;86085:24;86101:7;86085:15;:24::i;:::-;86062:47;;86160:6;86144:12;:22;;86122:111;;;::::0;-1:-1:-1;;;86122:111:0;;16490:2:1;86122:111:0::2;::::0;::::2;16472:21:1::0;16529:2;16509:18;;;16502:30;16568:34;16548:18;;;16541:62;-1:-1:-1;;;16619:18:1;;;16612:37;16666:19;;86122:111:0::2;16288:403:1::0;86122:111:0::2;86297:7;::::0;86269:23:::2;86286:6:::0;86270:12;86269:23:::2;:::i;:::-;86268:36;;:64;;;;86319:12;86308:6;:24;86268:64;86246:147;;;;-1:-1:-1::0;;;86246:147:0::2;;;;;;;:::i;:::-;86455:10;::::0;86406:19:::2;86501:16:::0;;;:8:::2;:16;::::0;;;;;86406:19;;86428:100:::2;::::0;86480:6;;86428:12:::2;:100::i;:::-;86406:122:::0;-1:-1:-1;86573:21:0::2;86588:6:::0;86573:12;:21:::2;:::i;:::-;86541:29;::::0;;;:20:::2;:29;::::0;;;;;;;:53;;;;86634:15:::2;:24:::0;;;;:38:::2;::::0;86661:11;;86634:38:::2;:::i;:::-;86607:24;::::0;;;:15:::2;:24;::::0;;;;;:65;;;;86709:23;;;;;:37:::2;::::0;86735:11;;86709:37:::2;:::i;:::-;86683:23;::::0;;;:15:::2;:23;::::0;;;;;;;:63;;;;86775:13;:22:::2;::::0;86791:6;;86775:22:::2;:::i;:::-;86759:13;:38:::0;86825:3:::2;::::0;:55:::2;::::0;-1:-1:-1;;;;;86825:3:0::2;86846:10;86866:4;86873:6:::0;86825:20:::2;:55::i;:::-;86906:42;::::0;;17300:25:1;;;17356:2;17341:18;;17334:34;;;17384:18;;;17377:34;;;86906:42:0::2;::::0;17288:2:1;17273:18;86906:42:0::2;;;;;;;85969:987;;73968:1:::1;85816:1140:::0;;;;:::o;101493:258::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;101614:28:::1;:58:::0;;;101688:55:::1;::::0;2918:25:1;;;101688:55:0::1;::::0;2906:2:1;2891:18;101688:55:0::1;2772:177:1::0;103910:277:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;96663:3:::1;104012:11;:22;;103984:92;;;::::0;-1:-1:-1;;;103984:92:0;;17624:2:1;103984:92:0::1;::::0;::::1;17606:21:1::0;17663:2;17643:18;;;17636:30;17702:34;17682:18;;;17675:62;-1:-1:-1;;;17753:18:1;;;17746:35;17798:19;;103984:92:0::1;17422:401:1::0;103984:92:0::1;104087:10;:24:::0;;;104150:29:::1;::::0;2918:25:1;;;104150:29:0::1;::::0;2906:2:1;2891:18;104150:29:0::1;2772:177:1::0;104401:303:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;104477:18:::1;104485:9;104477:7;:18::i;:::-;104469:64;;;::::0;-1:-1:-1;;;104469:64:0;;18030:2:1;104469:64:0::1;::::0;::::1;18012:21:1::0;18069:2;18049:18;;;18042:30;18108:34;18088:18;;;18081:62;-1:-1:-1;;;18159:18:1;;;18152:31;18200:19;;104469:64:0::1;17828:397:1::0;104469:64:0::1;104556:19;::::0;;;:8:::1;:19;::::0;;;;;:24;104548:63:::1;;;::::0;-1:-1:-1;;;104548:63:0;;18432:2:1;104548:63:0::1;::::0;::::1;18414:21:1::0;18471:2;18451:18;;;18444:30;18510:28;18490:18;;;18483:56;18556:18;;104548:63:0::1;18230:350:1::0;104548:63:0::1;104622:19;::::0;;;:8:::1;:19;::::0;;;;;;70298:5:::1;104622:34:::0;;104672:24;::::1;::::0;::::1;::::0;104631:9;2918:25:1;;2906:2;2891:18;;2772:177;51484:185:0;51622:39;51639:4;51645:2;51649:7;51622:39;;;;;;;;;;;;:16;:39::i;106698:250::-;98462:3;;-1:-1:-1;;;;;98462:3:0;98469:10;98462:17;98454:57;;;;-1:-1:-1;;;98454:57:0;;18787:2:1;98454:57:0;;;18769:21:1;18826:2;18806:18;;;18799:30;18865:29;18845:18;;;18838:57;18912:18;;98454:57:0;18585:351:1;98454:57:0;106802:3:::1;::::0;:28:::1;::::0;-1:-1:-1;;;106802:28:0;;106824:4:::1;106802:28;::::0;::::1;738:51:1::0;-1:-1:-1;;;;;106802:3:0;;::::1;::::0;:13:::1;::::0;711:18:1;;106802:28:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;106788:11;:42;106780:79;;;::::0;-1:-1:-1;;;106780:79:0;;19143:2:1;106780:79:0::1;::::0;::::1;19125:21:1::0;19182:2;19162:18;;;19155:30;19221:26;19201:18;;;19194:54;19265:18;;106780:79:0::1;18941:348:1::0;106780:79:0::1;106870:3;::::0;106883::::1;::::0;106870:30:::1;::::0;-1:-1:-1;;;106870:30:0;;-1:-1:-1;;;;;106883:3:0;;::::1;106870:30;::::0;::::1;9001:51:1::0;9068:18;;;9061:34;;;106870:3:0;::::1;::::0;:12:::1;::::0;8974:18:1;;106870:30:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;106916:24:0::1;::::0;2918:25:1;;;106916:24:0::1;::::0;2906:2:1;2891:18;106916:24:0::1;2772:177:1::0;74541:104:0;74597:4;74621:16;74629:7;74621;:16::i;63863:233::-;63938:7;63974:30;63761:10;:17;;63673:113;63974:30;63966:5;:38;63958:95;;;;-1:-1:-1;;;63958:95:0;;19496:2:1;63958:95:0;;;19478:21:1;19535:2;19515:18;;;19508:30;19574:34;19554:18;;;19547:62;-1:-1:-1;;;19625:18:1;;;19618:42;19677:19;;63958:95:0;19294:408:1;63958:95:0;64071:10;64082:5;64071:17;;;;;;;;:::i;:::-;;;;;;;;;64064:24;;63863:233;;;:::o;79906:533::-;80030:7;;80077:10;;80073:306;;70298:5;;80182:19;:17;:19::i;:::-;:34;;;;:::i;:::-;:49;;;;:::i;:::-;80152:8;70688:3;80113:12;80122:3;80113:6;:12;:::i;:::-;:36;;;;:::i;:::-;:47;;;;:::i;:::-;80112:120;;;;:::i;:::-;80104:129;;80073:306;;;70298:5;80332:19;:17;:19::i;:::-;:34;;;;:::i;:::-;70688:3;80274:12;80283:3;80274:6;:12;:::i;:::-;:36;;;;:::i;:::-;80273:94;;;;:::i;:::-;80266:101;;80073:306;80403:28;;80396:35;;:4;:35;:::i;:::-;80389:42;;;79906:533;;;;;;:::o;88588:896::-;88648:7;88672:24;;;:15;:24;;;;;;:29;;:59;;;88706:25;88723:7;88706:16;:25::i;:::-;88705:26;88672:59;88668:100;;;-1:-1:-1;88755:1:0;;88588:896;-1:-1:-1;88588:896:0:o;88668:100::-;88778:20;88801:18;88811:7;88801:9;:18::i;:::-;88835:17;88900:24;;;:15;:24;;;;;;88778:41;;-1:-1:-1;88835:17:0;88856:106;;88778:41;88856:29;:106::i;:::-;88832:130;;;88975:16;89006:9;;88994;:21;;;;:::i;:::-;88975:40;-1:-1:-1;89048:13:0;89044:54;;-1:-1:-1;89085:1:0;;88588:896;-1:-1:-1;;;;88588:896:0:o;89044:54::-;89154:7;;89130:19;;89126:23;;:2;:23;:::i;:::-;89112:38;;89113:8;89112:38;:::i;:::-;:49;89108:369;;89307:28;;89284:19;:17;:19::i;:::-;70381:4;89256:9;;89242;:24;;;;:::i;:::-;89241:39;;;;:::i;:::-;:63;;;;:::i;:::-;:94;;;;:::i;:::-;89234:101;88588:896;-1:-1:-1;;;;;88588:896:0:o;89108:369::-;89437:28;;89414:19;:17;:19::i;:::-;70381:4;89388:9;;89376:8;:22;;;;:::i;80555:259::-;80627:10;;80594:7;;80661:14;80627:10;80674:1;80661:14;:::i;:::-;80648:10;:27;;;80694:16;-1:-1:-1;80694:16:0;80686:25;;;;;;80722:21;80728:10;80740:2;80722:5;:21::i;:::-;80759:27;;;20013:25:1;;;80775:10:0;20069:2:1;20054:18;;20047:60;80759:27:0;;19986:18:1;80759:27:0;;;;;;;80804:2;80555:259;-1:-1:-1;80555:259:0:o;106258:191::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;106334:8;106326:57:::1;;;::::0;-1:-1:-1;;;106326:57:0;;20320:2:1;106326:57:0::1;::::0;::::1;20302:21:1::0;20359:2;20339:18;;;20332:30;20398:34;20378:18;;;20371:62;-1:-1:-1;;;20449:18:1;;;20442:33;20492:19;;106326:57:0::1;20118:399:1::0;106326:57:0::1;106394:2;:8:::0;;;106418:23:::1;::::0;2918:25:1;;;106418:23:0::1;::::0;2906:2:1;2891:18;106418:23:0::1;2772:177:1::0;105416:325:0;105480:9;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23:::1;2175:68;;;;-1:-1:-1::0;;;2175:68:0::1;;;;;;;:::i;:::-;105520:18:::2;105528:9;105520:7;:18::i;:::-;105512:67;;;::::0;-1:-1:-1;;;105512:67:0;;20724:2:1;105512:67:0::2;::::0;::::2;20706:21:1::0;20763:2;20743:18;;;20736:30;20802:34;20782:18;;;20775:62;-1:-1:-1;;;20853:18:1;;;20846:34;20897:19;;105512:67:0::2;20522:400:1::0;105512:67:0::2;105620:1;105598:19:::0;;;:8:::2;:19;::::0;;;;;105590:67:::2;;;::::0;-1:-1:-1;;;105590:67:0;;21129:2:1;105590:67:0::2;::::0;::::2;21111:21:1::0;21168:2;21148:18;;;21141:30;21207:33;21187:18;;;21180:61;21258:18;;105590:67:0::2;20927:355:1::0;105590:67:0::2;105690:1;105668:19:::0;;;:8:::2;:19;::::0;;;;;:23;;;;105707:26;::::2;::::0;::::2;::::0;105677:9;2918:25:1;;2906:2;2891:18;;2772:177;101902:219:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;102056:7:::1;:18:::0;;;102090:23:::1;::::0;2918:25:1;;;102090:23:0::1;::::0;2906:2:1;2891:18;102090:23:0::1;2772:177:1::0;48458:239:0;48530:7;48566:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48566:16:0;48601:19;48593:73;;;;-1:-1:-1;;;48593:73:0;;21845:2:1;48593:73:0;;;21827:21:1;21884:2;21864:18;;;21857:30;21923:34;21903:18;;;21896:62;-1:-1:-1;;;21974:18:1;;;21967:39;22023:19;;48593:73:0;21643:405:1;102288:219:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;102442:7:::1;:18:::0;;;102476:23:::1;::::0;2918:25:1;;;102476:23:0::1;::::0;2906:2:1;2891:18;102476:23:0::1;2772:177:1::0;79079:429:0;79189:4;79226:31;79272:17;79303:48;79333:11;79346:4;79303:29;:48::i;:::-;79211:140;;-1:-1:-1;79211:140:0;-1:-1:-1;79364:28:0;79395:35;79211:140;;79395:35;:::i;:::-;79472:28;;-1:-1:-1;79448:52:0;;79079:429;-1:-1:-1;;;;;;79079:429:0:o;102708:183::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;102776:18:0;::::1;102768:63;;;::::0;-1:-1:-1;;;102768:63:0;;22611:2:1;102768:63:0::1;::::0;::::1;22593:21:1::0;;;22630:18;;;22623:30;22689:34;22669:18;;;22662:62;22741:18;;102768:63:0::1;22409:356:1::0;102768:63:0::1;102842:3;:10:::0;;-1:-1:-1;;;;;;102842:10:0::1;-1:-1:-1::0;;;;;102842:10:0;::::1;::::0;;::::1;::::0;;;102868:15:::1;::::0;738:51:1;;;102868:15:0::1;::::0;726:2:1;711:18;102868:15:0::1;592:203:1::0;103097:183:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;103167:18:0;::::1;103159:59;;;::::0;-1:-1:-1;;;103159:59:0;;22972:2:1;103159:59:0::1;::::0;::::1;22954:21:1::0;23011:2;22991:18;;;22984:30;23050;23030:18;;;23023:58;23098:18;;103159:59:0::1;22770:352:1::0;103159:59:0::1;103229:3;:10:::0;;-1:-1:-1;;;;;;103229:10:0::1;-1:-1:-1::0;;;;;103229:10:0;::::1;::::0;;::::1;::::0;;;103255:17:::1;::::0;738:51:1;;;103255:17:0::1;::::0;726:2:1;711:18;103255:17:0::1;592:203:1::0;48188:208:0;48260:7;-1:-1:-1;;;;;48288:19:0;;48280:74;;;;-1:-1:-1;;;48280:74:0;;23329:2:1;48280:74:0;;;23311:21:1;23368:2;23348:18;;;23341:30;23407:34;23387:18;;;23380:62;-1:-1:-1;;;23458:18:1;;;23451:40;23508:19;;48280:74:0;23127:406:1;48280:74:0;-1:-1:-1;;;;;;48372:16:0;;;;;:9;:16;;;;;;;48188:208::o;2614:103::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;2679:30:::1;2706:1;2679:18;:30::i;:::-;2614:103::o:0;82576:775::-;82679:7;73474:16;73482:7;73474;:16::i;:::-;73466:49;;;;-1:-1:-1;;;73466:49:0;;;;;;;:::i;:::-;73554:10;73534:16;73542:7;73534;:16::i;:::-;-1:-1:-1;;;;;73534:30:0;;73526:68;;;;-1:-1:-1;;;73526:68:0;;;;;;;:::i;:::-;34324:1:::1;34922:7;;:19;;34914:63;;;;-1:-1:-1::0;;;34914:63:0::1;;;;;;;:::i;:::-;34324:1;35055:7;:18:::0;;;82748:24;;;:15:::2;:24;::::0;;;;;:34;-1:-1:-1;82748:34:0::2;82726:121;;;::::0;-1:-1:-1;;;82726:121:0;;24094:2:1;82726:121:0::2;::::0;::::2;24076:21:1::0;24133:2;24113:18;;;24106:30;24172:34;24152:18;;;24145:62;-1:-1:-1;;;24223:18:1;;;24216:35;24268:19;;82726:121:0::2;23892:401:1::0;82726:121:0::2;82860:21;82884:24:::0;;;:15:::2;:24;::::0;;;;;:33:::2;::::0;82911:6;;82884:33:::2;:::i;:::-;82860:57;;82928:12;82943:24;82959:7;82943:15;:24::i;:::-;82928:39:::0;-1:-1:-1;82984:9:0;;82980:204:::2;;83036:38;83054:13;83069:4;83036:17;:38::i;:::-;83010:162;;;::::0;-1:-1:-1;;;83010:162:0;;24500:2:1;83010:162:0::2;::::0;::::2;24482:21:1::0;24539:2;24519:18;;;24512:30;24578:34;24558:18;;;24551:62;24649:32;24629:18;;;24622:60;24699:19;;83010:162:0::2;24298:426:1::0;83010:162:0::2;83196:24;::::0;;;:15:::2;:24;::::0;;;;:40;;;83247:10:::2;::::0;:43:::2;::::0;-1:-1:-1;;;;;83247:10:0::2;83271;83283:6:::0;83247:23:::2;:43::i;:::-;83308:35;::::0;;12410:25:1;;;12466:2;12451:18;;12444:34;;;83308:35:0::2;::::0;12383:18:1;83308:35:0::2;;;;;;;-1:-1:-1::0;;34280:1:0::1;35234:7;:22:::0;-1:-1:-1;;;82576:775:0:o;80992:578::-;81073:7;73474:16;73482:7;73474;:16::i;:::-;73466:49;;;;-1:-1:-1;;;73466:49:0;;;;;;;:::i;:::-;73554:10;73534:16;73542:7;73534;:16::i;:::-;-1:-1:-1;;;;;73534:30:0;;73526:68;;;;-1:-1:-1;;;73526:68:0;;;;;;;:::i;:::-;34324:1:::1;34922:7;;:19;;34914:63;;;;-1:-1:-1::0;;;34914:63:0::1;;;;;;;:::i;:::-;34324:1;35055:7;:18:::0;81128::::2;81138:7:::0;81128:9:::2;:18::i;:::-;:23:::0;81120:62:::2;;;::::0;-1:-1:-1;;;81120:62:0;;24931:2:1;81120:62:0::2;::::0;::::2;24913:21:1::0;24970:2;24950:18;;;24943:30;25009:28;24989:18;;;24982:56;25055:18;;81120:62:0::2;24729:350:1::0;81120:62:0::2;81199:24;::::0;;;:15:::2;:24;::::0;;;;;:29;81195:174:::2;;81290:67;81314:16;81322:7;81314;:16::i;:::-;81332:24;::::0;;;:15:::2;:24;::::0;;;;;81290:10:::2;::::0;-1:-1:-1;;;;;81290:10:0::2;::::0;:67;:23:::2;:67::i;:::-;81381:14;81387:7;81381:5;:14::i;:::-;81415:24;::::0;;;:15:::2;:24;::::0;;;;;;;81408:31;;;81457:20:::2;:29:::0;;;;;81450:36;;;81504:12:::2;:21:::0;;;;;81497:28;;;;81541:21;;2918:25:1;;;81541:21:0::2;::::0;2891:18:1;81541:21:0::2;;;;;;;-1:-1:-1::0;;34280:1:0::1;35234:7;:22:::0;80992:578::o;103457:277::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;96663:3:::1;103559:11;:22;;103531:92;;;::::0;-1:-1:-1;;;103531:92:0;;25286:2:1;103531:92:0::1;::::0;::::1;25268:21:1::0;25325:2;25305:18;;;25298:30;25364:34;25344:18;;;25337:62;-1:-1:-1;;;25415:18:1;;;25408:35;25460:19;;103531:92:0::1;25084:401:1::0;103531:92:0::1;103634:10;:24:::0;;;103697:29:::1;::::0;2918:25:1;;;103697:29:0::1;::::0;2906:2:1;2891:18;103697:29:0::1;2772:177:1::0;94373:1930:0;94454:7;94437;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1;;;73671:49:0;;;;;;;:::i;:::-;94482:20:::1;94505:24;94521:7;94505:15;:24::i;:::-;94482:47:::0;-1:-1:-1;94550:17:0;94542:45:::1;;;::::0;-1:-1:-1;;;94542:45:0;;25692:2:1;94542:45:0::1;::::0;::::1;25674:21:1::0;25731:2;25711:18;;;25704:30;-1:-1:-1;;;25750:18:1;;;25743:45;25805:18;;94542:45:0::1;25490:339:1::0;94542:45:0::1;94615:31;94740:24:::0;;;:15:::1;:24;::::0;;;;;94615:31;;94692:118:::1;::::0;94783:12;94692:29:::1;:118::i;:::-;94600:210:::0;;-1:-1:-1;94600:210:0;-1:-1:-1;94823:28:0::1;94854:37;94600:210:::0;;94854:37:::1;:::i;:::-;94953:9;::::0;94823:68;;-1:-1:-1;94925:23:0::1;94823:68:::0;94946:2:::1;94925:23;:::i;:::-;94924:38;;94902:135;;;::::0;-1:-1:-1;;;94902:135:0;;26036:2:1;94902:135:0::1;::::0;::::1;26018:21:1::0;26075:2;26055:18;;;26048:30;26114:34;26094:18;;;26087:62;-1:-1:-1;;;26165:18:1;;;26158:44;26219:19;;94902:135:0::1;25834:410:1::0;94902:135:0::1;95050:23;95259:19;;95255:2;:23;;;;:::i;:::-;95223:28;;:56;;;;:::i;:::-;95157:123;::::0;:23;:123:::1;:::i;:::-;95094:19;::::0;95090:23:::1;::::0;:2:::1;:23;:::i;:::-;95077:37;::::0;:9;:37:::1;:::i;:::-;95076:205;;;;:::i;:::-;95370:3;::::0;:25:::1;::::0;-1:-1:-1;;;95370:25:0;;95384:10:::1;95370:25;::::0;::::1;738:51:1::0;95050:231:0;;-1:-1:-1;95050:231:0;;-1:-1:-1;;;;;95370:3:0;;::::1;::::0;:13:::1;::::0;711:18:1;;95370:25:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;95362:94;;;::::0;-1:-1:-1;;;95362:94:0;;26451:2:1;95362:94:0::1;::::0;::::1;26433:21:1::0;26490:2;26470:18;;;26463:30;26529:34;26509:18;;;26502:62;-1:-1:-1;;;26580:18:1;;;26573:35;26625:19;;95362:94:0::1;26249:401:1::0;95362:94:0::1;95482:3;::::0;:64:::1;::::0;-1:-1:-1;;;;;95482:3:0::1;95503:10;95523:4;95530:15:::0;95482:20:::1;:64::i;:::-;95590:15;95573:13;;:33;;;;:::i;:::-;95557:13;:49:::0;95653:16:::1;95672:13;:11;:13::i;:::-;95811:24;::::0;;;:15:::1;:24;::::0;;;;;;95783:25;;;;;:52;95653:32;-1:-1:-1;95879:30:0::1;95894:15:::0;95879:12;:30:::1;:::i;:::-;95846;::::0;;;:20:::1;:30;::::0;;;;;;;:63;;;;95920:12:::1;:22:::0;;;;;95945:15:::1;95920:40:::0;;96023:24;;;:15:::1;:24:::0;;;;;96016:31;;;96065:29;;;;;;96058:36;;;;96199:68;;26886:25:1;;;26927:18;;;26920:34;;;96239:10:0::1;26970:18:1::0;;;26963:60;27054:2;27039:18;;27032:34;;;96199:68:0;;::::1;::::0;;;;26873:3:1;96199:68:0;;::::1;96285:8:::0;-1:-1:-1;;;;;;73731:1:0::1;94373:1930:::0;;;;:::o;77290:417::-;77348:7;77369:11;77382:12;77398:25;77415:7;77398:16;:25::i;:::-;77368:55;;;;77456:3;77446:7;;:13;;;;:::i;:::-;77436:7;:23;77488:13;;:19;;77504:3;;77488:19;:::i;:::-;77472:13;:35;;;77520:21;;;;:12;:21;;;;;;77544:15;77520:39;;77639:20;:29;;;;;;:36;;;-1:-1:-1;77671:4:0;;77290:417;-1:-1:-1;77290:417:0:o;74193:110::-;74267:3;;:28;;-1:-1:-1;;;74267:28:0;;74289:4;74267:28;;;738:51:1;74240:7:0;;-1:-1:-1;;;;;74267:3:0;;:13;;711:18:1;;74267:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74260:35;;74193:110;:::o;91564:2349::-;91660:6;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;91689:7:::1;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1::0;;;73671:49:0::1;;;;;;;:::i;:::-;91736:13:::2;::::0;-1:-1:-1;;;;;91736:13:0::2;:27:::0;;:58:::2;;-1:-1:-1::0;91781:13:0::2;::::0;-1:-1:-1;;;;;91781:13:0::2;91767:10;:27;91736:58;91714:142;;;::::0;-1:-1:-1;;;91714:142:0;;27279:2:1;91714:142:0::2;::::0;::::2;27261:21:1::0;27318:2;27298:18;;;27291:30;27357:34;27337:18;;;27330:62;-1:-1:-1;;;27408:18:1;;;27401:32;27450:19;;91714:142:0::2;27077:398:1::0;91714:142:0::2;91869:20;91892:24;91908:7;91892:15;:24::i;:::-;91942:31;92067:24:::0;;;:15:::2;:24;::::0;;;;;91869:47;;-1:-1:-1;91942:31:0;;;92019:118:::2;::::0;91869:47;92019:29:::2;:118::i;:::-;91927:210;;;;92156:12;92172:1;92156:17;;92148:45;;;::::0;-1:-1:-1;;;92148:45:0;;25692:2:1;92148:45:0::2;::::0;::::2;25674:21:1::0;25731:2;25711:18;;;25704:30;-1:-1:-1;;;25750:18:1;;;25743:45;25805:18;;92148:45:0::2;25490:339:1::0;92148:45:0::2;92206:28;92237:37;92264:9:::0;92237:23;:37:::2;:::i;:::-;92206:68;;92332:28;;92309:20;:51;92287:149;;;::::0;-1:-1:-1;;;92287:149:0;;27682:2:1;92287:149:0::2;::::0;::::2;27664:21:1::0;27721:2;27701:18;;;27694:30;27760:34;27740:18;;;27733:62;-1:-1:-1;;;27811:18:1;;;27804:46;27867:19;;92287:149:0::2;27480:412:1::0;92287:149:0::2;92485:9;::::0;92457:25:::2;:20:::0;92480:2:::2;92457:25;:::i;:::-;:37;92449:80;;;::::0;-1:-1:-1;;;92449:80:0;;28099:2:1;92449:80:0::2;::::0;::::2;28081:21:1::0;28138:2;28118:18;;;28111:30;28177:31;28157:18;;;28150:59;28226:18;;92449:80:0::2;27897:353:1::0;92449:80:0::2;92571:19;::::0;92567:23:::2;::::0;:2:::2;:23;:::i;:::-;92554:37;::::0;:9;:37:::2;:::i;:::-;92542:49;;92604:16;92636:9;;92623;:23;;;;:::i;:::-;92604:42;;92691:7;;92679:8;:19;92675:72;;-1:-1:-1::0;92726:9:0;92675:72:::2;92781:3;::::0;:25:::2;::::0;-1:-1:-1;;;92781:25:0;;92795:10:::2;92781:25;::::0;::::2;738:51:1::0;92810:8:0;;-1:-1:-1;;;;;92781:3:0::2;::::0;:13:::2;::::0;711:18:1;;92781:25:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;92759:136;;;::::0;-1:-1:-1;;;92759:136:0;;28457:2:1;92759:136:0::2;::::0;::::2;28439:21:1::0;28496:2;28476:18;;;28469:30;28535:34;28515:18;;;28508:62;-1:-1:-1;;;28586:18:1;;;28579:47;28643:19;;92759:136:0::2;28255:413:1::0;92759:136:0::2;92941:8;92924:13;;:26;;;;:::i;:::-;92908:13;:42:::0;92963:20:::2;92986:21;92999:7:::0;92986:12:::2;:21::i;:::-;92963:44:::0;-1:-1:-1;93052:25:0::2;93068:8:::0;93052:12;:25:::2;:::i;:::-;93020:29;::::0;;;:20:::2;:29;::::0;;;;;;;:57;;;;93159:10:::2;::::0;93181:16;;;:8:::2;:16:::0;;;;;;;93020:29;;93146:52:::2;::::0;93171:8;;93146:12:::2;:52::i;:::-;93236:24;::::0;;;:15:::2;:24;::::0;;;;;93124:74;;-1:-1:-1;93236:40:0::2;::::0;93124:74;;93236:40:::2;:::i;:::-;93209:24;::::0;;;:15:::2;:24;::::0;;;;;:67;;;;93313:23;;;;;:39:::2;::::0;93340:11;;93313:39:::2;:::i;:::-;93287:23;::::0;;;:15:::2;:23;::::0;;;;;:65;;;;93460:24;;;;;:41:::2;::::0;93488:12;;93460:41:::2;:::i;:::-;93433:24;::::0;;;:15:::2;:24;::::0;;;;;;;:68;;;;93595:10:::2;93585:21:::0;;:9:::2;:21:::0;;;;:38:::2;::::0;93610:12;;93585:38:::2;:::i;:::-;93571:10;93561:21;::::0;;;:9:::2;:21;::::0;;;;:62;;;;93651:3:::2;::::0;:57:::2;::::0;-1:-1:-1;;;;;93651:3:0;;::::2;::::0;93692:4:::2;93699:8:::0;93651:20:::2;:57::i;:::-;93726:179;93755:7;93777:16;93785:7;93777;:16::i;:::-;93726:179;::::0;;28960:25:1;;;-1:-1:-1;;;;;29059:15:1;;;29054:2;29039:18;;29032:43;93808:10:0::2;29091:18:1::0;;;29084:43;29158:2;29143:18;;29136:34;;;29201:3;29186:19;;29179:35;;;29012:3;29230:19;;29223:35;;;28947:3;28932:19;93726:179:0::2;;;;;;;91703:2210;;;;;;;73968:1:::1;91564:2349:::0;;;:::o;48933:104::-;48989:13;49022:7;49015:14;;;;;:::i;83712:1365::-;83843:6;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;83872:7:::1;73474:16;73482:7;73474;:16::i;:::-;73466:49;;;;-1:-1:-1::0;;;73466:49:0::1;;;;;;;:::i;:::-;73554:10;73534:16;73542:7:::0;73534::::1;:16::i;:::-;-1:-1:-1::0;;;;;73534:30:0::1;;73526:68;;;;-1:-1:-1::0;;;73526:68:0::1;;;;;;;:::i;:::-;34324:1:::2;34922:7;;:19;;34914:63;;;;-1:-1:-1::0;;;34914:63:0::2;;;;;;;:::i;:::-;34324:1;35055:7;:18:::0;83926:10;83918:50:::3;;;::::0;-1:-1:-1;;;83918:50:0;;29471:2:1;83918:50:0::3;::::0;::::3;29453:21:1::0;29510:2;29490:18;;;29483:30;29549:29;29529:18;;;29522:57;29596:18;;83918:50:0::3;29269:351:1::0;83918:50:0::3;84011:16;:14;:16::i;:::-;84001:6;:26;;83979:123;;;::::0;-1:-1:-1;;;83979:123:0;;29827:2:1;83979:123:0::3;::::0;::::3;29809:21:1::0;29866:2;29846:18;;;29839:30;29905:34;29885:18;;;29878:62;-1:-1:-1;;;29956:18:1;;;29949:45;30011:19;;83979:123:0::3;29625:411:1::0;83979:123:0::3;84115:15;84160:6;84133:24;84149:7;84133:15;:24::i;:::-;:33;;;;:::i;:::-;84115:51;;84196:7;;84187;:16;;84179:63;;;::::0;-1:-1:-1;;;84179:63:0;;30243:2:1;84179:63:0::3;::::0;::::3;30225:21:1::0;30282:2;30262:18;;;30255:30;30321:34;30301:18;;;30294:62;-1:-1:-1;;;30372:18:1;;;30365:32;30414:19;;84179:63:0::3;30041:398:1::0;84179:63:0::3;84273:18;84283:7;84273:9;:18::i;:::-;84263:7;:28;84255:37;;;::::0;::::3;;84347:24;::::0;;;:15:::3;:24;::::0;;;;;84329:52:::3;::::0;84373:7;84329:17:::3;:52::i;:::-;84307:160;;;::::0;-1:-1:-1;;;84307:160:0;;30646:2:1;84307:160:0::3;::::0;::::3;30628:21:1::0;30685:2;30665:18;;;30658:30;30724:34;30704:18;;;30697:62;30795:28;30775:18;;;30768:56;30841:19;;84307:160:0::3;30444:422:1::0;84307:160:0::3;84537:7;;84526:6;84504:18;84514:7;84504:9;:18::i;:::-;84503:29;;;;:::i;:::-;84502:42;;84480:125;;;;-1:-1:-1::0;;;84480:125:0::3;;;;;;;:::i;:::-;84618:29;::::0;;;:20:::3;:29;::::0;;;;;;;:39;;;84705:10:::3;::::0;84726:16;;;:8:::3;:16:::0;;;;;;84692:51:::3;::::0;84705:10;84650:7;;84692:12:::3;:51::i;:::-;84783:24;::::0;;;:15:::3;:24;::::0;;;;;84670:73;;-1:-1:-1;84783:40:0::3;::::0;84670:73;;84783:40:::3;:::i;:::-;84756:24;::::0;;;:15:::3;:24;::::0;;;;;:67;;;;84860:23;;;;;:39:::3;::::0;84887:11;;84860:39:::3;:::i;:::-;84834:23;::::0;;;:15:::3;:23;::::0;;;;:65;84936:3:::3;::::0;:36:::3;::::0;-1:-1:-1;;;;;84936:3:0::3;84953:10;84965:6:::0;84936:16:::3;:36::i;:::-;85016:6;84999:13;;:24;;;;:::i;:::-;84983:13;:40:::0;;;85041:28:::3;::::0;;12410:25:1;;;12451:18;;;12444:34;;;85041:28:0::3;::::0;12383:18:1;85041:28:0::3;;;;;;;-1:-1:-1::0;;34280:1:0::2;35234:7;:22:::0;-1:-1:-1;;;;;83712:1365:0:o;75708:114::-;75785:14;;:29;;;-1:-1:-1;;;75785:29:0;;;;75758:7;;-1:-1:-1;;;;;75785:14:0;;:27;;:29;;;;;;;;;;;;;;:14;:29;;;;;;;;;;;;;;100497:231;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;100576:19:0;::::1;100568:69;;;::::0;-1:-1:-1;;;100568:69:0;;31073:2:1;100568:69:0::1;::::0;::::1;31055:21:1::0;31112:2;31092:18;;;31085:30;31151:34;31131:18;;;31124:62;-1:-1:-1;;;31202:18:1;;;31195:34;31246:19;;100568:69:0::1;30871:400:1::0;100568:69:0::1;100648:13;:21:::0;;-1:-1:-1;;;;;;100648:21:0::1;-1:-1:-1::0;;;;;100648:21:0;::::1;::::0;;::::1;::::0;;;100685:35:::1;::::0;738:51:1;;;100685:35:0::1;::::0;726:2:1;711:18;100685:35:0::1;592:203:1::0;50617:155:0;50712:52;763:10;50745:8;50755;50712:18;:52::i;:::-;50617:155;;:::o;98684:149::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;98763:20;;::::1;::::0;:10:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;;98799:26;98817:7;98799:26;;;;;;:::i;74795:252::-:0;74931:10;;:35;;-1:-1:-1;;;74931:35:0;;74960:4;74931:35;;;738:51:1;74849:7:0;;-1:-1:-1;;;;;74931:10:0;;:20;;711:18:1;;74931:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74900:28;;74878:19;:17;:19::i;:::-;:50;;;;:::i;:::-;:88;;;;:::i;90414:753::-;90535:4;90508:7;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1;;;73671:49:0;;;;;;;:::i;:::-;90557:20:::1;90580:18;90590:7;90580:9;:18::i;:::-;90615:24;::::0;;;:15:::1;:24;::::0;;;;;90557:41;;-1:-1:-1;90615:29:0;;:50:::1;;-1:-1:-1::0;90648:17:0;;90615:50:::1;90611:95;;;90689:5;90682:12;;;;;90611:95;90733:31;90858:24:::0;;;:15:::1;:24;::::0;;;;;90733:31;;90810:118:::1;::::0;90901:12;90810:29:::1;:118::i;:::-;90718:210:::0;;-1:-1:-1;90718:210:0;-1:-1:-1;90941:28:0::1;90972:37;90718:210:::0;;90972:37:::1;:::i;:::-;90941:68;;91047:28;;91024:20;:51;91020:140;;;91099:4;91092:11;;;;;;;;91020:140;91143:5;91136:12;;;;;;;;51740:328:::0;51915:41;763:10;51948:7;51915:18;:41::i;:::-;51907:103;;;;-1:-1:-1;;;51907:103:0;;;;;;;:::i;:::-;52021:39;52035:4;52041:2;52045:7;52054:5;52021:13;:39::i;:::-;51740:328;;;;:::o;69879:147::-;69944:13;69978:16;69986:7;69978;:16::i;:::-;69970:25;;;;;;70015:3;70008:10;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69879:147;;;:::o;104973:311::-;105055:9;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;105081:9:::1;73474:16;73482:7;73474;:16::i;:::-;73466:49;;;;-1:-1:-1::0;;;73466:49:0::1;;;;;;;:::i;:::-;73554:10;73534:16;73542:7:::0;73534::::1;:16::i;:::-;-1:-1:-1::0;;;;;73534:30:0::1;;73526:68;;;;-1:-1:-1::0;;;73526:68:0::1;;;;;;;:::i;:::-;105122:1:::2;105111:8;:12;:40;;;;;70298:5;105127:8;:24;;105111:40;105103:80;;;::::0;-1:-1:-1;;;105103:80:0;;31478:2:1;105103:80:0::2;::::0;::::2;31460:21:1::0;31517:2;31497:18;;;31490:30;31556:29;31536:18;;;31529:57;31603:18;;105103:80:0::2;31276:351:1::0;105103:80:0::2;105194:19;::::0;;;:8:::2;:19;::::0;;;;;;;;:30;;;105240:36;;12410:25:1;;;12451:18;;;12444:34;;;105240:36:0::2;::::0;12383:18:1;105240:36:0::2;;;;;;;;73968:1:::1;104973:311:::0;;;:::o;87072:266::-;34324:1;34922:7;;:19;;34914:63;;;;-1:-1:-1;;;34914:63:0;;;;;;;:::i;:::-;34324:1;35055:7;:18;;;87142:10:::1;87132:21:::0;;:9:::1;:21;::::0;;;;;87124:67:::1;;;::::0;-1:-1:-1;;;87124:67:0;;31834:2:1;87124:67:0::1;::::0;::::1;31816:21:1::0;31873:2;31853:18;;;31846:30;31912;31892:18;;;31885:58;31960:18;;87124:67:0::1;31632:352:1::0;87124:67:0::1;87229:10;87202:14;87219:21:::0;;;:9:::1;:21;::::0;;;;;;87251:25;;;87287:10:::1;::::0;87219:21;;87287:43:::1;::::0;-1:-1:-1;;;;;87287:10:0::1;::::0;87219:21;87287:23:::1;:43::i;:::-;-1:-1:-1::0;34280:1:0;35234:7;:22;87072:266::o;85085:392::-;85216:6;73805:16;73813:7;73805;:16::i;:::-;73797:59;;;;-1:-1:-1;;;73797:59:0;;;;;;;:::i;:::-;73875:17;;;;:8;:17;;;;;;70298:5;-1:-1:-1;73875:33:0;;;:58;;-1:-1:-1;73932:1:0;73912:17;;;:8;:17;;;;;;:21;;73875:58;73867:90;;;;-1:-1:-1;;;73867:90:0;;;;;;;:::i;:::-;85236:7:::1;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1::0;;;73671:49:0::1;;;;;;;:::i;:::-;85290:15:::2;85278:8;:27;;85256:111;;;::::0;-1:-1:-1;;;85256:111:0;;32191:2:1;85256:111:0::2;::::0;::::2;32173:21:1::0;32230:2;32210:18;;;32203:30;32269:34;32249:18;;;32242:62;-1:-1:-1;;;32320:18:1;;;32313:32;32362:19;;85256:111:0::2;31989:398:1::0;85256:111:0::2;85378:15;85396:24;85412:7;85396:15;:24::i;:::-;85378:42;;85431:38;85444:7;85453;85462:6;85431:12;:38::i;:::-;85245:232;73968:1:::1;85085:392:::0;;;;:::o;76933:151::-;76990:7;77013:12;77029:25;77046:7;77029:16;:25::i;89634:585::-;89764:7;89737;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1;;;73671:49:0;;;;;;;:::i;:::-;89789:20:::1;89812:18;89822:7;89812:9;:18::i;:::-;89847:24;::::0;;;:15:::1;:24;::::0;;;;;89789:41;;-1:-1:-1;89847:29:0;;:50:::1;;-1:-1:-1::0;89880:17:0;;89847:50:::1;89843:91;;;89921:1;89914:8;;;;;89843:91;89959:31;90084:24:::0;;;:15:::1;:24;::::0;;;;;89959:31;;90036:118:::1;::::0;90127:12;90036:29:::1;:118::i;:::-;89944:210:::0;;-1:-1:-1;89944:210:0;-1:-1:-1;90174:37:0::1;89944:210:::0;;90174:37:::1;:::i;:::-;90167:44:::0;89634:585;-1:-1:-1;;;;;;89634:585:0:o;107092:127::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;107165:10:::1;:3;107171:4:::0;;107165:10:::1;:::i;:::-;;107191:20;107207:3;107191:20;;;;;;:::i;69339:17::-:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;99455:205::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;99535:9:::1;::::0;99527:49:::1;;;::::0;-1:-1:-1;;;99527:49:0;;33911:2:1;99527:49:0::1;::::0;::::1;33893:21:1::0;33950:2;33930:18;;;33923:30;-1:-1:-1;;;33969:18:1;;;33962:52;34031:18;;99527:49:0::1;33709:346:1::0;99527:49:0::1;99587:9;:22:::0;;;99625:27:::1;::::0;2918:25:1;;;99625:27:0::1;::::0;2906:2:1;2891:18;99625:27:0::1;2772:177:1::0;81848:434:0;81947:7;73679:16;73687:7;73679;:16::i;:::-;73671:49;;;;-1:-1:-1;;;73671:49:0;;;;;;;:::i;:::-;81972:21:::1;81996:24:::0;;;:15:::1;:24;::::0;;;;;:35:::1;::::0;82024:6;;81996:35:::1;:::i;:::-;82069:24;::::0;;;:15:::1;:24;::::0;;;;;81972:59;;-1:-1:-1;82052:41:0;::::1;;82044:50;;;::::0;::::1;;82107:24;::::0;;;:15:::1;:24;::::0;;;;:40;;;82160:10:::1;::::0;:62:::1;::::0;-1:-1:-1;;;;;82160:10:0::1;82188;82208:4;82215:6:::0;82160:27:::1;:62::i;:::-;82240:34;::::0;;12410:25:1;;;12466:2;12451:18;;12444:34;;;82240::0::1;::::0;12383:18:1;82240:34:0::1;12236:248:1::0;2872:201:0;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;2961:22:0;::::1;2953:73;;;::::0;-1:-1:-1;;;2953:73:0;;34262:2:1;2953:73:0::1;::::0;::::1;34244:21:1::0;34301:2;34281:18;;;34274:30;34340:34;34320:18;;;34313:62;-1:-1:-1;;;34391:18:1;;;34384:36;34437:19;;2953:73:0::1;34060:402:1::0;2953:73:0::1;3037:28;3056:8;3037:18;:28::i;:::-;2872:201:::0;:::o;99030:233::-;2036:6;;-1:-1:-1;;;;;2036:6:0;763:10;2183:23;2175:68;;;;-1:-1:-1;;;2175:68:0;;;;;;;:::i;:::-;99124:4:::1;99110:10;:18;;99102:77;;;::::0;-1:-1:-1;;;99102:77:0;;34669:2:1;99102:77:0::1;::::0;::::1;34651:21:1::0;34708:2;34688:18;;;34681:30;34747:34;34727:18;;;34720:62;-1:-1:-1;;;34798:18:1;;;34791:44;34852:19;;99102:77:0::1;34467:410:1::0;99102:77:0::1;99190:9;:22:::0;;;99228:27:::1;::::0;2918:25:1;;;99228:27:0::1;::::0;2906:2:1;2891:18;99228:27:0::1;2772:177:1::0;64709:589:0;-1:-1:-1;;;;;64915:18:0;;64911:187;;64950:40;64982:7;66125:10;:17;;66098:24;;;;:15;:24;;;;;:44;;;66153:24;;;;;;;;;;;;66021:164;64950:40;64911:187;;;65020:2;-1:-1:-1;;;;;65012:10:0;:4;-1:-1:-1;;;;;65012:10:0;;65008:90;;65039:47;65072:4;65078:7;65039:32;:47::i;:::-;-1:-1:-1;;;;;65112:16:0;;65108:183;;65145:45;65182:7;65145:36;:45::i;65108:183::-;65218:4;-1:-1:-1;;;;;65212:10:0;:2;-1:-1:-1;;;;;65212:10:0;;65208:83;;65239:40;65267:2;65271:7;65239:27;:40::i;63033:224::-;63135:4;-1:-1:-1;;;;;;63159:50:0;;-1:-1:-1;;;63159:50:0;;:90;;;63213:36;63237:11;63213:23;:36::i;53578:127::-;53643:4;53667:16;;;:7;:16;;;;;;-1:-1:-1;;;;;53667:16:0;:30;;;53578:127::o;57724:174::-;57799:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;57799:29:0;-1:-1:-1;;;;;57799:29:0;;;;;;;;:24;;57853:23;57799:24;57853:14;:23::i;:::-;-1:-1:-1;;;;;57844:46:0;;;;;;;;;;;57724:174;;:::o;78070:713::-;78194:7;78203;78236:19;:17;:19::i;:::-;78228:33;;;;;;78320:23;78408:28;;78373:19;:17;:19::i;:::-;78346:46;;:11;:46;:::i;:::-;:90;;;;:::i;:::-;78320:116;;78476:11;78457:15;:30;;78449:39;;;;;;78501:17;78521:29;70688:3;78521:5;:29;:::i;:::-;78501:49;;78584:5;78571:9;:18;;78563:27;;;;;;78603:31;78637:21;:15;78655:3;78637:21;:::i;:::-;78603:55;;78703:15;78677:23;:41;78669:50;;;;;;78740:23;78765:9;;-1:-1:-1;78070:713:0;-1:-1:-1;;;;78070:713:0:o;53872:348::-;53965:4;53990:16;53998:7;53990;:16::i;:::-;53982:73;;;;-1:-1:-1;;;53982:73:0;;35084:2:1;53982:73:0;;;35066:21:1;35123:2;35103:18;;;35096:30;35162:34;35142:18;;;35135:62;-1:-1:-1;;;35213:18:1;;;35206:42;35265:19;;53982:73:0;34882:408:1;53982:73:0;54066:13;54082:23;54097:7;54082:14;:23::i;:::-;54066:39;;54135:5;-1:-1:-1;;;;;54124:16:0;:7;-1:-1:-1;;;;;54124:16:0;;:52;;;-1:-1:-1;;;;;;50964:25:0;;;50940:4;50964:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;54144:32;54124:87;;;;54204:7;-1:-1:-1;;;;;54180:31:0;:20;54192:7;54180:11;:20::i;:::-;-1:-1:-1;;;;;54180:31:0;;54116:96;53872:348;-1:-1:-1;;;;53872:348:0:o;56981:625::-;57140:4;-1:-1:-1;;;;;57113:31:0;:23;57128:7;57113:14;:23::i;:::-;-1:-1:-1;;;;;57113:31:0;;57105:81;;;;-1:-1:-1;;;57105:81:0;;35497:2:1;57105:81:0;;;35479:21:1;35536:2;35516:18;;;35509:30;35575:34;35555:18;;;35548:62;-1:-1:-1;;;35626:18:1;;;35619:35;35671:19;;57105:81:0;35295:401:1;57105:81:0;-1:-1:-1;;;;;57205:16:0;;57197:65;;;;-1:-1:-1;;;57197:65:0;;35903:2:1;57197:65:0;;;35885:21:1;35942:2;35922:18;;;35915:30;35981:34;35961:18;;;35954:62;-1:-1:-1;;;36032:18:1;;;36025:34;36076:19;;57197:65:0;35701:400:1;57197:65:0;57275:39;57296:4;57302:2;57306:7;57275:20;:39::i;:::-;57379:29;57396:1;57400:7;57379:8;:29::i;:::-;-1:-1:-1;;;;;57421:15:0;;;;;;:9;:15;;;;;:20;;57440:1;;57421:15;:20;;57440:1;;57421:20;:::i;:::-;;;;-1:-1:-1;;;;;;;57452:13:0;;;;;;:9;:13;;;;;:18;;57469:1;;57452:13;:18;;57469:1;;57452:18;:::i;:::-;;;;-1:-1:-1;;57481:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;57481:21:0;-1:-1:-1;;;;;57481:21:0;;;;;;;;;57520:27;;57481:16;;57520:27;;;;;;;49917:341;49847:411;;:::o;15745:248::-;15916:68;;-1:-1:-1;;;;;36364:15:1;;;15916:68:0;;;36346:34:1;36416:15;;36396:18;;;36389:43;36448:18;;;36441:34;;;15889:96:0;;15909:5;;-1:-1:-1;;;15939:27:0;36281:18:1;;15916:68:0;;;;-1:-1:-1;;15916:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;15916:68:0;-1:-1:-1;;;;;;15916:68:0;;;;;;;;;;15889:19;:96::i;55556:439::-;-1:-1:-1;;;;;55636:16:0;;55628:61;;;;-1:-1:-1;;;55628:61:0;;36688:2:1;55628:61:0;;;36670:21:1;;;36707:18;;;36700:30;36766:34;36746:18;;;36739:62;36818:18;;55628:61:0;36486:356:1;55628:61:0;55709:16;55717:7;55709;:16::i;:::-;55708:17;55700:58;;;;-1:-1:-1;;;55700:58:0;;37049:2:1;55700:58:0;;;37031:21:1;37088:2;37068:18;;;37061:30;37127;37107:18;;;37100:58;37175:18;;55700:58:0;36847:352:1;55700:58:0;55771:45;55800:1;55804:2;55808:7;55771:20;:45::i;:::-;-1:-1:-1;;;;;55829:13:0;;;;;;:9;:13;;;;;:18;;55846:1;;55829:13;:18;;55846:1;;55829:18;:::i;:::-;;;;-1:-1:-1;;55858:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;55858:21:0;-1:-1:-1;;;;;55858:21:0;;;;;;;;55897:33;;55858:16;;;55897:33;;55858:16;;55897:33;50617:155;;:::o;3233:191::-;3326:6;;;-1:-1:-1;;;;;3343:17:0;;;-1:-1:-1;;;;;;3343:17:0;;;;;;;3376:40;;3326:6;;;3343:17;3326:6;;3376:40;;3307:16;;3376:40;3296:128;3233:191;:::o;15526:211::-;15670:58;;-1:-1:-1;;;;;9019:32:1;;15670:58:0;;;9001:51:1;9068:18;;;9061:34;;;15643:86:0;;15663:5;;-1:-1:-1;;;15693:23:0;8974:18:1;;15670:58:0;8827:274:1;56224:420:0;56284:13;56300:23;56315:7;56300:14;:23::i;:::-;56284:39;;56336:48;56357:5;56372:1;56376:7;56336:20;:48::i;:::-;56425:29;56442:1;56446:7;56425:8;:29::i;:::-;-1:-1:-1;;;;;56467:16:0;;;;;;:9;:16;;;;;:21;;56487:1;;56467:16;:21;;56487:1;;56467:21;:::i;:::-;;;;-1:-1:-1;;56506:16:0;;;;:7;:16;;;;;;56499:23;;-1:-1:-1;;;;;;56499:23:0;;;56540:36;56514:7;;56506:16;-1:-1:-1;;;;;56540:36:0;;;;;56506:16;;56540:36;50617:155;;:::o;76124:577::-;76217:7;76314:29;;;:20;:29;;;;;;;;;76384:12;:21;;;;;;76217:7;;76273:15;;76217:7;;76384:26;;;;:36;;;76419:1;76414:2;;:6;76384:36;76380:285;;;76437:17;76471:21;;;:12;:21;;;;;;76457:35;;:11;:35;:::i;:::-;76437:55;;76509:18;70298:5;70338:8;76546:9;76538:4;76533:2;;:9;;;;:::i;:::-;76532:23;;;;:::i;:::-;76531:36;;;;:::i;:::-;76530:53;;;;:::i;:::-;76509:74;-1:-1:-1;76509:74:0;;-1:-1:-1;76636:17:0;76649:4;76509:74;76636:17;:::i;:::-;76629:24;;76422:243;;76380:285;76683:3;76688:4;;-1:-1:-1;76124:577:0;-1:-1:-1;;;76124:577:0:o;58040:315::-;58195:8;-1:-1:-1;;;;;58186:17:0;:5;-1:-1:-1;;;;;58186:17:0;;;58178:55;;;;-1:-1:-1;;;58178:55:0;;37406:2:1;58178:55:0;;;37388:21:1;37445:2;37425:18;;;37418:30;37484:27;37464:18;;;37457:55;37529:18;;58178:55:0;37204:349:1;58178:55:0;-1:-1:-1;;;;;58244:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;58244:46:0;;;;;;;;;;58306:41;;540::1;;;58306::0;;513:18:1;58306:41:0;;;;;;;58040:315;;;:::o;52950:::-;53107:28;53117:4;53123:2;53127:7;53107:9;:28::i;:::-;53154:48;53177:4;53183:2;53187:7;53196:5;53154:22;:48::i;:::-;53146:111;;;;-1:-1:-1;;;53146:111:0;;;;;;;:::i;66812:988::-;67078:22;67128:1;67103:22;67120:4;67103:16;:22::i;:::-;:26;;;;:::i;:::-;67140:18;67161:26;;;:17;:26;;;;;;67078:51;;-1:-1:-1;67294:28:0;;;67290:328;;-1:-1:-1;;;;;67361:18:0;;67339:19;67361:18;;;:12;:18;;;;;;;;:34;;;;;;;;;67412:30;;;;;;:44;;;67529:30;;:17;:30;;;;;:43;;;67290:328;-1:-1:-1;67714:26:0;;;;:17;:26;;;;;;;;67707:33;;;-1:-1:-1;;;;;67758:18:0;;;;;:12;:18;;;;;:34;;;;;;;67751:41;66812:988::o;68095:1079::-;68373:10;:17;68348:22;;68373:21;;68393:1;;68373:21;:::i;:::-;68405:18;68426:24;;;:15;:24;;;;;;68799:10;:26;;68348:46;;-1:-1:-1;68426:24:0;;68348:46;;68799:26;;;;;;:::i;:::-;;;;;;;;;68777:48;;68863:11;68838:10;68849;68838:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;68943:28;;;:15;:28;;;;;;;:41;;;69115:24;;;;;69108:31;69150:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;68166:1008;;;68095:1079;:::o;65599:221::-;65684:14;65701:20;65718:2;65701:16;:20::i;:::-;-1:-1:-1;;;;;65732:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;65777:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;65599:221:0:o;47819:305::-;47921:4;-1:-1:-1;;;;;;47958:40:0;;-1:-1:-1;;;47958:40:0;;:105;;-1:-1:-1;;;;;;;48015:48:0;;-1:-1:-1;;;48015:48:0;47958:105;:158;;;-1:-1:-1;;;;;;;;;;46353:40:0;;;48080:36;46244:157;69365:181;69493:45;69520:4;69526:2;69530:7;69493:26;:45::i;18099:716::-;18523:23;18549:69;18577:4;18549:69;;;;;;;;;;;;;;;;;18557:5;-1:-1:-1;;;;;18549:27:0;;;:69;;;;;:::i;:::-;18633:17;;18523:95;;-1:-1:-1;18633:21:0;18629:179;;18730:10;18719:30;;;;;;;;;;;;:::i;:::-;18711:85;;;;-1:-1:-1;;;18711:85:0;;38311:2:1;18711:85:0;;;38293:21:1;38350:2;38330:18;;;38323:30;38389:34;38369:18;;;38362:62;-1:-1:-1;;;38440:18:1;;;38433:40;38490:19;;18711:85:0;38109:406:1;58920:799:0;59075:4;-1:-1:-1;;;;;59096:13:0;;7850:19;:23;59092:620;;59132:72;;-1:-1:-1;;;59132:72:0;;-1:-1:-1;;;;;59132:36:0;;;;;:72;;763:10;;59183:4;;59189:7;;59198:5;;59132:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59132:72:0;;;;;;;;-1:-1:-1;;59132:72:0;;;;;;;;;;;;:::i;:::-;;;59128:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59374:13:0;;59370:272;;59417:60;;-1:-1:-1;;;59417:60:0;;;;;;;:::i;59370:272::-;59592:6;59586:13;59577:6;59573:2;59569:15;59562:38;59128:529;-1:-1:-1;;;;;;59255:51:0;-1:-1:-1;;;59255:51:0;;-1:-1:-1;59248:58:0;;59092:620;-1:-1:-1;59696:4:0;58920:799;;;;;;:::o;10300:229::-;10437:12;10469:52;10491:6;10499:4;10505:1;10508:12;10437;-1:-1:-1;;;;;7850:19:0;;;11707:60;;;;-1:-1:-1;;;11707:60:0;;39877:2:1;11707:60:0;;;39859:21:1;39916:2;39896:18;;;39889:30;39955:31;39935:18;;;39928:59;40004:18;;11707:60:0;39675:353:1;11707:60:0;11781:12;11795:23;11822:6;-1:-1:-1;;;;;11822:11:0;11841:5;11848:4;11822:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11780:73;;;;11871:51;11888:7;11897:10;11909:12;11871:16;:51::i;:::-;11864:58;11420:510;-1:-1:-1;;;;;;;11420:510:0:o;14106:712::-;14256:12;14285:7;14281:530;;;-1:-1:-1;14316:10:0;14309:17;;14281:530;14430:17;;:21;14426:374;;14628:10;14622:17;14689:15;14676:10;14672:2;14668:19;14661:44;14426:374;14771:12;14764:20;;-1:-1:-1;;;14764:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;955:258::-;1027:1;1037:113;1051:6;1048:1;1045:13;1037:113;;;1127:11;;;1121:18;1108:11;;;1101:39;1073:2;1066:10;1037:113;;;1168:6;1165:1;1162:13;1159:48;;;-1:-1:-1;;1203:1:1;1185:16;;1178:27;955:258::o;1218:::-;1260:3;1298:5;1292:12;1325:6;1320:3;1313:19;1341:63;1397:6;1390:4;1385:3;1381:14;1374:4;1367:5;1363:16;1341:63;:::i;:::-;1458:2;1437:15;-1:-1:-1;;1433:29:1;1424:39;;;;1465:4;1420:50;;1218:258;-1:-1:-1;;1218:258:1:o;1481:220::-;1630:2;1619:9;1612:21;1593:4;1650:45;1691:2;1680:9;1676:18;1668:6;1650:45;:::i;1706:173::-;1774:20;;-1:-1:-1;;;;;1823:31:1;;1813:42;;1803:70;;1869:1;1866;1859:12;1803:70;1706:173;;;:::o;1884:186::-;1943:6;1996:2;1984:9;1975:7;1971:23;1967:32;1964:52;;;2012:1;2009;2002:12;1964:52;2035:29;2054:9;2035:29;:::i;2075:180::-;2134:6;2187:2;2175:9;2166:7;2162:23;2158:32;2155:52;;;2203:1;2200;2193:12;2155:52;-1:-1:-1;2226:23:1;;2075:180;-1:-1:-1;2075:180:1:o;2260:254::-;2328:6;2336;2389:2;2377:9;2368:7;2364:23;2360:32;2357:52;;;2405:1;2402;2395:12;2357:52;2428:29;2447:9;2428:29;:::i;:::-;2418:39;2504:2;2489:18;;;;2476:32;;-1:-1:-1;;;2260:254:1:o;2519:248::-;2587:6;2595;2648:2;2636:9;2627:7;2623:23;2619:32;2616:52;;;2664:1;2661;2654:12;2616:52;-1:-1:-1;;2687:23:1;;;2757:2;2742:18;;;2729:32;;-1:-1:-1;2519:248:1:o;2954:328::-;3031:6;3039;3047;3100:2;3088:9;3079:7;3075:23;3071:32;3068:52;;;3116:1;3113;3106:12;3068:52;3139:29;3158:9;3139:29;:::i;:::-;3129:39;;3187:38;3221:2;3210:9;3206:18;3187:38;:::i;:::-;3177:48;;3272:2;3261:9;3257:18;3244:32;3234:42;;2954:328;;;;;:::o;3287:316::-;3364:6;3372;3380;3433:2;3421:9;3412:7;3408:23;3404:32;3401:52;;;3449:1;3446;3439:12;3401:52;-1:-1:-1;;3472:23:1;;;3542:2;3527:18;;3514:32;;-1:-1:-1;3593:2:1;3578:18;;;3565:32;;3287:316;-1:-1:-1;3287:316:1:o;4248:118::-;4334:5;4327:13;4320:21;4313:5;4310:32;4300:60;;4356:1;4353;4346:12;4371:315;4436:6;4444;4497:2;4485:9;4476:7;4472:23;4468:32;4465:52;;;4513:1;4510;4503:12;4465:52;4536:29;4555:9;4536:29;:::i;:::-;4526:39;;4615:2;4604:9;4600:18;4587:32;4628:28;4650:5;4628:28;:::i;:::-;4675:5;4665:15;;;4371:315;;;;;:::o;4691:127::-;4752:10;4747:3;4743:20;4740:1;4733:31;4783:4;4780:1;4773:15;4807:4;4804:1;4797:15;4823:632;4888:5;4918:18;4959:2;4951:6;4948:14;4945:40;;;4965:18;;:::i;:::-;5040:2;5034:9;5008:2;5094:15;;-1:-1:-1;;5090:24:1;;;5116:2;5086:33;5082:42;5070:55;;;5140:18;;;5160:22;;;5137:46;5134:72;;;5186:18;;:::i;:::-;5226:10;5222:2;5215:22;5255:6;5246:15;;5285:6;5277;5270:22;5325:3;5316:6;5311:3;5307:16;5304:25;5301:45;;;5342:1;5339;5332:12;5301:45;5392:6;5387:3;5380:4;5372:6;5368:17;5355:44;5447:1;5440:4;5431:6;5423;5419:19;5415:30;5408:41;;;;4823:632;;;;;:::o;5460:451::-;5529:6;5582:2;5570:9;5561:7;5557:23;5553:32;5550:52;;;5598:1;5595;5588:12;5550:52;5638:9;5625:23;5671:18;5663:6;5660:30;5657:50;;;5703:1;5700;5693:12;5657:50;5726:22;;5779:4;5771:13;;5767:27;-1:-1:-1;5757:55:1;;5808:1;5805;5798:12;5757:55;5831:74;5897:7;5892:2;5879:16;5874:2;5870;5866:11;5831:74;:::i;5916:667::-;6011:6;6019;6027;6035;6088:3;6076:9;6067:7;6063:23;6059:33;6056:53;;;6105:1;6102;6095:12;6056:53;6128:29;6147:9;6128:29;:::i;:::-;6118:39;;6176:38;6210:2;6199:9;6195:18;6176:38;:::i;:::-;6166:48;;6261:2;6250:9;6246:18;6233:32;6223:42;;6316:2;6305:9;6301:18;6288:32;6343:18;6335:6;6332:30;6329:50;;;6375:1;6372;6365:12;6329:50;6398:22;;6451:4;6443:13;;6439:27;-1:-1:-1;6429:55:1;;6480:1;6477;6470:12;6429:55;6503:74;6569:7;6564:2;6551:16;6546:2;6542;6538:11;6503:74;:::i;:::-;6493:84;;;5916:667;;;;;;;:::o;6588:592::-;6659:6;6667;6720:2;6708:9;6699:7;6695:23;6691:32;6688:52;;;6736:1;6733;6726:12;6688:52;6776:9;6763:23;6805:18;6846:2;6838:6;6835:14;6832:34;;;6862:1;6859;6852:12;6832:34;6900:6;6889:9;6885:22;6875:32;;6945:7;6938:4;6934:2;6930:13;6926:27;6916:55;;6967:1;6964;6957:12;6916:55;7007:2;6994:16;7033:2;7025:6;7022:14;7019:34;;;7049:1;7046;7039:12;7019:34;7094:7;7089:2;7080:6;7076:2;7072:15;7068:24;7065:37;7062:57;;;7115:1;7112;7105:12;7062:57;7146:2;7138:11;;;;;7168:6;;-1:-1:-1;6588:592:1;;-1:-1:-1;;;;6588:592:1:o;7185:260::-;7253:6;7261;7314:2;7302:9;7293:7;7289:23;7285:32;7282:52;;;7330:1;7327;7320:12;7282:52;7353:29;7372:9;7353:29;:::i;:::-;7343:39;;7401:38;7435:2;7424:9;7420:18;7401:38;:::i;:::-;7391:48;;7185:260;;;;;:::o;7810:355::-;8012:2;7994:21;;;8051:2;8031:18;;;8024:30;8090:33;8085:2;8070:18;;8063:61;8156:2;8141:18;;7810:355::o;8170:127::-;8231:10;8226:3;8222:20;8219:1;8212:31;8262:4;8259:1;8252:15;8286:4;8283:1;8276:15;8302:168;8342:7;8408:1;8404;8400:6;8396:14;8393:1;8390:21;8385:1;8378:9;8371:17;8367:45;8364:71;;;8415:18;;:::i;:::-;-1:-1:-1;8455:9:1;;8302:168::o;8475:217::-;8515:1;8541;8531:132;;8585:10;8580:3;8576:20;8573:1;8566:31;8620:4;8617:1;8610:15;8648:4;8645:1;8638:15;8531:132;-1:-1:-1;8677:9:1;;8475:217::o;8697:125::-;8737:4;8765:1;8762;8759:8;8756:34;;;8770:18;;:::i;:::-;-1:-1:-1;8807:9:1;;8697:125::o;9106:245::-;9173:6;9226:2;9214:9;9205:7;9201:23;9197:32;9194:52;;;9242:1;9239;9232:12;9194:52;9274:9;9268:16;9293:28;9315:5;9293:28;:::i;9356:380::-;9435:1;9431:12;;;;9478;;;9499:61;;9553:4;9545:6;9541:17;9531:27;;9499:61;9606:2;9598:6;9595:14;9575:18;9572:38;9569:161;;;9652:10;9647:3;9643:20;9640:1;9633:31;9687:4;9684:1;9677:15;9715:4;9712:1;9705:15;9741:356;9943:2;9925:21;;;9962:18;;;9955:30;10021:34;10016:2;10001:18;;9994:62;10088:2;10073:18;;9741:356::o;11748:128::-;11788:3;11819:1;11815:6;11812:1;11809:13;11806:39;;;11825:18;;:::i;:::-;-1:-1:-1;11861:9:1;;11748:128::o;12489:422::-;12578:1;12621:5;12578:1;12635:270;12656:7;12646:8;12643:21;12635:270;;;12715:4;12711:1;12707:6;12703:17;12697:4;12694:27;12691:53;;;12724:18;;:::i;:::-;12774:7;12764:8;12760:22;12757:55;;;12794:16;;;;12757:55;12873:22;;;;12833:15;;;;12635:270;;;12639:3;12489:422;;;;;:::o;12916:806::-;12965:5;12995:8;12985:80;;-1:-1:-1;13036:1:1;13050:5;;12985:80;13084:4;13074:76;;-1:-1:-1;13121:1:1;13135:5;;13074:76;13166:4;13184:1;13179:59;;;;13252:1;13247:130;;;;13159:218;;13179:59;13209:1;13200:10;;13223:5;;;13247:130;13284:3;13274:8;13271:17;13268:43;;;13291:18;;:::i;:::-;-1:-1:-1;;13347:1:1;13333:16;;13362:5;;13159:218;;13461:2;13451:8;13448:16;13442:3;13436:4;13433:13;13429:36;13423:2;13413:8;13410:16;13405:2;13399:4;13396:12;13392:35;13389:77;13386:159;;;-1:-1:-1;13498:19:1;;;13530:5;;13386:159;13577:34;13602:8;13596:4;13577:34;:::i;:::-;13647:6;13643:1;13639:6;13635:19;13626:7;13623:32;13620:58;;;13658:18;;:::i;:::-;13696:20;;12916:806;-1:-1:-1;;;12916:806:1:o;13727:131::-;13787:5;13816:36;13843:8;13837:4;13816:36;:::i;13863:413::-;14065:2;14047:21;;;14104:2;14084:18;;;14077:30;14143:34;14138:2;14123:18;;14116:62;-1:-1:-1;;;14209:2:1;14194:18;;14187:47;14266:3;14251:19;;13863:413::o;14693:354::-;14895:2;14877:21;;;14934:2;14914:18;;;14907:30;14973:32;14968:2;14953:18;;14946:60;15038:2;15023:18;;14693:354::o;15052:343::-;15254:2;15236:21;;;15293:2;15273:18;;;15266:30;-1:-1:-1;;;15327:2:1;15312:18;;15305:49;15386:2;15371:18;;15052:343::o;15400:344::-;15602:2;15584:21;;;15641:2;15621:18;;;15614:30;-1:-1:-1;;;15675:2:1;15660:18;;15653:50;15735:2;15720:18;;15400:344::o;15749:184::-;15819:6;15872:2;15860:9;15851:7;15847:23;15843:32;15840:52;;;15888:1;15885;15878:12;15840:52;-1:-1:-1;15911:16:1;;15749:184;-1:-1:-1;15749:184:1:o;16696:397::-;16898:2;16880:21;;;16937:2;16917:18;;;16910:30;16976:34;16971:2;16956:18;;16949:62;-1:-1:-1;;;17042:2:1;17027:18;;17020:31;17083:3;17068:19;;16696:397::o;19707:127::-;19768:10;19763:3;19759:20;19756:1;19749:31;19799:4;19796:1;19789:15;19823:4;19820:1;19813:15;23538:349;23740:2;23722:21;;;23779:2;23759:18;;;23752:30;23818:27;23813:2;23798:18;;23791:55;23878:2;23863:18;;23538:349::o;32518:1186::-;32627:4;32656:2;32685;32674:9;32667:21;32708:1;32741:6;32735:13;32771:3;32793:1;32821:9;32817:2;32813:18;32803:28;;32881:2;32870:9;32866:18;32903;32893:61;;32947:4;32939:6;32935:17;32925:27;;32893:61;33000:2;32992:6;32989:14;32969:18;32966:38;32963:165;;;-1:-1:-1;;;33027:33:1;;33083:4;33080:1;33073:15;33113:4;33034:3;33101:17;32963:165;33184:18;;;887:19;;;939:4;930:14;33227:18;33254:100;;;;33368:1;33363:315;;;;33220:458;;33254:100;-1:-1:-1;;33287:24:1;;33275:37;;33332:12;;;;-1:-1:-1;33254:100:1;;33363:315;32465:1;32458:14;;;32502:4;32489:18;;33458:1;33472:165;33486:6;33483:1;33480:13;33472:165;;;33564:14;;33551:11;;;33544:35;33607:16;;;;33501:10;;33472:165;;;33657:11;;;-1:-1:-1;;33220:458:1;-1:-1:-1;33695:3:1;;32518:1186;-1:-1:-1;;;;;;;;;32518:1186:1:o;37558:414::-;37760:2;37742:21;;;37799:2;37779:18;;;37772:30;37838:34;37833:2;37818:18;;37811:62;-1:-1:-1;;;37904:2:1;37889:18;;37882:48;37962:3;37947:19;;37558:414::o;37977:127::-;38038:10;38033:3;38029:20;38026:1;38019:31;38069:4;38066:1;38059:15;38093:4;38090:1;38083:15;38520:489;-1:-1:-1;;;;;38789:15:1;;;38771:34;;38841:15;;38836:2;38821:18;;38814:43;38888:2;38873:18;;38866:34;;;38936:3;38931:2;38916:18;;38909:31;;;38714:4;;38957:46;;38983:19;;38975:6;38957:46;:::i;39014:249::-;39083:6;39136:2;39124:9;39115:7;39111:23;39107:32;39104:52;;;39152:1;39149;39142:12;39104:52;39184:9;39178:16;39203:30;39227:5;39203:30;:::i;40033:274::-;40162:3;40200:6;40194:13;40216:53;40262:6;40257:3;40250:4;40242:6;40238:17;40216:53;:::i;:::-;40285:16;;;;;40033:274;-1:-1:-1;;40033:274:1:o

Swarm Source

ipfs://5969f6371bd10e54f12be697d33f6f10295954d960c25267ecb120a2f7204dbf
Loading