Token DiversiFi

 

Overview ERC-20

Price
$0.00 @ 0.000000 FTM
Fully Diluted Market Cap
Total Supply:
10,000,000 DFi

Holders:
553 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

Diversifi allows users to buy one token and receive a percentage of the trading volume.


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

Contract Source Code Verified (Exact Match)

Contract Name:
DiversiFi

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-01
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

interface IUniswapV2Pair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

interface IUniswapV2Factory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB)
        external
        view
        returns (address pair);

    function allPairs(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;
}

library IterableMapping {
    // Iterable mapping from address to uint;
    struct Map {
        address[] keys;
        mapping(address => uint256) values;
        mapping(address => uint256) indexOf;
        mapping(address => bool) inserted;
    }

    function get(Map storage map, address key) internal view returns (uint256) {
        return map.values[key];
    }

    function getIndexOfKey(Map storage map, address key)
        internal
        view
        returns (int256)
    {
        if (!map.inserted[key]) {
            return -1;
        }
        return int256(map.indexOf[key]);
    }

    function getKeyAtIndex(Map storage map, uint256 index)
        internal
        view
        returns (address)
    {
        return map.keys[index];
    }

    function size(Map storage map) internal view returns (uint256) {
        return map.keys.length;
    }

    function set(
        Map storage map,
        address key,
        uint256 val
    ) internal {
        if (map.inserted[key]) {
            map.values[key] = val;
        } else {
            map.inserted[key] = true;
            map.values[key] = val;
            map.indexOf[key] = map.keys.length;
            map.keys.push(key);
        }
    }

    function remove(Map storage map, address key) internal {
        if (!map.inserted[key]) {
            return;
        }

        delete map.inserted[key];
        delete map.values[key];

        uint256 index = map.indexOf[key];
        uint256 lastIndex = map.keys.length - 1;
        address lastKey = map.keys[lastIndex];

        map.indexOf[lastKey] = index;
        delete map.indexOf[key];

        map.keys[index] = lastKey;
        map.keys.pop();
    }
}

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

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

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

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

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

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

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

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

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);
}

contract ERC20 is Context, IERC20, IERC20Metadata {
    using SafeMath for uint256;

    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:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount)
        public
        virtual
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

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

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

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

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

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

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(
            amount,
            "ERC20: transfer amount exceeds balance"
        );
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `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 = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

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

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

        _balances[account] = _balances[account].sub(
            amount,
            "ERC20: burn amount exceeds balance"
        );
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

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

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

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

interface DividendPayingTokenOptionalInterface {
    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function withdrawableDividendOf(address _owner)
        external
        view
        returns (uint256);

    /// @notice View the amount of dividend in wei that an address has withdrawn.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has withdrawn.
    function withdrawnDividendOf(address _owner)
        external
        view
        returns (uint256);

    /// @notice View the amount of dividend in wei that an address has earned in total.
    /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has earned in total.
    function accumulativeDividendOf(address _owner)
        external
        view
        returns (uint256);
}

interface DividendPayingTokenInterface {
    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function dividendOf(address _owner) external view returns (uint256);

    /// @notice Distributes ether to token holders as dividends.
    /// @dev SHOULD distribute the paid ether to token holders as dividends.
    ///  SHOULD NOT directly transfer ether to token holders in this function.
    ///  MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0.
    function distributeDividends() external payable;

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev SHOULD transfer `dividendOf(msg.sender)` wei to `msg.sender`, and `dividendOf(msg.sender)` SHOULD be 0 after the transfer.
    ///  MUST emit a `DividendWithdrawn` event if the amount of ether transferred is greater than 0.
    function withdrawDividend() external;

    /// @dev This event MUST emit when ether is distributed to token holders.
    /// @param from The address which sends ether to this contract.
    /// @param weiAmount The amount of distributed ether in wei.
    event DividendsDistributed(address indexed from, uint256 weiAmount);

    /// @dev This event MUST emit when an address withdraws their dividend.
    /// @param to The address which withdraws ether from this contract.
    /// @param weiAmount The amount of withdrawn ether in wei.
    event DividendWithdrawn(address indexed to, uint256 weiAmount);
}

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

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

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

        return c;
    }

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

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

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() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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"
        );
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a) internal pure returns (int256) {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }

    function toUint256Safe(int256 a) internal pure returns (uint256) {
        require(a >= 0);
        return uint256(a);
    }
}

library SafeMathUint {
    function toInt256Safe(uint256 a) internal pure returns (int256) {
        int256 b = int256(a);
        require(b >= 0);
        return b;
    }
}

interface IUniswapV2Router01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

contract DividendPayingToken is
    ERC20,
    DividendPayingTokenInterface,
    DividendPayingTokenOptionalInterface
{
    using SafeMath for uint256;
    using SafeMathUint for uint256;
    using SafeMathInt for int256;

    // With `magnitude`, we can properly distribute dividends even if the amount of received ether is small.
    // For more discussion about choosing the value of `magnitude`,
    //  see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
    uint256 internal constant magnitude = 2**128;

    uint256 internal magnifiedDividendPerShare;

    // About dividendCorrection:
    // If the token balance of a `_user` is never changed, the dividend of `_user` can be computed with:
    //   `dividendOf(_user) = dividendPerShare * balanceOf(_user)`.
    // When `balanceOf(_user)` is changed (via minting/burning/transferring tokens),
    //   `dividendOf(_user)` should not be changed,
    //   but the computed value of `dividendPerShare * balanceOf(_user)` is changed.
    // To keep the `dividendOf(_user)` unchanged, we add a correction term:
    //   `dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user)`,
    //   where `dividendCorrectionOf(_user)` is updated whenever `balanceOf(_user)` is changed:
    //   `dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user))`.
    // So now `dividendOf(_user)` returns the same value before and after `balanceOf(_user)` is changed.
    mapping(address => int256) internal magnifiedDividendCorrections;
    mapping(address => uint256) internal withdrawnDividends;

    uint256 public totalDividendsDistributed;

    constructor(string memory _name, string memory _symbol)
        ERC20(_name, _symbol)
    {}

    /// @dev Distributes dividends whenever ether is paid to this contract.
    receive() external payable {
        distributeDividends();
    }

    /// @notice Distributes ether to token holders as dividends.
    /// @dev It reverts if the total supply of tokens is 0.
    /// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0.
    /// About undistributed ether:
    ///   In each distribution, there is a small amount of ether not distributed,
    ///     the magnified amount of which is
    ///     `(msg.value * magnitude) % totalSupply()`.
    ///   With a well-chosen `magnitude`, the amount of undistributed ether
    ///     (de-magnified) in a distribution can be less than 1 wei.
    ///   We can actually keep track of the undistributed ether in a distribution
    ///     and try to distribute it in the next distribution,
    ///     but keeping track of such data on-chain costs much more than
    ///     the saved ether, so we don't do that.
    function distributeDividends() public payable override {
        require(totalSupply() > 0);

        if (msg.value > 0) {
            magnifiedDividendPerShare = magnifiedDividendPerShare.add(
                (msg.value).mul(magnitude) / totalSupply()
            );
            emit DividendsDistributed(msg.sender, msg.value);

            totalDividendsDistributed = totalDividendsDistributed.add(
                msg.value
            );
        }
    }

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
    function withdrawDividend() public virtual override {
        _withdrawDividendOfUser(payable(msg.sender));
    }

    /// @notice Withdraws the ether distributed to the sender.
    /// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
    function _withdrawDividendOfUser(address payable user)
        internal
        virtual
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(
                _withdrawableDividend
            );
            emit DividendWithdrawn(user, _withdrawableDividend);
            (bool success, ) = user.call{
                value: _withdrawableDividend,
                gas: 3000
            }("");

            if (!success) {
                withdrawnDividends[user] = withdrawnDividends[user].sub(
                    _withdrawableDividend
                );
                return 0;
            }

            return _withdrawableDividend;
        }

        return 0;
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function dividendOf(address _owner) public view override returns (uint256) {
        return withdrawableDividendOf(_owner);
    }

    /// @notice View the amount of dividend in wei that an address can withdraw.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` can withdraw.
    function withdrawableDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
    }

    /// @notice View the amount of dividend in wei that an address has withdrawn.
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has withdrawn.
    function withdrawnDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return withdrawnDividends[_owner];
    }

    /// @notice View the amount of dividend in wei that an address has earned in total.
    /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
    /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
    /// @param _owner The address of a token holder.
    /// @return The amount of dividend in wei that `_owner` has earned in total.
    function accumulativeDividendOf(address _owner)
        public
        view
        override
        returns (uint256)
    {
        return
            magnifiedDividendPerShare
                .mul(balanceOf(_owner))
                .toInt256Safe()
                .add(magnifiedDividendCorrections[_owner])
                .toUint256Safe() / magnitude;
    }

    /// @dev Internal function that transfer tokens from one address to another.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param from The address to transfer from.
    /// @param to The address to transfer to.
    /// @param value The amount to be transferred.
    function _transfer(
        address from,
        address to,
        uint256 value
    ) internal virtual override {
        require(false);

        int256 _magCorrection = magnifiedDividendPerShare
            .mul(value)
            .toInt256Safe();
        magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from]
            .add(_magCorrection);
        magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(
            _magCorrection
        );
    }

    /// @dev Internal function that mints tokens to an account.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account that will receive the created tokens.
    /// @param value The amount that will be created.
    function _mint(address account, uint256 value) internal override {
        super._mint(account, value);

        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
            account
        ].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
    }

    /// @dev Internal function that burns an amount of the token of a given account.
    /// Update magnifiedDividendCorrections to keep dividends unchanged.
    /// @param account The account whose tokens will be burnt.
    /// @param value The amount that will be burnt.
    function _burn(address account, uint256 value) internal override {
        super._burn(account, value);

        magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
            account
        ].add((magnifiedDividendPerShare.mul(value)).toInt256Safe());
    }

    function _setBalance(address account, uint256 newBalance) internal {
        uint256 currentBalance = balanceOf(account);

        if (newBalance > currentBalance) {
            uint256 mintAmount = newBalance.sub(currentBalance);
            _mint(account, mintAmount);
        } else if (newBalance < currentBalance) {
            uint256 burnAmount = currentBalance.sub(newBalance);
            _burn(account, burnAmount);
        }
    }
}

contract DiversiFi is ERC20, Ownable {
    using SafeMath for uint256;

    IUniswapV2Router02 public uniswapV2Router;

    address public uniswapV2Pair;

    bool private swapping;
    bool private stakingEnabled = false;
    bool public tradingEnabled = false;
    // Saturday, January 15, 2022 00:00:00 GMT
    uint public immutable forceStartTradingAt = 1642233600;
    uint256 public sellAmount = 0;
    uint256 public buyAmount = 0;
    uint256 private totalSellFees;
    uint256 private totalBuyFees;

    DiversiFiDividendTracker public dividendTracker;

    address public liquidityWallet;

    address payable public operations1Address =
        payable(0xb2055632af7521E16c57e2DBD943eC0C5e78e078);
    address payable public operations2Address =
        payable(0x92e5cbb95E1831e732CC26E8Fe81431a73FA3d5e);

    uint256 public maxSellTransactionAmount = 0;
    uint256 public swapTokensAtAmount = 250000 * (10**9);

    uint256 public operationsFees = 4;
    uint256 public liquidityFee = 1;
    uint256 public FTMRewardsBuyFee = 5;
    uint256 public FTMRewardsSellFee = 5;
    bool public swapAndLiquifyEnabled = true;

    // use by default 300,000 gas to process auto-claiming dividends
    uint256 public gasForProcessing = 300000;

    // exlcude from fees and max transaction amount
    mapping(address => bool) private _isExcludedFromFees;

    // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
    // could be subject to a maximum transfer amount
    mapping(address => bool) public automatedMarketMakerPairs;

    mapping(address => uint256) public stakingBonus;
    mapping(address => uint256) public stakingUntilDate;
    mapping(uint256 => uint256) public stakingAmounts;

    mapping(address => bool) private canTransferBeforeTradingIsEnabled;

    event EnableAccountStaking(address indexed account, uint256 duration);
    event UpdateStakingAmounts(uint256 duration, uint256 amount);

    event EnableSwapAndLiquify(bool enabled);
    event EnableStaking(bool enabled);

    event SetPreSaleWallet(address wallet);

    event UpdateDividendTracker(
        address indexed newAddress,
        address indexed oldAddress
    );

    event UpdateUniswapV2Router(
        address indexed newAddress,
        address indexed oldAddress
    );

    event TradingEnabled();

    event UpdateFees(
        uint256 operations,
        uint256 liquidity,
        uint256 FTMRewardsBuy,
        uint256 FTMRewardsSell
    );

    event ExcludeFromFees(address indexed account, bool isExcluded);
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);

    event LiquidityWalletUpdated(
        address indexed newLiquidityWallet,
        address indexed oldLiquidityWallet
    );

    event GasForProcessingUpdated(
        uint256 indexed newValue,
        uint256 indexed oldValue
    );

    event SwapAndLiquify(
        uint256 tokensSwapped,
        uint256 ethReceived,
        uint256 tokensIntoLiqudity
    );

    event SendDividends(uint256 amount, uint256 opAmount, bool success);

    event ProcessedDividendTracker(
        uint256 iterations,
        uint256 claims,
        uint256 lastProcessedIndex,
        bool indexed automatic,
        uint256 gas,
        address indexed processor
    );

    event UpdatePayoutToken(address account, address token);
    event UpdateAllowTokens(address token, bool allow);

    constructor() ERC20("DiversiFi", "DFi") {
        dividendTracker = new DiversiFiDividendTracker(payable(this));

        liquidityWallet = owner();

        uniswapV2Router = IUniswapV2Router02(
            0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506
            
        );

        // Create a uniswap pair for this new token
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
                address(this),
                uniswapV2Router.WETH()
            );

        _setAutomatedMarketMakerPair(uniswapV2Pair, true);

        // exclude from receiving dividends
        dividendTracker.excludeFromDividends(address(dividendTracker));
        dividendTracker.excludeFromDividends(address(this));
        dividendTracker.excludeFromDividends(
            0x000000000000000000000000000000000000dEaD
        );
        dividendTracker.excludedFromDividends(address(0));
        dividendTracker.excludeFromDividends(owner());
        dividendTracker.excludeFromDividends(address(uniswapV2Router));

        // exclude from paying fees or having max transaction amount
        _isExcludedFromFees[liquidityWallet] = true;
        _isExcludedFromFees[address(this)] = true;
        _isExcludedFromFees[owner()] = true;
        _isExcludedFromFees[address(dividendTracker)] = true;

        totalSellFees = FTMRewardsSellFee.add(liquidityFee).add(operationsFees);
        totalBuyFees = FTMRewardsBuyFee.add(liquidityFee).add(operationsFees);

        canTransferBeforeTradingIsEnabled[owner()] = true;
        /*
            _mint is an internal function in ERC20.sol that is only called here,
            and CANNOT be called ever again
        */

        _mint(owner(), 10000000 * (10**9));
    }

    function decimals() public view virtual override returns (uint8) {
        return 9;
    }

    receive() external payable {}

    function updateStakingAmounts(uint256 duration, uint256 bonus)
        public
        onlyOwner
    {
        require(stakingAmounts[duration] != bonus);
        require(bonus <= 500, "Staking bonus can't exceed 500%");

        stakingAmounts[duration] = bonus;
        emit UpdateStakingAmounts(duration, bonus);
    }

    function enableTrading() external onlyOwner {
        require(!tradingEnabled);

        tradingEnabled = true;
        emit TradingEnabled();
    }

    function setPresaleWallet(address wallet) external onlyOwner {
        canTransferBeforeTradingIsEnabled[wallet] = true;
        _isExcludedFromFees[wallet] = true;
        dividendTracker.excludeFromDividends(wallet);

        emit SetPreSaleWallet(wallet);
    }

    function enableStaking(bool enable) public onlyOwner {
        require(stakingEnabled != enable);
        stakingEnabled = enable;

        emit EnableStaking(enable);
    }

    function stake(uint256 duration) public {
        require(stakingEnabled, "Staking is not enabled");
        require(stakingAmounts[duration] != 0, "Invalid staking duration");
        require(
            stakingUntilDate[_msgSender()] < block.timestamp.add(duration),
            "already staked for a longer duration"
        );

        stakingBonus[_msgSender()] = stakingAmounts[duration];
        stakingUntilDate[_msgSender()] = block.timestamp.add(duration);

        dividendTracker.setBalance(
            _msgSender(),
            getStakingBalance(_msgSender())
        );

        emit EnableAccountStaking(_msgSender(), duration);
    }

    function updateMaxAmount(uint256 newNum) public onlyOwner {
        require(maxSellTransactionAmount != newNum);
        // 0 means disabled
        require(
            maxSellTransactionAmount == 0 ||
                maxSellTransactionAmount >= 1000 * (10**9),
            "max sell amount must either be disabled or greater than 1 thousand"
        );
        maxSellTransactionAmount = newNum * (10**9);
    }

    function updateSwapTokensAtAmount(uint256 newNum) public onlyOwner {
        require(swapTokensAtAmount != newNum);
        require(
                swapTokensAtAmount >= 50000 * (10**9),
            "Swap Token Amount must be greater than 50 thousand"
        );
        swapTokensAtAmount = newNum * (10**9);
    }
    
    function updateDividendTracker(address newAddress) public onlyOwner {
        require(newAddress != address(dividendTracker));

        DiversiFiDividendTracker newDividendTracker = DiversiFiDividendTracker(
            payable(newAddress)
        );

        require(newDividendTracker.owner() == address(this));

        newDividendTracker.excludeFromDividends(address(newDividendTracker));
        newDividendTracker.excludeFromDividends(address(this));
        newDividendTracker.excludeFromDividends(owner());
        newDividendTracker.excludeFromDividends(address(uniswapV2Router));

        emit UpdateDividendTracker(newAddress, address(dividendTracker));

        dividendTracker = newDividendTracker;
    }

    function updateOperations1Address(address payable newAddress)
        public
        onlyOwner
    {
        operations1Address = newAddress;
    }

    function updateOperations2Address(address payable newAddress)
        public
        onlyOwner
    {
        operations2Address = newAddress;
    }

    function updateUniswapV2Router(address newAddress) public onlyOwner {
        require(newAddress != address(uniswapV2Router));
        emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router));
        uniswapV2Router = IUniswapV2Router02(newAddress);
        dividendTracker.updateUniswapV2Router(newAddress);
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        require(_isExcludedFromFees[account] != excluded);
        _isExcludedFromFees[account] = excluded;

        emit ExcludeFromFees(account, excluded);
    }

    function enableSwapAndLiquify(bool enabled) public onlyOwner {
        require(swapAndLiquifyEnabled != enabled);
        swapAndLiquifyEnabled = enabled;

        emit EnableSwapAndLiquify(enabled);
    }

    function setAutomatedMarketMakerPair(address pair, bool value)
        public
        onlyOwner
    {
        require(pair != uniswapV2Pair);

        _setAutomatedMarketMakerPair(pair, value);
    }

    function setAllowCustomTokens(bool allow) public onlyOwner {
        dividendTracker.setAllowCustomTokens(allow);
    }

    function setAllowAutoReinvest(bool allow) public onlyOwner {
        dividendTracker.setAllowAutoReinvest(allow);
    }

    function _setAutomatedMarketMakerPair(address pair, bool value) private {
        automatedMarketMakerPairs[pair] = value;

        if (value) {
            dividendTracker.excludeFromDividends(pair);
        }

        emit SetAutomatedMarketMakerPair(pair, value);
    }

    function updateLiquidityWallet(address newLiquidityWallet)
        public
        onlyOwner
    {
        excludeFromFees(newLiquidityWallet, true);
        emit LiquidityWalletUpdated(newLiquidityWallet, liquidityWallet);
        liquidityWallet = newLiquidityWallet;
    }

    function updateGasForProcessing(uint256 newValue) public onlyOwner {
        require(newValue >= 200000 && newValue <= 600000);
        emit GasForProcessingUpdated(newValue, gasForProcessing);
        gasForProcessing = newValue;
    }

    function updateFees(
        uint256 operations,
        uint256 liquidity,
        uint256 FTMRewardsBuy,
        uint256 FTMRewardsSell
    ) public onlyOwner {
        require(operations <= 20, "operation fees can't exceed 20%");
        require(liquidity <= 20, "liquidity fees can't exceed 20%");
        require(
            FTMRewardsBuy >= 1 && FTMRewardsBuy <= 50,
            "FTM reward fees must be between 1 and 50"
        );
        require(
            FTMRewardsSell >= 1 && FTMRewardsSell <= 50,
            "FTM reward fees must be between 1 and 50"
        );

        operationsFees = operations;
        liquidityFee = liquidity;
        FTMRewardsBuyFee = FTMRewardsBuy;
        FTMRewardsSellFee = FTMRewardsSell;

        totalSellFees = FTMRewardsSellFee.add(liquidityFee).add(operationsFees);
        totalBuyFees = FTMRewardsBuyFee.add(liquidityFee).add(operationsFees);

        emit UpdateFees(operations, liquidity, FTMRewardsBuy, FTMRewardsSell);
    }

    function getStakingInfo(address account)
        external
        view
        returns (uint256, uint256)
    {
        return (stakingUntilDate[account], stakingBonus[account]);
    }

    function getTotalDividendsDistributed() external view returns (uint256) {
        return dividendTracker.totalDividendsDistributed();
    }

    function isExcludedFromFees(address account) public view returns (bool) {
        return _isExcludedFromFees[account];
    }

    function withdrawableDividendOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.withdrawableDividendOf(account);
    }

    function dividendTokenBalanceOf(address account)
        public
        view
        returns (uint256)
    {
        return dividendTracker.balanceOf(account);
    }

    function getAccountDividendsInfo(address account)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccount(account);
    }

    function getAccountDividendsInfoAtIndex(uint256 index)
        external
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        return dividendTracker.getAccountAtIndex(index);
    }

    function processDividendTracker(uint256 gas) external {
        (
            uint256 iterations,
            uint256 claims,
            uint256 lastProcessedIndex
        ) = dividendTracker.process(gas);
        emit ProcessedDividendTracker(
            iterations,
            claims,
            lastProcessedIndex,
            false,
            gas,
            tx.origin
        );
    }

    function claim() external {
        dividendTracker.processAccount(payable(msg.sender), false);
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return dividendTracker.getLastProcessedIndex();
    }

    function getNumberOfDividendTokenHolders() external view returns (uint256) {
        return dividendTracker.getNumberOfTokenHolders();
    }

    function setAutoClaim(bool value) external {
        dividendTracker.setAutoClaim(msg.sender, value);
    }

    function setReinvest(bool value) external {
        dividendTracker.setReinvest(msg.sender, value);
    }

    function setDividendsPaused(bool value) external onlyOwner {
        dividendTracker.setDividendsPaused(value);
    }

    function isExcludedFromAutoClaim(address account)
        external
        view
        returns (bool)
    {
        return dividendTracker.isExcludedFromAutoClaim(account);
    }

    function isReinvest(address account) external view returns (bool) {
        return dividendTracker.isReinvest(account);
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(
            tradingEnabled || canTransferBeforeTradingIsEnabled[from] || block.timestamp >= forceStartTradingAt,
            "Trading has not yet been enabled"
        );

        if (amount == 0) {
            super._transfer(from, to, 0);
            return;
        } else if (
            !swapping && !_isExcludedFromFees[from] && !_isExcludedFromFees[to]
        ) {
            bool isSelling = automatedMarketMakerPairs[to];

            if (!automatedMarketMakerPairs[from] && stakingEnabled) {
                require(
                    stakingUntilDate[from] <= block.timestamp,
                    "Tokens are staked and locked!"
                );
                if (stakingUntilDate[from] != 0) {
                    stakingUntilDate[from] = 0;
                    stakingBonus[from] = 0;
                }
            }

            uint256 FTMRewardsFee;

            if (isSelling) {
                FTMRewardsFee = FTMRewardsSellFee;
            } else {
                FTMRewardsFee = FTMRewardsBuyFee;
            }

            uint256 totalFees = FTMRewardsFee.add(liquidityFee).add(operationsFees);

            if (
                maxSellTransactionAmount != 0 &&
                isSelling && // sells only by detecting transfer to automated market maker pair
                from != address(uniswapV2Router) //router -> pair is removing liquidity which shouldn't have max
            ) {
                require(
                    amount <= maxSellTransactionAmount,
                    "maxSellTransactionAmount."
                );
            }

            uint256 contractTokenBalance = balanceOf(address(this));

            bool canSwap = contractTokenBalance >= swapTokensAtAmount;

            if (canSwap && !automatedMarketMakerPairs[from]) {
                swapping = true;

                if (swapAndLiquifyEnabled) {
                    uint256 totalBuySell = buyAmount.add(sellAmount);
                    uint256 swapAmountBought = contractTokenBalance
                        .mul(buyAmount)
                        .div(totalBuySell);
                    uint256 swapAmountSold = contractTokenBalance
                        .mul(sellAmount)
                        .div(totalBuySell);

                    uint256 swapBuyTokens = swapAmountBought
                        .mul(liquidityFee)
                        .div(totalBuyFees);

                    uint256 swapSellTokens = swapAmountSold
                        .mul(liquidityFee)
                        .div(totalSellFees);

                    uint256 swapTokens = swapSellTokens.add(swapBuyTokens);

                    swapAndLiquify(swapTokens);
                }

                uint256 remainingBalance = balanceOf(address(this));

                swapAndSendDividends(remainingBalance);

                buyAmount = 0;
                sellAmount = 0;

                swapping = false;
            }

            uint256 fees = amount.mul(totalFees).div(100);

            amount = amount.sub(fees);

            if (isSelling) {
                sellAmount = sellAmount.add(fees);
            } else {
                buyAmount = buyAmount.add(fees);
            }

            super._transfer(from, address(this), fees);

            uint256 gas = gasForProcessing;

            try dividendTracker.process(gas) returns (
                uint256 iterations,
                uint256 claims,
                uint256 lastProcessedIndex
            ) {
                emit ProcessedDividendTracker(
                    iterations,
                    claims,
                    lastProcessedIndex,
                    true,
                    gas,
                    tx.origin
                );
            } catch {}
        }

        super._transfer(from, to, amount);

        dividendTracker.setBalance(from, getStakingBalance(from));
        dividendTracker.setBalance(to, getStakingBalance(to));
    }

    function getStakingBalance(address account) private view returns (uint256) {
        return
            stakingEnabled
                ? balanceOf(account).mul(stakingBonus[account].add(100)).div(
                    100
                )
                : balanceOf(account);
    }

    function swapAndLiquify(uint256 tokens) private {
        // split the contract balance into halves
        uint256 half = tokens.div(2);
        uint256 otherHalf = tokens.sub(half);

        // capture the contract's current ETH balance.
        // this is so that we can capture exactly the amount of ETH that the
        // swap creates, and not make the liquidity event include any ETH that
        // has been manually sent to the contract
        uint256 initialBalance = address(this).balance;

        // swap tokens for ETH
        swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered

        // how much ETH did we just swap into?
        uint256 newBalance = address(this).balance.sub(initialBalance);

        // add liquidity to uniswap
        addLiquidity(otherHalf, newBalance);

        emit SwapAndLiquify(half, newBalance, otherHalf);
    }

    function swapTokensForEth(uint256 tokenAmount) private {
        // generate the uniswap pair path of token -> weth
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();

        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // make the swap
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function updatePayoutToken(address token) public {
        require(balanceOf(msg.sender) > 0);
        require(token != address(this));

        dividendTracker.updatePayoutToken(msg.sender, token);
        emit UpdatePayoutToken(msg.sender, token);
    }

    function getPayoutToken(address account) public view returns (address) {
        return dividendTracker.getPayoutToken(account);
    }

    function updateAllowTokens(address token, bool allow) public onlyOwner {
        require(token != address(this));

        dividendTracker.updateAllowTokens(token, allow);
        emit UpdateAllowTokens(token, allow);
    }

    function getAllowTokens(address token) public view returns (bool) {
        return dividendTracker.getAllowTokens(token);
    }

    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            liquidityWallet,
            block.timestamp
        );
    }

    function forceSwapAndSendDividends(uint256 tokens) public onlyOwner {
        uint256 totalAmount = buyAmount.add(sellAmount);
        uint256 fromBuy = tokens.mul(buyAmount).div(totalAmount);
        uint256 fromSell = tokens.mul(sellAmount).div(totalAmount);

        swapAndSendDividends(tokens);

        buyAmount = buyAmount.sub(fromBuy);
        sellAmount = sellAmount.sub(fromSell);
    }

    function swapAndSendDividends(uint256 tokens) private {
        swapTokensForEth(tokens);
        uint256 totalAmount = buyAmount.add(sellAmount);

        uint256 dividendsFromBuy = address(this)
            .balance
            .mul(buyAmount)
            .div(totalAmount)
            .mul(FTMRewardsBuyFee)
            .div(FTMRewardsBuyFee.add(operationsFees));

        uint256 dividendsFromSell = address(this)
            .balance
            .mul(sellAmount)
            .div(totalAmount)
            .mul(FTMRewardsSellFee)
            .div(FTMRewardsSellFee.add(operationsFees));

        uint256 dividends = dividendsFromBuy.add(dividendsFromSell);

        (bool success, ) = address(dividendTracker).call{value: dividends}("");

        uint256 theRest = address(this).balance;
        uint256 half = theRest.div(2);
        uint256 otherHalf = theRest - half;
        (bool successOp1, ) = address(operations1Address).call{value: half}("");

        (bool successOp2, ) = address(operations2Address).call{
            value: otherHalf
        }("");

        emit SendDividends(
            dividends,
            theRest,
            success && successOp1 && successOp2
        );
    }
}

contract DiversiFiDividendTracker is DividendPayingToken, Ownable {
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using IterableMapping for IterableMapping.Map;

    IterableMapping.Map private tokenHoldersMap;
    uint256 public lastProcessedIndex;

    mapping(address => bool) public excludedFromDividends;
    mapping(address => bool) public excludedFromAutoClaim;
    mapping(address => bool) public autoReinvest;
    mapping(address => address) public payoutToken;
    mapping(address => bool) public allowTokens;
    bool public allowCustomTokens;
    bool public allowAutoReinvest;
    bool public dividendsPaused = false;

    IUniswapV2Router02 public uniswapV2Router;

    DiversiFi public diversiFi;

    mapping(address => uint256) public lastClaimTimes;

    uint256 public immutable minimumTokenBalanceForAutoDividends;
    uint256 public immutable minimumTokenBalanceForDividends;

    event ExcludeFromDividends(address indexed account);
    event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
    event DividendReinvested(
        address indexed acount,
        uint256 value,
        bool indexed automatic
    );
    event Claim(
        address indexed account,
        uint256 amount,
        bool indexed automatic
    );
    event DividendsPaused(bool paused);
    event SetAllowCustomTokens(bool allow);
    event SetAllowAutoReinvest(bool allow);

    constructor(address payable mainContract)
        DividendPayingToken(
            "DiversiFi_Dividend_Tracker",
            "DiversiFi_Dividend_Tracker"
        )
    {
        diversiFi = DiversiFi(mainContract);
        minimumTokenBalanceForAutoDividends = 1000 * (10**9);
        minimumTokenBalanceForDividends = 100 * (10**9);

        uniswapV2Router = IUniswapV2Router02(
            0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506 
        );
        allowCustomTokens = true;
        allowAutoReinvest = true;
    }

    function decimals() public view virtual override returns (uint8) {
        return 9;
    }

    function _transfer(
        address,
        address,
        uint256
    ) internal pure override {
        require(false, "DiversiFi_Dividend_Tracker: No transfers allowed");
    }

    function withdrawDividend() public pure override {
        require(
            false,
            "DiversiFi_Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main DiversiFi contract."
        );
    }

    function isExcludedFromAutoClaim(address account)
        external
        view
        onlyOwner
        returns (bool)
    {
        return excludedFromAutoClaim[account];
    }

    function isReinvest(address account)
        external
        view
        onlyOwner
        returns (bool)
    {
        return autoReinvest[account];
    }

    function setAllowCustomTokens(bool allow) external onlyOwner {
        require(allowCustomTokens != allow);
        allowCustomTokens = allow;
        emit SetAllowCustomTokens(allow);
    }

    function setAllowAutoReinvest(bool allow) external onlyOwner {
        require(allowAutoReinvest != allow);
        allowAutoReinvest = allow;
        emit SetAllowAutoReinvest(allow);
    }

    function excludeFromDividends(address account) external onlyOwner {
        require(!excludedFromDividends[account]);
        excludedFromDividends[account] = true;

        _setBalance(account, 0);
        tokenHoldersMap.remove(account);

        emit ExcludeFromDividends(account);
    }

    function setAutoClaim(address account, bool value) external onlyOwner {
        excludedFromAutoClaim[account] = value;
    }

    function setReinvest(address account, bool value) external onlyOwner {
        autoReinvest[account] = value;
    }

    function setDividendsPaused(bool value) external onlyOwner {
        require(dividendsPaused != value);
        dividendsPaused = value;
        emit DividendsPaused(value);
    }

    function getLastProcessedIndex() external view returns (uint256) {
        return lastProcessedIndex;
    }

    function getNumberOfTokenHolders() external view returns (uint256) {
        return tokenHoldersMap.keys.length;
    }

    function getAccount(address _account)
        public
        view
        returns (
            address account,
            int256 index,
            int256 iterationsUntilProcessed,
            uint256 withdrawableDividends,
            uint256 totalDividends,
            uint256 lastClaimTime
        )
    {
        account = _account;

        index = tokenHoldersMap.getIndexOfKey(account);

        iterationsUntilProcessed = -1;

        if (index >= 0) {
            if (uint256(index) > lastProcessedIndex) {
                iterationsUntilProcessed = index.sub(
                    int256(lastProcessedIndex)
                );
            } else {
                uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
                    lastProcessedIndex
                    ? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
                    : 0;

                iterationsUntilProcessed = index.add(
                    int256(processesUntilEndOfArray)
                );
            }
        }

        withdrawableDividends = withdrawableDividendOf(account);
        totalDividends = accumulativeDividendOf(account);

        lastClaimTime = lastClaimTimes[account];
    }

    function getAccountAtIndex(uint256 index)
        public
        view
        returns (
            address,
            int256,
            int256,
            uint256,
            uint256,
            uint256
        )
    {
        if (index >= tokenHoldersMap.size()) {
            return (
                0x0000000000000000000000000000000000000000,
                -1,
                -1,
                0,
                0,
                0
            );
        }

        address account = tokenHoldersMap.getKeyAtIndex(index);

        return getAccount(account);
    }

    function setBalance(address account, uint256 newBalance)
        external
        onlyOwner
    {
        if (excludedFromDividends[account]) {
            return;
        }

        if (newBalance < minimumTokenBalanceForDividends) {
            tokenHoldersMap.remove(account);
            _setBalance(account, 0);

            return;
        }

        _setBalance(account, newBalance);

        if (newBalance >= minimumTokenBalanceForAutoDividends) {
            tokenHoldersMap.set(account, newBalance);
        } else {
            tokenHoldersMap.remove(account);
        }
    }

    function process(uint256 gas)
        public
        returns (
            uint256,
            uint256,
            uint256
        )
    {
        uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;

        if (numberOfTokenHolders == 0 || dividendsPaused) {
            return (0, 0, lastProcessedIndex);
        }

        uint256 _lastProcessedIndex = lastProcessedIndex;

        uint256 gasUsed = 0;

        uint256 gasLeft = gasleft();

        uint256 iterations = 0;
        uint256 claims = 0;

        while (gasUsed < gas && iterations < numberOfTokenHolders) {
            _lastProcessedIndex++;

            if (_lastProcessedIndex >= numberOfTokenHolders) {
                _lastProcessedIndex = 0;
            }

            address account = tokenHoldersMap.keys[_lastProcessedIndex];

            if (!excludedFromAutoClaim[account]) {
                if (processAccount(payable(account), true)) {
                    claims++;
                }
            }

            iterations++;

            uint256 newGasLeft = gasleft();

            if (gasLeft > newGasLeft) {
                gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
            }

            gasLeft = newGasLeft;
        }

        lastProcessedIndex = _lastProcessedIndex;

        return (iterations, claims, lastProcessedIndex);
    }

    function processAccount(address payable account, bool automatic)
        public
        onlyOwner
        returns (bool)
    {
        if (dividendsPaused) {
            return false;
        }

        bool reinvest = autoReinvest[account];

        if (automatic && reinvest && !allowAutoReinvest) {
            return false;
        }

        uint256 amount = reinvest
            ? _reinvestDividendOfUser(account)
            : _withdrawDividendOfUser(account);

        if (amount > 0) {
            lastClaimTimes[account] = block.timestamp;
            if (reinvest) {
                emit DividendReinvested(account, amount, automatic);
            } else {
                emit Claim(account, amount, automatic);
            }
            return true;
        }

        return false;
    }

    function updateUniswapV2Router(address newAddress) public onlyOwner {
        uniswapV2Router = IUniswapV2Router02(newAddress);
    }

    function updatePayoutToken(address account, address token)
        public
        onlyOwner
    {
        require(
            allowTokens[token] || token == address(0),
            "Token not in allow list"
        );
        payoutToken[account] = token;
    }

    function getPayoutToken(address account) public view returns (address) {
        return payoutToken[account];
    }

    function updateAllowTokens(address token, bool allow) public onlyOwner {
        allowTokens[token] = allow;
    }

    function getAllowTokens(address token) public view returns (bool) {
        return allowTokens[token];
    }

    function _reinvestDividendOfUser(address account)
        private
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(account);
        if (_withdrawableDividend > 0) {
            bool success;

            withdrawnDividends[account] = withdrawnDividends[account].add(
                _withdrawableDividend
            );

            address[] memory path = new address[](2);
            path[0] = uniswapV2Router.WETH();
            path[1] = address(diversiFi);

            uint256 prevBalance = diversiFi.balanceOf(address(this));

            // make the swap
            try
                uniswapV2Router
                    .swapExactETHForTokensSupportingFeeOnTransferTokens{
                    value: _withdrawableDividend
                }(
                    0, // accept any amount of Tokens
                    path,
                    address(this),
                    block.timestamp
                )
            {
                uint256 received = diversiFi.balanceOf(address(this)).sub(
                    prevBalance
                );
                if (received > 0) {
                    success = true;
                    diversiFi.transfer(account, received);
                } else {
                    success = false;
                }
            } catch {
                success = false;
            }

            if (!success) {
                withdrawnDividends[account] = withdrawnDividends[account].sub(
                    _withdrawableDividend
                );
                return 0;
            }

            return _withdrawableDividend;
        }

        return 0;
    }

    function _withdrawDividendOfUser(address payable user)
        internal
        override
        returns (uint256)
    {
        uint256 _withdrawableDividend = withdrawableDividendOf(user);
        if (_withdrawableDividend > 0) {
            withdrawnDividends[user] = withdrawnDividends[user].add(
                _withdrawableDividend
            );

            address tokenAddress = payoutToken[user];
            bool success;

            // if no tokenAddress assume ftm payout
            if (
                !allowCustomTokens ||
                tokenAddress == address(0) ||
                !allowTokens[tokenAddress]
            ) {
                (success, ) = user.call{
                    value: _withdrawableDividend,
                    gas: 3000
                }("");
            } else {
                //investor wants to be payed out in a custom token
                address[] memory path = new address[](2);
                path[0] = uniswapV2Router.WETH();
                path[1] = tokenAddress;

                try
                    uniswapV2Router
                        .swapExactETHForTokensSupportingFeeOnTransferTokens{
                        value: _withdrawableDividend
                    }(
                        0, // accept any amount of Tokens
                        path,
                        user,
                        block.timestamp
                    )
                {
                    success = true;
                } catch {
                    success = false;
                }
            }

            if (!success) {
                withdrawnDividends[user] = withdrawnDividends[user].sub(
                    _withdrawableDividend
                );
                return 0;
            } else {
                emit DividendWithdrawn(user, _withdrawableDividend);
            }

            return _withdrawableDividend;
        }

        return 0;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"EnableAccountStaking","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EnableStaking","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"EnableSwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"newValue","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"oldValue","type":"uint256"}],"name":"GasForProcessingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newLiquidityWallet","type":"address"},{"indexed":true,"internalType":"address","name":"oldLiquidityWallet","type":"address"}],"name":"LiquidityWalletUpdated","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":"iterations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claims","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastProcessedIndex","type":"uint256"},{"indexed":true,"internalType":"bool","name":"automatic","type":"bool"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"},{"indexed":true,"internalType":"address","name":"processor","type":"address"}],"name":"ProcessedDividendTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"opAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"SendDividends","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"bool","name":"value","type":"bool"}],"name":"SetAutomatedMarketMakerPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wallet","type":"address"}],"name":"SetPreSaleWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensIntoLiqudity","type":"uint256"}],"name":"SwapAndLiquify","type":"event"},{"anonymous":false,"inputs":[],"name":"TradingEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"allow","type":"bool"}],"name":"UpdateAllowTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"}],"name":"UpdateDividendTracker","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"operations","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"FTMRewardsBuy","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"FTMRewardsSell","type":"uint256"}],"name":"UpdateFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"UpdatePayoutToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UpdateStakingAmounts","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"}],"name":"UpdateUniswapV2Router","type":"event"},{"inputs":[],"name":"FTMRewardsBuyFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FTMRewardsSellFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"automatedMarketMakerPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"dividendTokenBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dividendTracker","outputs":[{"internalType":"contract DiversiFiDividendTracker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"enable","type":"bool"}],"name":"enableStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"enableSwapAndLiquify","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"forceStartTradingAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"forceSwapAndSendDividends","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasForProcessing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAccountDividendsInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getAccountDividendsInfoAtIndex","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"int256","name":"","type":"int256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getAllowTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastProcessedIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNumberOfDividendTokenHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getPayoutToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakingInfo","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDividendsDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromAutoClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isReinvest","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidityWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSellTransactionAmount","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":"operations1Address","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operations2Address","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operationsFees","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":"gas","type":"uint256"}],"name":"processDividendTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"allow","type":"bool"}],"name":"setAllowAutoReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"allow","type":"bool"}],"name":"setAllowCustomTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutoClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setDividendsPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"setPresaleWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"setReinvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakingAmounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakingUntilDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapAndLiquifyEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"allow","type":"bool"}],"name":"updateAllowTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateDividendTracker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"operations","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"FTMRewardsBuy","type":"uint256"},{"internalType":"uint256","name":"FTMRewardsSell","type":"uint256"}],"name":"updateFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"updateGasForProcessing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newLiquidityWallet","type":"address"}],"name":"updateLiquidityWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNum","type":"uint256"}],"name":"updateMaxAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newAddress","type":"address"}],"name":"updateOperations1Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newAddress","type":"address"}],"name":"updateOperations2Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"updatePayoutToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"bonus","type":"uint256"}],"name":"updateStakingAmounts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNum","type":"uint256"}],"name":"updateSwapTokensAtAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateUniswapV2Router","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawableDividendOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040526007805461ffff60a81b191690556361e27f00608052600060088190556009819055600e80546001600160a01b031990811673b2055632af7521e16c57e2dbd943ec0c5e78e07817909155600f80549091167392e5cbb95e1831e732cc26e8fe81431a73fa3d5e17905560105565e35fa931a000601155600460125560016013819055600560148190556015556016805460ff19169091179055620493e0601755348015620000b257600080fd5b506040518060400160405280600981526020016844697665727369466960b81b8152506040518060400160405280600381526020016244466960e81b815250816003908051906020019062000109929190620009ee565b5080516200011f906004906020840190620009ee565b505050600062000134620007b460201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35030604051620001919062000a7d565b6001600160a01b039091168152602001604051809103906000f080158015620001be573d6000803e3d6000fd5b50600c80546001600160a01b039283166001600160a01b031991821617909155600554600d80548316919093161790915560068054731b02da8cb0d097eb8d57a175b88c7d8b479975069216821790556040805163c45a015560e01b8152905163c45a015591600480820192602092909190829003018186803b1580156200024557600080fd5b505afa1580156200025a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000280919062000aa2565b6001600160a01b031663c9c6539630600660009054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b158015620002de57600080fd5b505afa158015620002f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000319919062000aa2565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381600087803b1580156200036257600080fd5b505af115801562000377573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200039d919062000aa2565b600780546001600160a01b0319166001600160a01b03929092169182179055620003c9906001620007b8565b600c5460405163031e79db60e41b81526001600160a01b0390911660048201819052906331e79db090602401600060405180830381600087803b1580156200041057600080fd5b505af115801562000425573d6000803e3d6000fd5b5050600c5460405163031e79db60e41b81523060048201526001600160a01b0390911692506331e79db09150602401600060405180830381600087803b1580156200046f57600080fd5b505af115801562000484573d6000803e3d6000fd5b5050600c5460405163031e79db60e41b815261dead60048201526001600160a01b0390911692506331e79db09150602401600060405180830381600087803b158015620004d057600080fd5b505af1158015620004e5573d6000803e3d6000fd5b5050600c54604051634e7b827f60e01b8152600060048201526001600160a01b039091169250634e7b827f915060240160206040518083038186803b1580156200052e57600080fd5b505afa15801562000543573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000569919062000acb565b50600c546001600160a01b03166331e79db06200058e6005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015620005d057600080fd5b505af1158015620005e5573d6000803e3d6000fd5b5050600c5460065460405163031e79db60e41b81526001600160a01b039182166004820152911692506331e79db09150602401600060405180830381600087803b1580156200063357600080fd5b505af115801562000648573d6000803e3d6000fd5b5050600d546001600160a01b031660009081526018602081905260408083208054600160ff19918216811790925530855291842080549092168117909155935091506200069d6005546001600160a01b031690565b6001600160a01b03908116825260208083019390935260409182016000908120805495151560ff19968716179055600c549091168152601883522080549092166001179091556012546013546015546200071a93620007069290620030d162000884821b17901c565b6200088460201b620030d11790919060201c565b600a8190555062000745601254620007066013546014546200088460201b620030d11790919060201c565b600b556001601d6000620007616005546001600160a01b031690565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055620007ae620007a06005546001600160a01b031690565b662386f26fc10000620008f2565b62000b4f565b3390565b6001600160a01b0382166000908152601960205260409020805460ff191682158015919091179091556200084857600c5460405163031e79db60e41b81526001600160a01b038481166004830152909116906331e79db090602401600060405180830381600087803b1580156200082e57600080fd5b505af115801562000843573d6000803e3d6000fd5b505050505b604051811515906001600160a01b038416907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab90600090a35050565b60008062000893838562000aed565b905083811015620008eb5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064015b60405180910390fd5b9392505050565b6001600160a01b0382166200094a5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401620008e2565b62000966816002546200088460201b620030d11790919060201c565b6002556001600160a01b0382166000908152602081815260409091205462000999918390620030d162000884821b17901c565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b828054620009fc9062000b12565b90600052602060002090601f01602090048101928262000a20576000855562000a6b565b82601f1062000a3b57805160ff191683800117855562000a6b565b8280016001018555821562000a6b579182015b8281111562000a6b57825182559160200191906001019062000a4e565b5062000a7992915062000a8b565b5090565b613486806200536e83390190565b5b8082111562000a79576000815560010162000a8c565b60006020828403121562000ab4578081fd5b81516001600160a01b0381168114620008eb578182fd5b60006020828403121562000add578081fd5b81518015158114620008eb578182fd5b6000821982111562000b0d57634e487b7160e01b81526011600452602481fd5b500190565b600181811c9082168062000b2757607f821691505b6020821081141562000b4957634e487b7160e01b600052602260045260246000fd5b50919050565b6080516147fc62000b7260003960008181610e4301526136ed01526147fc6000f3fe60806040526004361061050b5760003560e01c806388bdd9be11610294578063c32c293d1161015e578063e2f45605116100d6578063f1c0ddff1161008a578063f2fde38b1161006f578063f2fde38b14610ec8578063f5d3c79a14610ee8578063fd957f4214610f0857600080fd5b8063f1c0ddff14610e7b578063f27fd25414610ea857600080fd5b8063e7841ec0116100bb578063e7841ec014610e1c578063ed37af0b14610e31578063f1bdd7ab14610e6557600080fd5b8063e2f4560514610de6578063e37ba8f914610dfc57600080fd5b8063d257b34f1161012d578063d5e3725111610112578063d5e3725114610d60578063d8032ed314610d80578063dd62ed3e14610da057600080fd5b8063d257b34f14610d20578063d469801614610d4057600080fd5b8063c32c293d14610ca0578063c6616ba114610cc0578063cd66056a14610ce0578063d07a091c14610d0057600080fd5b8063a457c2d71161020c578063ad56c13c116101c0578063b62496f5116101a5578063b62496f514610c30578063ba079d4914610c60578063c024666814610c8057600080fd5b8063ad56c13c14610bc3578063b5cc797c14610c1a57600080fd5b8063a8b9d240116101f1578063a8b9d24014610b2b578063a9059cbb14610b4b578063aa4704f314610b6b57600080fd5b8063a457c2d714610aeb578063a694fc3a14610b0b57600080fd5b806398118cb4116102635780639c1b8af5116102485780639c1b8af514610a955780639c3372ea14610aab5780639cefc1da14610acb57600080fd5b806398118cb414610a5f5780639a7a23d614610a7557600080fd5b806388bdd9be146109f75780638a8c523c14610a175780638da5cb5b14610a2c57806395d89b4114610a4a57600080fd5b80634912572c116103d557806364b0f6531161034d57806370a08231116103015780637d32f342116102e65780637d32f3421461098a578063868730c7146109b7578063871c128d146109d757600080fd5b806370a082311461093f578063715018a61461097557600080fd5b80636843cd84116103325780636843cd84146108df5780636d48467b146108ff578063700bb1911461091f57600080fd5b806364b0f653146108aa57806365b8dbc0146108bf57600080fd5b80634e71d92d116103a457806350151d991161038957806350151d991461084a5780635123425b1461086a5780635b72c18c1461088a57600080fd5b80634e71d92d146107fc5780634fbee1931461081157600080fd5b80634912572c1461078157806349bd5a5e146107a15780634a74bb02146107c15780634ada218b146107db57600080fd5b806323b872dd116104835780633599bb17116104375780633f407b841161041c5780633f407b841461071e57806340ffdd8014610734578063435c89e41461075457600080fd5b80633599bb17146106de57806339509351146106fe57600080fd5b80632c4c1841116104685780632c4c18411461069757806330bb4cff146106ad578063313ce567146106c257600080fd5b806323b872dd146106575780632c1f52161461067757600080fd5b80630ef35b7e116104da5780631694505e116104bf5780631694505e146105f457806318160ddd1461062c5780631fa705311461064157600080fd5b80630ef35b7e146105b4578063106b5da1146105d457600080fd5b806302259e9e1461051757806305ca5f081461054057806306fdde0314610562578063095ea7b31461058457600080fd5b3661051257005b600080fd5b34801561052357600080fd5b5061052d60105481565b6040519081526020015b60405180910390f35b34801561054c57600080fd5b5061056061055b3660046144df565b610f28565b005b34801561056e57600080fd5b50610577610fff565b604051610537919061458e565b34801561059057600080fd5b506105a461059f36600461447c565b611091565b6040519015158152602001610537565b3480156105c057600080fd5b506105606105cf36600461450f565b6110a8565b3480156105e057600080fd5b506105606105ef3660046144df565b6111ad565b34801561060057600080fd5b50600654610614906001600160a01b031681565b6040516001600160a01b039091168152602001610537565b34801561063857600080fd5b5060025461052d565b34801561064d57600080fd5b5061052d60095481565b34801561066357600080fd5b506105a46106723660046143bd565b6112c6565b34801561068357600080fd5b50600c54610614906001600160a01b031681565b3480156106a357600080fd5b5061052d60155481565b3480156106b957600080fd5b5061052d61132f565b3480156106ce57600080fd5b5060405160098152602001610537565b3480156106ea57600080fd5b506105606106f93660046144a7565b6113ca565b34801561070a57600080fd5b506105a461071936600461447c565b61148e565b34801561072a57600080fd5b5061052d60085481565b34801561074057600080fd5b5061056061074f3660046144a7565b6114c4565b34801561076057600080fd5b5061052d61076f3660046144df565b601c6020526000908152604090205481565b34801561078d57600080fd5b50600e54610614906001600160a01b031681565b3480156107ad57600080fd5b50600754610614906001600160a01b031681565b3480156107cd57600080fd5b506016546105a49060ff1681565b3480156107e757600080fd5b506007546105a490600160b01b900460ff1681565b34801561080857600080fd5b50610560611557565b34801561081d57600080fd5b506105a461082c36600461434d565b6001600160a01b031660009081526018602052604090205460ff1690565b34801561085657600080fd5b5061056061086536600461434d565b6115f7565b34801561087657600080fd5b506105606108853660046143fd565b611661565b34801561089657600080fd5b506105a46108a536600461434d565b611780565b3480156108b657600080fd5b5061052d611818565b3480156108cb57600080fd5b506105606108da36600461434d565b611876565b3480156108eb57600080fd5b5061052d6108fa36600461434d565b611976565b34801561090b57600080fd5b506105a461091a36600461434d565b611a0e565b34801561092b57600080fd5b5061056061093a3660046144df565b611a5a565b34801561094b57600080fd5b5061052d61095a36600461434d565b6001600160a01b031660009081526020819052604090205490565b34801561098157600080fd5b50610560611b51565b34801561099657600080fd5b5061052d6109a536600461434d565b601b6020526000908152604090205481565b3480156109c357600080fd5b506105606109d23660046144a7565b611be3565b3480156109e357600080fd5b506105606109f23660046144df565b611c34565b348015610a0357600080fd5b50610560610a1236600461434d565b611cce565b348015610a2357600080fd5b50610560611faf565b348015610a3857600080fd5b506005546001600160a01b0316610614565b348015610a5657600080fd5b50610577612067565b348015610a6b57600080fd5b5061052d60135481565b348015610a8157600080fd5b50610560610a903660046143fd565b612076565b348015610aa157600080fd5b5061052d60175481565b348015610ab757600080fd5b50610560610ac63660046144a7565b6120e7565b348015610ad757600080fd5b50610560610ae63660046144a7565b61217a565b348015610af757600080fd5b506105a4610b0636600461447c565b612253565b348015610b1757600080fd5b50610560610b263660046144df565b6122a2565b348015610b3757600080fd5b5061052d610b4636600461434d565b6124e3565b348015610b5757600080fd5b506105a4610b6636600461447c565b61252f565b348015610b7757600080fd5b50610bae610b8636600461434d565b6001600160a01b03166000908152601b6020908152604080832054601a909252909120549091565b60408051928352602083019190915201610537565b348015610bcf57600080fd5b50610be3610bde36600461434d565b61253c565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c001610537565b348015610c2657600080fd5b5061052d60125481565b348015610c3c57600080fd5b506105a4610c4b36600461434d565b60196020526000908152604090205460ff1681565b348015610c6c57600080fd5b506105a4610c7b36600461434d565b6125f4565b348015610c8c57600080fd5b50610560610c9b3660046143fd565b612640565b348015610cac57600080fd5b50610614610cbb36600461434d565b612713565b348015610ccc57600080fd5b50610560610cdb36600461455d565b6127aa565b348015610cec57600080fd5b50600f54610614906001600160a01b031681565b348015610d0c57600080fd5b50610560610d1b36600461434d565b612a06565b348015610d2c57600080fd5b50610560610d3b3660046144df565b612b1c565b348015610d4c57600080fd5b50600d54610614906001600160a01b031681565b348015610d6c57600080fd5b50610560610d7b3660046144a7565b612c05565b348015610d8c57600080fd5b50610560610d9b36600461434d565b612ca4565b348015610dac57600080fd5b5061052d610dbb366004614385565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610df257600080fd5b5061052d60115481565b348015610e0857600080fd5b50610560610e1736600461434d565b612d91565b348015610e2857600080fd5b5061052d612e41565b348015610e3d57600080fd5b5061052d7f000000000000000000000000000000000000000000000000000000000000000081565b348015610e7157600080fd5b5061052d60145481565b348015610e8757600080fd5b5061052d610e9636600461434d565b601a6020526000908152604090205481565b348015610eb457600080fd5b50610be3610ec33660046144df565b612e9f565b348015610ed457600080fd5b50610560610ee336600461434d565b612ef6565b348015610ef457600080fd5b50610560610f033660046144a7565b613016565b348015610f1457600080fd5b50610560610f2336600461434d565b613067565b6005546001600160a01b03163314610f755760405162461bcd60e51b8152602060048201819052602482015260008051602061478283398151915260448201526064015b60405180910390fd5b6000610f8e6008546009546130d190919063ffffffff16565b90506000610fb182610fab6009548661313790919063ffffffff16565b906131d2565b90506000610fce83610fab6008548761313790919063ffffffff16565b9050610fd984613214565b600954610fe69083613454565b600955600854610ff69082613454565b60085550505050565b60606003805461100e906146bf565b80601f016020809104026020016040519081016040528092919081815260200182805461103a906146bf565b80156110875780601f1061105c57610100808354040283529160200191611087565b820191906000526020600020905b81548152906001019060200180831161106a57829003601f168201915b5050505050905090565b600061109e338484613496565b5060015b92915050565b6005546001600160a01b031633146110f05760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6000828152601c602052604090205481141561110b57600080fd5b6101f481111561115d5760405162461bcd60e51b815260206004820152601f60248201527f5374616b696e6720626f6e75732063616e2774206578636565642035303025006044820152606401610f6c565b6000828152601c602090815260409182902083905581518481529081018390527f065c0eec5c5d031ee25323575d53db5536226ab058b74d8bdb03c517dd4f605d91015b60405180910390a15050565b6005546001600160a01b031633146111f55760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b80601054141561120457600080fd5b601054158061121a575064e8d4a5100060105410155b6112b25760405162461bcd60e51b815260206004820152604260248201527f6d61782073656c6c20616d6f756e74206d75737420656974686572206265206460448201527f697361626c6564206f722067726561746572207468616e20312074686f75736160648201527f6e64000000000000000000000000000000000000000000000000000000000000608482015260a401610f6c565b6112c081633b9aca00614689565b60105550565b60006112d38484846135ef565b61132584336113208560405180606001604052806028815260200161475a602891396001600160a01b038a1660009081526001602090815260408083203384529091529020549190613d08565b613496565b5060019392505050565b600c54604080517f85a6b3ae00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916385a6b3ae916004808301926020929190829003018186803b15801561138d57600080fd5b505afa1580156113a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c591906144f7565b905090565b6005546001600160a01b031633146114125760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600c546040517f3599bb1700000000000000000000000000000000000000000000000000000000815282151560048201526001600160a01b0390911690633599bb17906024015b600060405180830381600087803b15801561147357600080fd5b505af1158015611487573d6000803e3d6000fd5b5050505050565b3360008181526001602090815260408083206001600160a01b0387168452909152812054909161109e91859061132090866130d1565b6005546001600160a01b0316331461150c5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600c546040517f40ffdd8000000000000000000000000000000000000000000000000000000000815282151560048201526001600160a01b03909116906340ffdd8090602401611459565b600c546040517fbc4c4b37000000000000000000000000000000000000000000000000000000008152336004820152600060248201526001600160a01b039091169063bc4c4b3790604401602060405180830381600087803b1580156115bc57600080fd5b505af11580156115d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f491906144c3565b50565b6005546001600160a01b0316331461163f5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b031633146116a95760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6001600160a01b0382163014156116bf57600080fd5b600c546040517f5123425b0000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152831515602483015290911690635123425b90604401600060405180830381600087803b15801561172757600080fd5b505af115801561173b573d6000803e3d6000fd5b5050604080516001600160a01b038616815284151560208201527ff8e5e8c18b9fbb7607019e8dab60e0ad981ba259df038a668fc13025a64854d693500190506111a1565b600c546040517f5b72c18c0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000921690635b72c18c906024015b60206040518083038186803b1580156117e057600080fd5b505afa1580156117f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a291906144c3565b600c54604080517f09bbedde00000000000000000000000000000000000000000000000000000000815290516000926001600160a01b0316916309bbedde916004808301926020929190829003018186803b15801561138d57600080fd5b6005546001600160a01b031633146118be5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6006546001600160a01b03828116911614156118d957600080fd5b6006546040516001600160a01b03918216918316907f8fc842bbd331dfa973645f4ed48b11683d501ebf1352708d77a5da2ab49a576e90600090a3600680546001600160a01b0319166001600160a01b03838116918217909255600c546040517f65b8dbc00000000000000000000000000000000000000000000000000000000081526004810192909252909116906365b8dbc090602401611459565b600c546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03838116600483015260009216906370a08231906024015b60206040518083038186803b1580156119d657600080fd5b505afa1580156119ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a291906144f7565b600c546040517f6d48467b0000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301526000921690636d48467b906024016117c8565b600c546040517fffb2c47900000000000000000000000000000000000000000000000000000000815260048101839052600091829182916001600160a01b03169063ffb2c47990602401606060405180830381600087803b158015611abe57600080fd5b505af1158015611ad2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af69190614530565b604080518481526020810184905290810182905260608101889052929550909350915032906000907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a350505050565b6005546001600160a01b03163314611b995760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b600c546040517f8bc1d63900000000000000000000000000000000000000000000000000000000815233600482015282151560248201526001600160a01b0390911690638bc1d63990604401611459565b6005546001600160a01b03163314611c7c5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b62030d408110158015611c925750620927c08111155b611c9b57600080fd5b60175460405182907f40d7e40e79af4e8e5a9b3c57030d8ea93f13d669c06d448c4d631d4ae7d23db790600090a3601755565b6005546001600160a01b03163314611d165760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600c546001600160a01b0382811691161415611d3157600080fd5b6000819050306001600160a01b0316816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611d7957600080fd5b505afa158015611d8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611db19190614369565b6001600160a01b031614611dc457600080fd5b60405163031e79db60e41b81526001600160a01b03821660048201819052906331e79db090602401600060405180830381600087803b158015611e0657600080fd5b505af1158015611e1a573d6000803e3d6000fd5b505060405163031e79db60e41b81523060048201526001600160a01b03841692506331e79db09150602401600060405180830381600087803b158015611e5f57600080fd5b505af1158015611e73573d6000803e3d6000fd5b50505050806001600160a01b03166331e79db0611e986005546001600160a01b031690565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b158015611ed957600080fd5b505af1158015611eed573d6000803e3d6000fd5b505060065460405163031e79db60e41b81526001600160a01b03918216600482015290841692506331e79db09150602401600060405180830381600087803b158015611f3857600080fd5b505af1158015611f4c573d6000803e3d6000fd5b5050600c546040516001600160a01b03918216935090851691507f90c7d74461c613da5efa97d90740869367d74ab3aa5837aa4ae9a975f954b7a890600090a3600c80546001600160a01b0319166001600160a01b039290921691909117905550565b6005546001600160a01b03163314611ff75760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600754600160b01b900460ff161561200e57600080fd5b600780547fffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffff16600160b01b1790556040517f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c790600090a1565b60606004805461100e906146bf565b6005546001600160a01b031633146120be5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6007546001600160a01b03838116911614156120d957600080fd5b6120e38282613d42565b5050565b6005546001600160a01b0316331461212f5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600c546040517f9c3372ea00000000000000000000000000000000000000000000000000000000815282151560048201526001600160a01b0390911690639c3372ea90602401611459565b6005546001600160a01b031633146121c25760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b60075460ff600160a81b90910416151581151514156121e057600080fd5b60078054821515600160a81b027fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff9091161790556040517f0d240c24014ec8c204fc1bdcc286f7d01fd2ab6a07c558a9b2d3f12904323a879061224890831515815260200190565b60405180910390a150565b600061109e3384611320856040518060600160405280602581526020016147a2602591393360009081526001602090815260408083206001600160a01b038d1684529091529020549190613d08565b600754600160a81b900460ff166122fb5760405162461bcd60e51b815260206004820152601660248201527f5374616b696e67206973206e6f7420656e61626c6564000000000000000000006044820152606401610f6c565b6000818152601c60205260409020546123565760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207374616b696e67206475726174696f6e00000000000000006044820152606401610f6c565b61236042826130d1565b336000908152601b6020526040902054106123e25760405162461bcd60e51b8152602060048201526024808201527f616c7265616479207374616b656420666f722061206c6f6e676572206475726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610f6c565b6000818152601c6020908152604080832054338452601a9092529091205561240a42826130d1565b336000818152601b6020526040902091909155600c546001600160a01b03169063e30443bc9061243981613e0b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561247f57600080fd5b505af1158015612493573d6000803e3d6000fd5b5050505061249e3390565b6001600160a01b03167f13dd201d7da4f9b31a9064a09abc1a6ce420dacd837a77abafaec5bd9d28d2c8826040516124d891815260200190565b60405180910390a250565b600c546040517fa8b9d2400000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092169063a8b9d240906024016119be565b600061109e3384846135ef565b600c546040517ffbcbc0f10000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092839283928392839283929091169063fbcbc0f1906024015b60c06040518083038186803b1580156125a857600080fd5b505afa1580156125bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e0919061442a565b949c939b5091995097509550909350915050565b600c546040517fba079d490000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092169063ba079d49906024016117c8565b6005546001600160a01b031633146126885760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6001600160a01b03821660009081526018602052604090205460ff16151581151514156126b457600080fd5b6001600160a01b038216600081815260186020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b600c546040517fc32c293d0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152600092169063c32c293d9060240160206040518083038186803b15801561277257600080fd5b505afa158015612786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a29190614369565b6005546001600160a01b031633146127f25760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b60148411156128435760405162461bcd60e51b815260206004820152601f60248201527f6f7065726174696f6e20666565732063616e27742065786365656420323025006044820152606401610f6c565b60148311156128945760405162461bcd60e51b815260206004820152601f60248201527f6c697175696469747920666565732063616e27742065786365656420323025006044820152606401610f6c565b600182101580156128a6575060328211155b6129035760405162461bcd60e51b815260206004820152602860248201527f46544d207265776172642066656573206d757374206265206265747765656e2060448201526703120616e642035360c41b6064820152608401610f6c565b60018110158015612915575060328111155b6129725760405162461bcd60e51b815260206004820152602860248201527f46544d207265776172642066656573206d757374206265206265747765656e2060448201526703120616e642035360c41b6064820152608401610f6c565b601284905560138390556014829055601581905561299a8461299483866130d1565b906130d1565b600a556012546013546014546129b5929161299491906130d1565b600b556040805185815260208101859052908101839052606081018290527f5c3aee3d65f7eb02cded951435d06b06ef307bc7f57b98975c4a41dc116e711c9060800160405180910390a150505050565b6005546001600160a01b03163314612a4e5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6001600160a01b038181166000818152601d602090815260408083208054600160ff19918216811790925560189093529281902080549092169092179055600c54905163031e79db60e41b81526004810192909252909116906331e79db090602401600060405180830381600087803b158015612aca57600080fd5b505af1158015612ade573d6000803e3d6000fd5b50506040516001600160a01b03841681527f85d097e432d8e396fa72c83ebd34196326e1cf1694ef910cd53554b2ee7597c592506020019050612248565b6005546001600160a01b03163314612b645760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b806011541415612b7357600080fd5b652d79883d20006011541015612bf15760405162461bcd60e51b815260206004820152603260248201527f5377617020546f6b656e20416d6f756e74206d7573742062652067726561746560448201527f72207468616e2035302074686f7573616e6400000000000000000000000000006064820152608401610f6c565b612bff81633b9aca00614689565b60115550565b6005546001600160a01b03163314612c4d5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b60165460ff1615158115151415612c6357600080fd5b6016805460ff19168215159081179091556040519081527fff5917043f8453af413305b2dbd1ed9748a37df481beb71ba4b9b212a07b9bef90602001612248565b3360009081526020819052604081205411612cbe57600080fd5b6001600160a01b038116301415612cd457600080fd5b600c546040517ff7dd53a90000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0383811660248301529091169063f7dd53a990604401600060405180830381600087803b158015612d3a57600080fd5b505af1158015612d4e573d6000803e3d6000fd5b5050604080513381526001600160a01b03851660208201527f3640c981ed7cfa9e689ac4e9cafffd8c9240b716b14c982b3e90d54e7b61de249350019050612248565b6005546001600160a01b03163314612dd95760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b612de4816001612640565b600d546040516001600160a01b03918216918316907f6080503d1da552ae8eb4b7b8a20245d9fabed014180510e7d1a05ea08fdb0f3e90600090a3600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600c54604080517fe7841ec000000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163e7841ec0916004808301926020929190829003018186803b15801561138d57600080fd5b600c546040517f5183d6fd00000000000000000000000000000000000000000000000000000000815260048101839052600091829182918291829182916001600160a01b0390911690635183d6fd90602401612590565b6005546001600160a01b03163314612f3e5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b6001600160a01b038116612fba5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610f6c565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b600c546040517fb22f8a0400000000000000000000000000000000000000000000000000000000815233600482015282151560248201526001600160a01b039091169063b22f8a0490604401611459565b6005546001600160a01b031633146130af5760405162461bcd60e51b815260206004820181905260248201526000805160206147828339815191526044820152606401610f6c565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6000806130de8385614651565b9050838110156131305760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610f6c565b9392505050565b600082613146575060006110a2565b60006131528385614689565b90508261315f8583614669565b146131305760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60448201527f77000000000000000000000000000000000000000000000000000000000000006064820152608401610f6c565b600061313083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613e89565b61321d81613eb7565b60006132366008546009546130d190919063ffffffff16565b905060006132796132546012546014546130d190919063ffffffff16565b610fab60145461327386610fab6009544761313790919063ffffffff16565b90613137565b905060006132b66132976012546015546130d190919063ffffffff16565b610fab60155461327387610fab6008544761313790919063ffffffff16565b905060006132c483836130d1565b600c546040519192506000916001600160a01b039091169083908381818185875af1925050503d8060008114613316576040519150601f19603f3d011682016040523d82523d6000602084013e61331b565b606091505b50909150479050600061332f8260026131d2565b9050600061333d82846146a8565b600e546040519192506000916001600160a01b039091169084908381818185875af1925050503d806000811461338f576040519150601f19603f3d011682016040523d82523d6000602084013e613394565b606091505b5050600f546040519192506000916001600160a01b039091169084908381818185875af1925050503d80600081146133e8576040519150601f19603f3d011682016040523d82523d6000602084013e6133ed565b606091505b505090507f8e09ec88c0d24c22e3a9b8555c029afcc4a7c609daabf6d7849e814c2d14efd0878688801561341e5750845b80156134275750835b60408051938452602084019290925215159082015260600160405180910390a15050505050505050505050565b600061313083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d08565b6001600160a01b0383166135115760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f6c565b6001600160a01b03821661358d5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f6c565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383166136535760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610f6c565b6001600160a01b0382166136b55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610f6c565b600754600160b01b900460ff16806136e557506001600160a01b0383166000908152601d602052604090205460ff165b8061371057507f00000000000000000000000000000000000000000000000000000000000000004210155b61375c5760405162461bcd60e51b815260206004820181905260248201527f54726164696e6720686173206e6f7420796574206265656e20656e61626c65646044820152606401610f6c565b806137725761376d8383600061406e565b505050565b600754600160a01b900460ff161580156137a557506001600160a01b03831660009081526018602052604090205460ff16155b80156137ca57506001600160a01b03821660009081526018602052604090205460ff16155b15613c04576001600160a01b0380831660009081526019602052604080822054928616825290205460ff918216911615801561380f5750600754600160a81b900460ff165b156138c1576001600160a01b0384166000908152601b602052604090205442101561387c5760405162461bcd60e51b815260206004820152601d60248201527f546f6b656e7320617265207374616b656420616e64206c6f636b6564210000006044820152606401610f6c565b6001600160a01b0384166000908152601b6020526040902054156138c1576001600160a01b0384166000908152601b60209081526040808320839055601a9091528120555b600081156138d257506015546138d7565b506014545b60006138f4601254612994601354856130d190919063ffffffff16565b90506010546000141580156139065750825b801561392057506006546001600160a01b03878116911614155b15613977576010548411156139775760405162461bcd60e51b815260206004820152601960248201527f6d617853656c6c5472616e73616374696f6e416d6f756e742e000000000000006044820152606401610f6c565b30600090815260208190526040902054601154811080159081906139b457506001600160a01b03881660009081526019602052604090205460ff16155b15613aba576007805460ff60a01b1916600160a01b17905560165460ff1615613a885760006139f06008546009546130d190919063ffffffff16565b90506000613a0d82610fab6009548761313790919063ffffffff16565b90506000613a2a83610fab6008548861313790919063ffffffff16565b90506000613a49600b54610fab6013548661313790919063ffffffff16565b90506000613a68600a54610fab6013548661313790919063ffffffff16565b90506000613a7682846130d1565b9050613a81816141f1565b5050505050505b30600090815260208190526040902054613aa181613214565b50600060098190556008556007805460ff60a01b191690555b6000613acb6064610fab8987613137565b9050613ad78782613454565b96508515613af457600854613aec90826130d1565b600855613b05565b600954613b0190826130d1565b6009555b613b1089308361406e565b601754600c546040517fffb2c479000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b039091169063ffb2c47990602401606060405180830381600087803b158015613b7257600080fd5b505af1925050508015613ba2575060408051601f3d908101601f19168201909252613b9f91810190614530565b60015b613bab57613bfc565b60408051848152602081018490529081018290526060810185905232906001907fc864333d6121033635ab41b29ae52f10a22cf4438c3e4f1c4c68518feb2f8a989060800160405180910390a35050505b505050505050505b613c0f83838361406e565b600c546001600160a01b031663e30443bc84613c2a81613e0b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613c7057600080fd5b505af1158015613c84573d6000803e3d6000fd5b5050600c546001600160a01b0316915063e30443bc905083613ca581613e0b565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613ceb57600080fd5b505af1158015613cff573d6000803e3d6000fd5b50505050505050565b60008184841115613d2c5760405162461bcd60e51b8152600401610f6c919061458e565b506000613d3984866146a8565b95945050505050565b6001600160a01b0382166000908152601960205260409020805460ff19168215801591909117909155613dcf57600c5460405163031e79db60e41b81526001600160a01b038481166004830152909116906331e79db090602401600060405180830381600087803b158015613db657600080fd5b505af1158015613dca573d6000803e3d6000fd5b505050505b604051811515906001600160a01b038416907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab90600090a35050565b600754600090600160a81b900460ff16613e3d576001600160a01b0382166000908152602081905260409020546110a2565b6001600160a01b0382166000908152601a60205260409020546110a290606490610fab90613e6b90836130d1565b6001600160a01b038616600090815260208190526040902054613273565b60008183613eaa5760405162461bcd60e51b8152600401610f6c919061458e565b506000613d398486614669565b6040805160028082526060820183526000926020830190803683370190505090503081600081518110613efa57634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201810191909152600654604080517fad5c46480000000000000000000000000000000000000000000000000000000081529051919093169263ad5c4648926004808301939192829003018186803b158015613f6757600080fd5b505afa158015613f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f9f9190614369565b81600181518110613fc057634e487b7160e01b600052603260045260246000fd5b6001600160a01b039283166020918202929092010152600654613fe69130911684613496565b6006546040517f791ac9470000000000000000000000000000000000000000000000000000000081526001600160a01b039091169063791ac947906140389085906000908690309042906004016145e1565b600060405180830381600087803b15801561405257600080fd5b505af1158015614066573d6000803e3d6000fd5b505050505050565b6001600160a01b0383166140d25760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610f6c565b6001600160a01b0382166141345760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610f6c565b61417181604051806060016040528060268152602001614734602691396001600160a01b0386166000908152602081905260409020549190613d08565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546141a090826130d1565b6001600160a01b038381166000818152602081815260409182902094909455518481529092918616917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016135e2565b60006141fe8260026131d2565b9050600061420c8383613454565b90504761421883613eb7565b60006142244783613454565b90506142308382614278565b60408051858152602081018390529081018490527f17bbfb9a6069321b6ded73bd96327c9e6b7212a5cd51ff219cd61370acafb5619060600160405180910390a15050505050565b6006546142909030906001600160a01b031684613496565b600654600d546040517ff305d7190000000000000000000000000000000000000000000000000000000081523060048201526024810185905260006044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990839060c4016060604051808303818588803b15801561431457600080fd5b505af1158015614328573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906114879190614530565b60006020828403121561435e578081fd5b813561313081614710565b60006020828403121561437a578081fd5b815161313081614710565b60008060408385031215614397578081fd5b82356143a281614710565b915060208301356143b281614710565b809150509250929050565b6000806000606084860312156143d1578081fd5b83356143dc81614710565b925060208401356143ec81614710565b929592945050506040919091013590565b6000806040838503121561440f578182fd5b823561441a81614710565b915060208301356143b281614725565b60008060008060008060c08789031215614442578182fd5b865161444d81614710565b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b6000806040838503121561448e578182fd5b823561449981614710565b946020939093013593505050565b6000602082840312156144b8578081fd5b813561313081614725565b6000602082840312156144d4578081fd5b815161313081614725565b6000602082840312156144f0578081fd5b5035919050565b600060208284031215614508578081fd5b5051919050565b60008060408385031215614521578182fd5b50508035926020909101359150565b600080600060608486031215614544578283fd5b8351925060208401519150604084015190509250925092565b60008060008060808587031215614572578182fd5b5050823594602084013594506040840135936060013592509050565b6000602080835283518082850152825b818110156145ba5785810183015185820160400152820161459e565b818111156145cb5783604083870101525b50601f01601f1916929092016040019392505050565b600060a082018783526020878185015260a0604085015281875180845260c0860191508289019350845b818110156146305784516001600160a01b03168352938301939183019160010161460b565b50506001600160a01b03969096166060850152505050608001529392505050565b60008219821115614664576146646146fa565b500190565b60008261468457634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156146a3576146a36146fa565b500290565b6000828210156146ba576146ba6146fa565b500390565b600181811c908216806146d357607f821691505b602082108114156146f457634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146115f457600080fd5b80151581146115f457600080fdfe45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212201a79d6383e041b85f42307ef92c741e58c946b981aa14479f0a14f6676877fce64736f6c6343000804003360c06040526014805462ff0000191690553480156200001d57600080fd5b506040516200348638038062003486833981016040819052620000409162000224565b604080518082018252601a8082527f4469766572736946695f4469766964656e645f547261636b6572000000000000602080840182815285518087019096529285528401528151919291839183916200009c916003916200017e565b508051620000b29060049060208401906200017e565b50505050506000620000c96200017a60201b60201c565b600980546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350601580546001600160a01b0319166001600160a01b039290921691909117905564e8d4a5100060805264174876e80060a0526014805462ff0001600160b81b031916761b02da8cb0d097eb8d57a175b88c7d8b4799750600010117905562000291565b3390565b8280546200018c9062000254565b90600052602060002090601f016020900481019282620001b05760008555620001fb565b82601f10620001cb57805160ff1916838001178555620001fb565b82800160010185558215620001fb579182015b82811115620001fb578251825591602001919060010190620001de565b50620002099291506200020d565b5090565b5b808211156200020957600081556001016200020e565b60006020828403121562000236578081fd5b81516001600160a01b03811681146200024d578182fd5b9392505050565b600181811c908216806200026957607f821691505b602082108114156200028b57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516131c1620002c560003960008181610a1101526117cc0152600081816108c7015261181801526131c16000f3fe6080604052600436106103645760003560e01c806370a08231116101c6578063a9059cbb116100f7578063dd62ed3e11610095578063f2fde38b1161006f578063f2fde38b14610ae7578063f7dd53a914610b07578063fbcbc0f114610b27578063ffb2c47914610b4757600080fd5b8063dd62ed3e14610a6c578063e30443bc14610ab2578063e7841ec014610ad257600080fd5b8063ba079d49116100d1578063ba079d49146109bf578063bc4c4b37146109df578063be10b614146109ff578063c32c293d14610a3357600080fd5b8063a9059cbb14610949578063aafd847a14610969578063b22f8a041461099f57600080fd5b806395d89b4111610164578063a1363cda1161013e578063a1363cda146108b5578063a4234069146108e9578063a457c2d714610909578063a8b9d2401461092957600080fd5b806395d89b41146108665780639c3372ea1461087b5780639eec101e1461089b57600080fd5b806385a6b3ae116101a057806385a6b3ae146107f25780638bc1d639146108085780638da5cb5b1461082857806391b89fba1461084657600080fd5b806370a082311461077157806370d3c747146107a7578063715018a6146107dd57600080fd5b80633599bb17116102a05780635183d6fd1161023e57806365b8dbc01161021857806365b8dbc0146106ec5780636a4740021461070c5780636b69163b146107215780636d48467b1461075157600080fd5b80635183d6fd1461063c5780635344b50b146106935780635b72c18c146106b357600080fd5b8063418089041161027a578063418089041461059d5780634e5ee1c0146105bc5780634e7b827f146105ec5780635123425b1461061c57600080fd5b80633599bb171461053d578063395093511461055d57806340ffdd801461057d57600080fd5b80631d4ff89a1161030d57806327ce0147116102e757806327ce0147146104cb5780633009a609146104eb578063313ce5671461050157806331e79db01461051d57600080fd5b80631d4ff89a1461044e578063226cfa3d1461047e57806323b872dd146104ab57600080fd5b806309bbedde1161033e57806309bbedde146103db5780631694505e146103fa57806318160ddd1461043957600080fd5b806303c833021461037857806306fdde0314610380578063095ea7b3146103ab57600080fd5b3661037357610371610b82565b005b600080fd5b610371610b82565b34801561038c57600080fd5b50610395610c22565b6040516103a29190612ef9565b60405180910390f35b3480156103b757600080fd5b506103cb6103c6366004612dee565b610cb4565b60405190151581526020016103a2565b3480156103e757600080fd5b50600a545b6040519081526020016103a2565b34801561040657600080fd5b5060145461042190630100000090046001600160a01b031681565b6040516001600160a01b0390911681526020016103a2565b34801561044557600080fd5b506002546103ec565b34801561045a57600080fd5b506103cb610469366004612cff565b60116020526000908152604090205460ff1681565b34801561048a57600080fd5b506103ec610499366004612cff565b60166020526000908152604090205481565b3480156104b757600080fd5b506103cb6104c6366004612d9c565b610ccb565b3480156104d757600080fd5b506103ec6104e6366004612cff565b610d34565b3480156104f757600080fd5b506103ec600e5481565b34801561050d57600080fd5b50604051600981526020016103a2565b34801561052957600080fd5b50610371610538366004612cff565b610d9d565b34801561054957600080fd5b50610371610558366004612e19565b610e80565b34801561056957600080fd5b506103cb610578366004612dee565b610f3b565b34801561058957600080fd5b50610371610598366004612e19565b610f71565b3480156105a957600080fd5b506014546103cb90610100900460ff1681565b3480156105c857600080fd5b506103cb6105d7366004612cff565b60136020526000908152604090205460ff1681565b3480156105f857600080fd5b506103cb610607366004612cff565b600f6020526000908152604090205460ff1681565b34801561062857600080fd5b50610371610637366004612ddc565b61101e565b34801561064857600080fd5b5061065c610657366004612e51565b611091565b604080516001600160a01b0390971687526020870195909552938501929092526060840152608083015260a082015260c0016103a2565b34801561069f57600080fd5b50601554610421906001600160a01b031681565b3480156106bf57600080fd5b506103cb6106ce366004612cff565b6001600160a01b031660009081526013602052604090205460ff1690565b3480156106f857600080fd5b50610371610707366004612cff565b6110f1565b34801561071857600080fd5b5061037161117a565b34801561072d57600080fd5b506103cb61073c366004612cff565b60106020526000908152604090205460ff1681565b34801561075d57600080fd5b506103cb61076c366004612cff565b611234565b34801561077d57600080fd5b506103ec61078c366004612cff565b6001600160a01b031660009081526020819052604090205490565b3480156107b357600080fd5b506104216107c2366004612cff565b6012602052600090815260409020546001600160a01b031681565b3480156107e957600080fd5b5061037161129e565b3480156107fe57600080fd5b506103ec60085481565b34801561081457600080fd5b50610371610823366004612ddc565b611330565b34801561083457600080fd5b506009546001600160a01b0316610421565b34801561085257600080fd5b506103ec610861366004612cff565b6113a3565b34801561087257600080fd5b506103956113ae565b34801561088757600080fd5b50610371610896366004612e19565b6113bd565b3480156108a757600080fd5b506014546103cb9060ff1681565b3480156108c157600080fd5b506103ec7f000000000000000000000000000000000000000000000000000000000000000081565b3480156108f557600080fd5b506014546103cb9062010000900460ff1681565b34801561091557600080fd5b506103cb610924366004612dee565b61145c565b34801561093557600080fd5b506103ec610944366004612cff565b6114ab565b34801561095557600080fd5b506103cb610964366004612dee565b6114d7565b34801561097557600080fd5b506103ec610984366004612cff565b6001600160a01b031660009081526007602052604090205490565b3480156109ab57600080fd5b506103716109ba366004612ddc565b6114e4565b3480156109cb57600080fd5b506103cb6109da366004612cff565b611557565b3480156109eb57600080fd5b506103cb6109fa366004612d37565b6115c1565b348015610a0b57600080fd5b506103ec7f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3f57600080fd5b50610421610a4e366004612cff565b6001600160a01b039081166000908152601260205260409020541690565b348015610a7857600080fd5b506103ec610a87366004612d6f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610abe57600080fd5b50610371610acd366004612dee565b61175d565b348015610ade57600080fd5b50600e546103ec565b348015610af357600080fd5b50610371610b02366004612cff565b611854565b348015610b1357600080fd5b50610371610b22366004612d6f565b611974565b348015610b3357600080fd5b5061065c610b42366004612cff565b611a64565b348015610b5357600080fd5b50610b67610b62366004612e51565b611b13565b604080519384526020840192909252908201526060016103a2565b6000610b8d60025490565b11610b9757600080fd5b3415610c2057610bd7610ba960025490565b610bc434700100000000000000000000000000000000611c46565b610bce9190612fbc565b60055490611ce8565b60055560405134815233907fa493a9229478c3fcd73f66d2cdeb7f94fd0f341da924d1054236d784541165119060200160405180910390a2600854610c1c9034611ce8565b6008555b565b606060038054610c319061306a565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5d9061306a565b8015610caa5780601f10610c7f57610100808354040283529160200191610caa565b820191906000526020600020905b815481529060010190602001808311610c8d57829003601f168201915b5050505050905090565b6000610cc1338484611d47565b5060015b92915050565b6000610cd8848484611e9f565b610d2a8433610d258560405180606001604052806028815260200161311f602891396001600160a01b038a1660009081526001602090815260408083203384529091529020549190611f12565b611d47565b5060019392505050565b6001600160a01b0381166000908152600660209081526040808320549183905282205460055470010000000000000000000000000000000092610d9392610d8e92610d8891610d839190611c46565b611f4c565b90611f5c565b611f9a565b610cc59190612fbc565b6009546001600160a01b03163314610dea5760405162461bcd60e51b8152602060048201819052602482015260008051602061314783398151915260448201526064015b60405180910390fd5b6001600160a01b0381166000908152600f602052604090205460ff1615610e1057600080fd5b6001600160a01b0381166000908152600f60205260408120805460ff19166001179055610e3e908290611fad565b610e49600a8261200c565b6040516001600160a01b038216907fa878b31040b2e6d0a9a3d3361209db3908ba62014b0dca52adbaee451d128b2590600090a250565b6009546001600160a01b03163314610ec85760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff620100009091041615158115151415610ee557600080fd5b60148054821515620100000262ff0000199091161790556040517f3da2593f2c4724acfbd754045321e852cad26f3974834b1890045530f89c21b390610f3090831515815260200190565b60405180910390a150565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610cc1918590610d259086611ce8565b6009546001600160a01b03163314610fb95760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff6101009091041615158115151415610fd557600080fd5b601480548215156101000261ff00199091161790556040517fc138a28750b971696f46ea59731c471ef1e08e4015404afdb139fd2e87dca1bb90610f3090831515815260200190565b6009546001600160a01b031633146110665760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601360205260409020805460ff1916911515919091179055565b6000806000806000806110a3600a5490565b87106110c25750600094506000199350839250849150819050806110e8565b60006110cf600a89612171565b90506110da81611a64565b965096509650965096509650505b91939550919395565b6009546001600160a01b031633146111395760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b601480546001600160a01b039092166301000000027fffffffffffffffffff0000000000000000000000000000000000000000ffffff909216919091179055565b60405162461bcd60e51b815260206004820152606f60248201527f4469766572736946695f4469766964656e645f547261636b65723a207769746860448201527f647261774469766964656e642064697361626c65642e2055736520746865202760648201527f636c61696d272066756e6374696f6e206f6e20746865206d61696e204469766560848201527f727369466920636f6e74726163742e000000000000000000000000000000000060a482015260c401610de1565b6009546000906001600160a01b0316331461127f5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b506001600160a01b031660009081526010602052604090205460ff1690565b6009546001600160a01b031633146112e65760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6009546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600980546001600160a01b0319169055565b6009546001600160a01b031633146113785760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601060205260409020805460ff1916911515919091179055565b6000610cc5826114ab565b606060048054610c319061306a565b6009546001600160a01b031633146114055760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145460ff161515811515141561141b57600080fd5b6014805460ff19168215159081179091556040519081527f8d34c313963017194ed726d050e868657d0e2d2c6748d13e358cd4b89d4ee7c890602001610f30565b6000610cc13384610d2585604051806060016040528060258152602001613167602591393360009081526001602090815260408083206001600160a01b038d1684529091529020549190611f12565b6001600160a01b038116600090815260076020526040812054610cc5906114d184610d34565b906121b2565b6000610cc1338484611e9f565b6009546001600160a01b0316331461152c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03919091166000908152601160205260409020805460ff1916911515919091179055565b6009546000906001600160a01b031633146115a25760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b506001600160a01b031660009081526011602052604090205460ff1690565b6009546000906001600160a01b0316331461160c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b60145462010000900460ff161561162557506000610cc5565b6001600160a01b03831660009081526011602052604090205460ff1682801561164b5750805b801561165f5750601454610100900460ff16155b1561166e576000915050610cc5565b6000816116835761167e856121f4565b61168c565b61168c85612532565b90508015611752576001600160a01b0385166000908152601660205260409020429055811561170057831515856001600160a01b03167ffbd928dd3806a2bdf802f3a28a2cc55205f95dbcd2c3ed313abfca278366f80c836040516116f391815260200190565b60405180910390a3611747565b831515856001600160a01b03167fa2c38e2d2fb7e3e1912d937fd1ca11ed6d51864dee4cfa7a7bf02becd7acf0928360405161173e91815260200190565b60405180910390a35b600192505050610cc5565b506000949350505050565b6009546001600160a01b031633146117a55760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b0382166000908152600f602052604090205460ff16156117ca575050565b7f000000000000000000000000000000000000000000000000000000000000000081101561180c576117fd600a8361200c565b611808826000611fad565b5050565b6118168282611fad565b7f0000000000000000000000000000000000000000000000000000000000000000811061184957611808600a8383612927565b611808600a8361200c565b6009546001600160a01b0316331461189c5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b0381166119185760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610de1565b6009546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600980546001600160a01b0319166001600160a01b0392909216919091179055565b6009546001600160a01b031633146119bc5760405162461bcd60e51b815260206004820181905260248201526000805160206131478339815191526044820152606401610de1565b6001600160a01b03811660009081526013602052604090205460ff16806119ea57506001600160a01b038116155b611a365760405162461bcd60e51b815260206004820152601760248201527f546f6b656e206e6f7420696e20616c6c6f77206c6973740000000000000000006044820152606401610de1565b6001600160a01b03918216600090815260126020526040902080546001600160a01b03191691909216179055565b80600080808080611a76600a876129d0565b9450600019935060008512611ad857600e54851115611aa457600e54611a9d908690612a1b565b9350611ad8565b600e54600a5460009110611ab9576000611ac8565b600e54600a54611ac8916121b2565b9050611ad48682611f5c565b9450505b611ae1866114ab565b9250611aec86610d34565b6001600160a01b038716600090815260166020526040902054969895975093959294915050565b600a5460009081908190801580611b32575060145462010000900460ff165b15611b48575050600e5460009250829150611c3f565b600e546000805a90506000805b8984108015611b6357508582105b15611c2e5784611b72816130a5565b955050858510611b8157600094505b6000600a6000018681548110611ba757634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0316808352601090915260409091205490915060ff16611bf457611be18160016115c1565b15611bf45781611bf0816130a5565b9250505b82611bfe816130a5565b93505060005a905080851115611c2557611c22611c1b86836121b2565b8790611ce8565b95505b9350611b559050565b600e85905590975095509193505050505b9193909250565b600082611c5557506000610cc5565b6000611c618385612fdc565b905082611c6e8583612fbc565b14611ce15760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60448201527f77000000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b9392505050565b600080611cf58385612fa4565b905083811015611ce15760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610de1565b6001600160a01b038316611dc25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610de1565b6001600160a01b038216611e3e5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60405162461bcd60e51b815260206004820152603060248201527f4469766572736946695f4469766964656e645f547261636b65723a204e6f207460448201527f72616e736665727320616c6c6f776564000000000000000000000000000000006064820152608401610de1565b505050565b60008184841115611f365760405162461bcd60e51b8152600401610de19190612ef9565b506000611f438486613053565b95945050505050565b60008181811215610cc557600080fd5b600080611f698385612f4c565b905060008312158015611f7c5750838112155b80611f915750600083128015611f9157508381125b611ce157600080fd5b600080821215611fa957600080fd5b5090565b6001600160a01b03821660009081526020819052604090205480821115611fec576000611fda83836121b2565b9050611fe68482612a58565b50505050565b80821015611f0d57600061200082846121b2565b9050611fe68482612abc565b6001600160a01b038116600090815260038301602052604090205460ff16612032575050565b6001600160a01b03811660009081526003830160209081526040808320805460ff191690556001808601835281842084905560028601909252822054845490929161207c91613053565b905060008460000182815481106120a357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0390811680845260028901909252604080842087905590871683528220919091558554909150819086908590811061210057634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055845485908061214857634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b03191690550190555050505050565b600082600001828154811061219657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169392505050565b6000611ce183836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611f12565b600080612200836114ab565b90508015612529576001600160a01b03831660009081526007602052604090205461222b9082611ce8565b6001600160a01b0380851660009081526007602090815260408083209490945560129052918220546014549116919060ff16158061227057506001600160a01b038216155b8061229457506001600160a01b03821660009081526013602052604090205460ff16155b156122f7576040516001600160a01b03861690610bb89085906000818181858888f193505050503d80600081146122e7576040519150601f19603f3d011682016040523d82523d6000602084013e6122ec565b606091505b50508091505061248f565b604080516002808252606082018352600092602083019080368337019050509050601460039054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b15801561236657600080fd5b505afa15801561237a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239e9190612d1b565b816000815181106123bf57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050828160018151811061240157634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260145460405163b6f9de9560e01b815263010000009091049091169063b6f9de959086906124509060009086908c904290600401612ec4565b6000604051808303818588803b15801561246957600080fd5b505af19350505050801561247b575060015b612488576000915061248d565b600191505b505b806124dd576001600160a01b0385166000908152600760205260409020546124b790846121b2565b6001600160a01b0390951660009081526007602052604081209590955550929392505050565b846001600160a01b03167fee503bee2bb6a87e57bc57db795f98137327401a0e7b7ce42e37926cc1a9ca4d8460405161251891815260200190565b60405180910390a250909392505050565b50600092915050565b60008061253e836114ab565b90508015612529576001600160a01b0383166000908152600760205260408120546125699083611ce8565b6001600160a01b0385166000908152600760205260408082209290925581516002808252606082019093529091816020016020820280368337019050509050601460039054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b815260040160206040518083038186803b1580156125f657600080fd5b505afa15801561260a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061262e9190612d1b565b8160008151811061264f57634e487b7160e01b600052603260045260246000fd5b6001600160a01b03928316602091820292909201015260155482519116908290600190811061268e57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0392831660209182029290920101526015546040516370a0823160e01b815230600482015260009291909116906370a082319060240160206040518083038186803b1580156126e357600080fd5b505afa1580156126f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271b9190612e69565b60145460405163b6f9de9560e01b8152919250630100000090046001600160a01b03169063b6f9de9590869061275c90600090879030904290600401612ec4565b6000604051808303818588803b15801561277557600080fd5b505af193505050508015612787575060015b61279457600092506128ce565b6015546040516370a0823160e01b81523060048201526000916128169184916001600160a01b0316906370a082319060240160206040518083038186803b1580156127de57600080fd5b505afa1580156127f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d19190612e69565b905080156128c7576015546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260248201849052600196509091169063a9059cbb90604401602060405180830381600087803b15801561288957600080fd5b505af115801561289d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128c19190612e35565b506128cc565b600093505b505b8261291d576001600160a01b0386166000908152600760205260409020546128f690856121b2565b6001600160a01b039096166000908152600760205260408120969096555093949350505050565b5091949350505050565b6001600160a01b038216600090815260038401602052604090205460ff161561296c576001600160a01b03821660009081526001840160205260409020819055505050565b6001600160a01b03821660008181526003850160209081526040808320805460ff19166001908117909155878101835281842086905587546002890184529184208290558101875586835291200180546001600160a01b0319169091179055505050565b6001600160a01b038116600090815260038301602052604081205460ff166129fb5750600019610cc5565b506001600160a01b03166000908152600291909101602052604090205490565b600080612a288385612ffb565b905060008312158015612a3b5750838113155b80611f915750600083128015611f915750838113611ce157600080fd5b612a628282612b00565b612a9c612a7d610d8383600554611c4690919063ffffffff16565b6001600160a01b03841660009081526006602052604090205490612a1b565b6001600160a01b0390921660009081526006602052604090209190915550565b612ac68282612bdf565b612a9c612ae1610d8383600554611c4690919063ffffffff16565b6001600160a01b03841660009081526006602052604090205490611f5c565b6001600160a01b038216612b565760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610de1565b600254612b639082611ce8565b6002556001600160a01b038216600090815260208190526040902054612b899082611ce8565b6001600160a01b038316600081815260208181526040808320949094559251848152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a35050565b6001600160a01b038216612c5b5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610de1565b612c98816040518060600160405280602281526020016130fd602291396001600160a01b0385166000908152602081905260409020549190611f12565b6001600160a01b038316600090815260208190526040902055600254612cbe90826121b2565b6002556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612bd3565b600060208284031215612d10578081fd5b8135611ce1816130d6565b600060208284031215612d2c578081fd5b8151611ce1816130d6565b60008060408385031215612d49578081fd5b8235612d54816130d6565b91506020830135612d64816130ee565b809150509250929050565b60008060408385031215612d81578182fd5b8235612d8c816130d6565b91506020830135612d64816130d6565b600080600060608486031215612db0578081fd5b8335612dbb816130d6565b92506020840135612dcb816130d6565b929592945050506040919091013590565b60008060408385031215612d49578182fd5b60008060408385031215612e00578182fd5b8235612e0b816130d6565b946020939093013593505050565b600060208284031215612e2a578081fd5b8135611ce1816130ee565b600060208284031215612e46578081fd5b8151611ce1816130ee565b600060208284031215612e62578081fd5b5035919050565b600060208284031215612e7a578081fd5b5051919050565b6000815180845260208085019450808401835b83811015612eb95781516001600160a01b031687529582019590820190600101612e94565b509495945050505050565b848152608060208201526000612edd6080830186612e81565b6001600160a01b03949094166040830152506060015292915050565b6000602080835283518082850152825b81811015612f2557858101830151858201604001528201612f09565b81811115612f365783604083870101525b50601f01601f1916929092016040019392505050565b6000808212827f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03841381151615612f8657612f866130c0565b82600160ff1b038412811615612f9e57612f9e6130c0565b50500190565b60008219821115612fb757612fb76130c0565b500190565b600082612fd757634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612ff657612ff66130c0565b500290565b600080831283600160ff1b01831281151615613019576130196130c0565b837f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01831381161561304d5761304d6130c0565b50500390565b600082821015613065576130656130c0565b500390565b600181811c9082168061307e57607f821691505b6020821081141561309f57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156130b9576130b96130c0565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146130eb57600080fd5b50565b80151581146130eb57600080fdfe45524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122058a930dca684adcddf0226e4202f7551f9505675bf8d4b2b37f47f043ae4559164736f6c63430008040033

Deployed ByteCode Sourcemap

45103:24166:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45952:43;;;;;;;;;;;;;;;;;;;17246:25:1;;;17234:2;17219:18;45952:43:0;;;;;;;;67614:406;;;;;;;;;;-1:-1:-1;67614:406:0;;;;;:::i;:::-;;:::i;:::-;;9879:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;12187:210::-;;;;;;;;;;-1:-1:-1;12187:210:0;;;;;:::i;:::-;;:::i;:::-;;;8226:14:1;;8219:22;8201:41;;8189:2;8174:18;12187:210:0;8156:92:1;50549:329:0;;;;;;;;;;-1:-1:-1;50549:329:0;;;;;:::i;:::-;;:::i;52187:422::-;;;;;;;;;;-1:-1:-1;52187:422:0;;;;;:::i;:::-;;:::i;45182:41::-;;;;;;;;;;-1:-1:-1;45182:41:0;;;;-1:-1:-1;;;;;45182:41:0;;;;;;-1:-1:-1;;;;;5253:55:1;;;5235:74;;5223:2;5208:18;45182:41:0;5190:125:1;10999:108:0;;;;;;;;;;-1:-1:-1;11087:12:0;;10999:108;;45525:28;;;;;;;;;;;;;;;;12879:454;;;;;;;;;;-1:-1:-1;12879:454:0;;;;;:::i;:::-;;:::i;45633:47::-;;;;;;;;;;-1:-1:-1;45633:47:0;;;;-1:-1:-1;;;;;45633:47:0;;;46183:36;;;;;;;;;;;;;;;;57333:141;;;;;;;;;;;;;:::i;50412:92::-;;;;;;;;;;-1:-1:-1;50412:92:0;;50495:1;19765:36:1;;19753:2;19738:18;50412:92:0;19720:87:1;59676:119:0;;;;;;;;;;-1:-1:-1;59676:119:0;;;;;:::i;:::-;;:::i;13742:300::-;;;;;;;;;;-1:-1:-1;13742:300:0;;;;;:::i;:::-;;:::i;45489:29::-;;;;;;;;;;;;;;;;55163:121;;;;;;;;;;-1:-1:-1;55163:121:0;;;;;:::i;:::-;;:::i;46835:49::-;;;;;;;;;;-1:-1:-1;46835:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;45728:104;;;;;;;;;;-1:-1:-1;45728:104:0;;;;-1:-1:-1;;;;;45728:104:0;;;45232:28;;;;;;;;;;-1:-1:-1;45232:28:0;;;;-1:-1:-1;;;;;45232:28:0;;;46226:40;;;;;;;;;;-1:-1:-1;46226:40:0;;;;;;;;45339:34;;;;;;;;;;-1:-1:-1;45339:34:0;;;;-1:-1:-1;;;45339:34:0;;;;;;59045:103;;;;;;;;;;;;;:::i;57482:126::-;;;;;;;;;;-1:-1:-1;57482:126:0;;;;;:::i;:::-;-1:-1:-1;;;;;57572:28:0;57548:4;57572:28;;;:19;:28;;;;;;;;;57482:126;53854:152;;;;;;;;;;-1:-1:-1;53854:152:0;;;;;:::i;:::-;;:::i;66712:228::-;;;;;;;;;;-1:-1:-1;66712:228:0;;;;;:::i;:::-;;:::i;66948:129::-;;;;;;;;;;-1:-1:-1;66948:129:0;;;;;:::i;:::-;;:::i;59294:142::-;;;;;;;;;;;;;:::i;54014:328::-;;;;;;;;;;-1:-1:-1;54014:328:0;;;;;:::i;:::-;;:::i;57808:171::-;;;;;;;;;;-1:-1:-1;57808:171:0;;;;;:::i;:::-;;:::i;59803:185::-;;;;;;;;;;-1:-1:-1;59803:185:0;;;;;:::i;:::-;;:::i;58627:410::-;;;;;;;;;;-1:-1:-1;58627:410:0;;;;;:::i;:::-;;:::i;11170:177::-;;;;;;;;;;-1:-1:-1;11170:177:0;;;;;:::i;:::-;-1:-1:-1;;;;;11321:18:0;11289:7;11321:18;;;;;;;;;;;;11170:177;27828:148;;;;;;;;;;;;;:::i;46777:51::-;;;;;;;;;;-1:-1:-1;46777:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;59444:109;;;;;;;;;;-1:-1:-1;59444:109:0;;;;;:::i;:::-;;:::i;55869:240::-;;;;;;;;;;-1:-1:-1;55869:240:0;;;;;:::i;:::-;;:::i;52952:734::-;;;;;;;;;;-1:-1:-1;52952:734:0;;;;;:::i;:::-;;:::i;50886:153::-;;;;;;;;;;;;;:::i;27186:79::-;;;;;;;;;;-1:-1:-1;27251:6:0;;-1:-1:-1;;;;;27251:6:0;27186:79;;10098:104;;;;;;;;;;;;;:::i;46103:31::-;;;;;;;;;;;;;;;;54820:206;;;;;;;;;;-1:-1:-1;54820:206:0;;;;;:::i;:::-;;:::i;46345:40::-;;;;;;;;;;;;;;;;55034:121;;;;;;;;;;-1:-1:-1;55034:121:0;;;;;:::i;:::-;;:::i;51325:178::-;;;;;;;;;;-1:-1:-1;51325:178:0;;;;;:::i;:::-;;:::i;14545:400::-;;;;;;;;;;-1:-1:-1;14545:400:0;;;;;:::i;:::-;;:::i;51511:668::-;;;;;;;;;;-1:-1:-1;51511:668:0;;;;;:::i;:::-;;:::i;57616:184::-;;;;;;;;;;-1:-1:-1;57616:184:0;;;;;:::i;:::-;;:::i;11560:216::-;;;;;;;;;;-1:-1:-1;11560:216:0;;;;;:::i;:::-;;:::i;57135:190::-;;;;;;;;;;-1:-1:-1;57135:190:0;;;;;:::i;:::-;-1:-1:-1;;;;;57268:25:0;57226:7;57268:25;;;:16;:25;;;;;;;;;57295:12;:21;;;;;;;57268:25;;57135:190;;;;;18490:25:1;;;18546:2;18531:18;;18524:34;;;;18463:18;57135:190:0;18445:119:1;57987:307:0;;;;;;;;;;-1:-1:-1;57987:307:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;6840:55:1;;;6822:74;;6927:2;6912:18;;6905:34;;;;6955:18;;;6948:34;;;;7013:2;6998:18;;6991:34;7056:3;7041:19;;7034:35;7100:3;7085:19;;7078:35;6809:3;6794:19;57987:307:0;6776:343:1;46063:33:0;;;;;;;;;;;;;;;;46657:57;;;;;;;;;;-1:-1:-1;46657:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;59996:127;;;;;;;;;;-1:-1:-1;59996:127:0;;;;;:::i;:::-;;:::i;54350:244::-;;;;;;;;;;-1:-1:-1;54350:244:0;;;;;:::i;:::-;;:::i;66568:136::-;;;;;;;;;;-1:-1:-1;66568:136:0;;;;;:::i;:::-;;:::i;56117:1010::-;;;;;;;;;;-1:-1:-1;56117:1010:0;;;;;:::i;:::-;;:::i;45839:104::-;;;;;;;;;;-1:-1:-1;45839:104:0;;;;-1:-1:-1;;;;;45839:104:0;;;51047:270;;;;;;;;;;-1:-1:-1;51047:270:0;;;;;:::i;:::-;;:::i;52617:323::-;;;;;;;;;;-1:-1:-1;52617:323:0;;;;;:::i;:::-;;:::i;45689:30::-;;;;;;;;;;-1:-1:-1;45689:30:0;;;;-1:-1:-1;;;;;45689:30:0;;;54602:210;;;;;;;;;;-1:-1:-1;54602:210:0;;;;;:::i;:::-;;:::i;66299:261::-;;;;;;;;;;-1:-1:-1;66299:261:0;;;;;:::i;:::-;;:::i;11839:201::-;;;;;;;;;;-1:-1:-1;11839:201:0;;;;;:::i;:::-;-1:-1:-1;;;;;12005:18:0;;;11973:7;12005:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11839:201;46002:52;;;;;;;;;;;;;;;;55580:281;;;;;;;;;;-1:-1:-1;55580:281:0;;;;;:::i;:::-;;:::i;59156:130::-;;;;;;;;;;;;;:::i;45428:54::-;;;;;;;;;;;;;;;46141:35;;;;;;;;;;;;;;;;46723:47;;;;;;;;;;-1:-1:-1;46723:47:0;;;;;:::i;:::-;;;;;;;;;;;;;;58302:317;;;;;;;;;;-1:-1:-1;58302:317:0;;;;;:::i;:::-;;:::i;28131:281::-;;;;;;;;;;-1:-1:-1;28131:281:0;;;;;:::i;:::-;;:::i;59561:107::-;;;;;;;;;;-1:-1:-1;59561:107:0;;;;;:::i;:::-;;:::i;53694:152::-;;;;;;;;;;-1:-1:-1;53694:152:0;;;;;:::i;:::-;;:::i;67614:406::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;;;;;;;;;67693:19:::1;67715:25;67729:10;;67715:9;;:13;;:25;;;;:::i;:::-;67693:47;;67751:15;67769:38;67795:11;67769:21;67780:9;;67769:6;:10;;:21;;;;:::i;:::-;:25:::0;::::1;:38::i;:::-;67751:56;;67818:16;67837:39;67864:11;67837:22;67848:10;;67837:6;:10;;:22;;;;:::i;:39::-;67818:58;;67889:28;67910:6;67889:20;:28::i;:::-;67942:9;::::0;:22:::1;::::0;67956:7;67942:13:::1;:22::i;:::-;67930:9;:34:::0;67988:10:::1;::::0;:24:::1;::::0;68003:8;67988:14:::1;:24::i;:::-;67975:10;:37:::0;-1:-1:-1;;;;67614:406:0:o;9879:100::-;9933:13;9966:5;9959:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9879:100;:::o;12187:210::-;12306:4;12328:39;173:10;12351:7;12360:6;12328:8;:39::i;:::-;-1:-1:-1;12385:4:0;12187:210;;;;;:::o;50549:329::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;50671:24:::1;::::0;;;:14:::1;:24;::::0;;;;;:33;::::1;;50663:42;;;::::0;::::1;;50733:3;50724:5;:12;;50716:56;;;::::0;-1:-1:-1;;;50716:56:0;;10357:2:1;50716:56:0::1;::::0;::::1;10339:21:1::0;10396:2;10376:18;;;10369:30;10435:33;10415:18;;;10408:61;10486:18;;50716:56:0::1;10329:181:1::0;50716:56:0::1;50785:24;::::0;;;:14:::1;:24;::::0;;;;;;;;:32;;;50833:37;;18490:25:1;;;18531:18;;;18524:34;;;50833:37:0::1;::::0;18463:18:1;50833:37:0::1;;;;;;;;50549:329:::0;;:::o;52187:422::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;52292:6:::1;52264:24;;:34;;52256:43;;;::::0;::::1;;52361:24;::::0;:29;;:92:::1;;;52439:14;52411:24;;:42;;52361:92;52339:208;;;::::0;-1:-1:-1;;;52339:208:0;;16827:2:1;52339:208:0::1;::::0;::::1;16809:21:1::0;16866:2;16846:18;;;16839:30;16905:34;16885:18;;;16878:62;16976:34;16956:18;;;16949:62;17048:4;17027:19;;;17020:33;17070:19;;52339:208:0::1;16799:296:1::0;52339:208:0::1;52585:16;:6:::0;52595:5:::1;52585:16;:::i;:::-;52558:24;:43:::0;-1:-1:-1;52187:422:0:o;12879:454::-;13019:4;13036:36;13046:6;13054:9;13065:6;13036:9;:36::i;:::-;13083:220;13106:6;173:10;13154:138;13210:6;13154:138;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;13154:19:0;;;;;;:11;:19;;;;;;;;173:10;13154:33;;;;;;;;;;:37;:138::i;:::-;13083:8;:220::i;:::-;-1:-1:-1;13321:4:0;12879:454;;;;;:::o;57333:141::-;57423:15;;:43;;;;;;;;57396:7;;-1:-1:-1;;;;;57423:15:0;;:41;;:43;;;;;;;;;;;;;;:15;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57416:50;;57333:141;:::o;59676:119::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;59746:15:::1;::::0;:41:::1;::::0;;;;8226:14:1;;8219:22;59746:41:0::1;::::0;::::1;8201::1::0;-1:-1:-1;;;;;59746:15:0;;::::1;::::0;:34:::1;::::0;8174:18:1;;59746:41:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;59676:119:::0;:::o;13742:300::-;173:10;13857:4;13951:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;13951:34:0;;;;;;;;;;13857:4;;13879:133;;13929:7;;13951:50;;13990:10;13951:38;:50::i;55163:121::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;55233:15:::1;::::0;:43:::1;::::0;;;;8226:14:1;;8219:22;55233:43:0::1;::::0;::::1;8201:41:1::0;-1:-1:-1;;;;;55233:15:0;;::::1;::::0;:36:::1;::::0;8174:18:1;;55233:43:0::1;8156:92:1::0;59045:103:0;59082:15;;:58;;;;;59121:10;59082:58;;;5751:74:1;59082:15:0;5841:18:1;;;5834:50;-1:-1:-1;;;;;59082:15:0;;;;:30;;5724:18:1;;59082:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;59045:103::o;53854:152::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;53967:18:::1;:31:::0;;-1:-1:-1;;;;;;53967:31:0::1;-1:-1:-1::0;;;;;53967:31:0;;;::::1;::::0;;;::::1;::::0;;53854:152::o;66712:228::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;-1:-1:-1;;;;;66802:22:0;::::1;66819:4;66802:22;;66794:31;;;::::0;::::1;;66838:15;::::0;:47:::1;::::0;;;;-1:-1:-1;;;;;5769:55:1;;;66838:47:0::1;::::0;::::1;5751:74:1::0;5868:14;;5861:22;5841:18;;;5834:50;66838:15:0;;::::1;::::0;:33:::1;::::0;5724:18:1;;66838:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;66901:31:0::1;::::0;;-1:-1:-1;;;;;5769:55:1;;5751:74;;5868:14;;5861:22;5856:2;5841:18;;5834:50;66901:31:0::1;::::0;-1:-1:-1;5724:18:1;;-1:-1:-1;66901:31:0::1;5706:184:1::0;66948:129:0;67032:15;;:37;;;;;-1:-1:-1;;;;;5253:55:1;;;67032:37:0;;;5235:74:1;67008:4:0;;67032:15;;:30;;5208:18:1;;67032:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;59294:142::-;59387:15;;:41;;;;;;;;59360:7;;-1:-1:-1;;;;;59387:15:0;;:39;;:41;;;;;;;;;;;;;;:15;:41;;;;;;;;;;54014:328;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;54123:15:::1;::::0;-1:-1:-1;;;;;54101:38:0;;::::1;54123:15:::0;::::1;54101:38;;54093:47;;;::::0;::::1;;54198:15;::::0;54156:59:::1;::::0;-1:-1:-1;;;;;54198:15:0;;::::1;::::0;54156:59;::::1;::::0;::::1;::::0;54198:15:::1;::::0;54156:59:::1;54226:15;:48:::0;;-1:-1:-1;;;;;;54226:48:0::1;-1:-1:-1::0;;;;;54226:48:0;;::::1;::::0;;::::1;::::0;;;54285:15:::1;::::0;:49:::1;::::0;;;;::::1;::::0;::::1;5235:74:1::0;;;;54285:15:0;;::::1;::::0;:37:::1;::::0;5208:18:1;;54285:49:0::1;5190:125:1::0;57808:171:0;57937:15;;:34;;;;;-1:-1:-1;;;;;5253:55:1;;;57937:34:0;;;5235:74:1;57905:7:0;;57937:15;;:25;;5208:18:1;;57937:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;59803:185::-;59932:15;;:48;;;;;-1:-1:-1;;;;;5253:55:1;;;59932:48:0;;;5235:74:1;59903:4:0;;59932:15;;:39;;5208:18:1;;59932:48:0;5190:125:1;58627:410:0;58809:15;;:28;;;;;;;;17246:25:1;;;58707:18:0;;;;;;-1:-1:-1;;;;;58809:15:0;;:23;;17219:18:1;;58809:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58853:176;;;19458:25:1;;;19514:2;19499:18;;19492:34;;;19542:18;;;19535:34;;;19600:2;19585:18;;19578:34;;;58692:145:0;;-1:-1:-1;58692:145:0;;-1:-1:-1;58692:145:0;-1:-1:-1;59009:9:0;;58971:5;;58853:176;;19445:3:1;19430:19;58853:176:0;;;;;;;58627:410;;;;:::o;27828:148::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;27919:6:::1;::::0;27898:40:::1;::::0;27935:1:::1;::::0;-1:-1:-1;;;;;27919:6:0::1;::::0;27898:40:::1;::::0;27935:1;;27898:40:::1;27949:6;:19:::0;;-1:-1:-1;;;;;;27949:19:0::1;::::0;;27828:148::o;59444:109::-;59498:15;;:47;;;;;59527:10;59498:47;;;5751:74:1;5868:14;;5861:22;5841:18;;;5834:50;-1:-1:-1;;;;;59498:15:0;;;;:28;;5724:18:1;;59498:47:0;5706:184:1;55869:240:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;55967:6:::1;55955:8;:18;;:40;;;;;55989:6;55977:8;:18;;55955:40;55947:49;;;::::0;::::1;;56046:16;::::0;56012:51:::1;::::0;56036:8;;56012:51:::1;::::0;;;::::1;56074:16;:27:::0;55869:240::o;52952:734::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;53061:15:::1;::::0;-1:-1:-1;;;;;53039:38:0;;::::1;53061:15:::0;::::1;53039:38;;53031:47;;;::::0;::::1;;53091:43;53184:10;53091:115;;53265:4;-1:-1:-1::0;;;;;53227:43:0::1;:18;-1:-1:-1::0;;;;;53227:24:0::1;;:26;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;53227:43:0::1;;53219:52;;;::::0;::::1;;53284:68;::::0;-1:-1:-1;;;53284:68:0;;-1:-1:-1;;;;;53284:39:0;::::1;:68;::::0;::::1;5235:74:1::0;;;53284:39:0;::::1;::::0;5208:18:1;;53284:68:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;53363:54:0::1;::::0;-1:-1:-1;;;53363:54:0;;53411:4:::1;53363:54;::::0;::::1;5235:74:1::0;-1:-1:-1;;;;;53363:39:0;::::1;::::0;-1:-1:-1;53363:39:0::1;::::0;-1:-1:-1;5208:18:1;;53363:54:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;53428:18;-1:-1:-1::0;;;;;53428:39:0::1;;53468:7;27251:6:::0;;-1:-1:-1;;;;;27251:6:0;;27186:79;53468:7:::1;53428:48;::::0;-1:-1:-1;;;;;;53428:48:0::1;::::0;;;;;;-1:-1:-1;;;;;5253:55:1;;;53428:48:0::1;::::0;::::1;5235:74:1::0;5208:18;;53428:48:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;53535:15:0::1;::::0;53487:65:::1;::::0;-1:-1:-1;;;53487:65:0;;-1:-1:-1;;;;;53535:15:0;;::::1;53487:65;::::0;::::1;5235:74:1::0;53487:39:0;;::::1;::::0;-1:-1:-1;53487:39:0::1;::::0;-1:-1:-1;5208:18:1;;53487:65:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;53612:15:0::1;::::0;53570:59:::1;::::0;-1:-1:-1;;;;;53612:15:0;;::::1;::::0;-1:-1:-1;53570:59:0;;::::1;::::0;-1:-1:-1;53570:59:0::1;::::0;53612:15:::1;::::0;53570:59:::1;53642:15;:36:::0;;-1:-1:-1;;;;;;53642:36:0::1;-1:-1:-1::0;;;;;53642:36:0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;52952:734:0:o;50886:153::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;50950:14:::1;::::0;-1:-1:-1;;;50950:14:0;::::1;;;50949:15;50941:24;;;::::0;::::1;;50978:14;:21:::0;;;::::1;-1:-1:-1::0;;;50978:21:0::1;::::0;;51015:16:::1;::::0;::::1;::::0;50978:21;;51015:16:::1;50886:153::o:0;10098:104::-;10154:13;10187:7;10180:14;;;;;:::i;54820:206::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;54950:13:::1;::::0;-1:-1:-1;;;;;54942:21:0;;::::1;54950:13:::0;::::1;54942:21;;54934:30;;;::::0;::::1;;54977:41;55006:4;55012:5;54977:28;:41::i;:::-;54820:206:::0;;:::o;55034:121::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;55104:15:::1;::::0;:43:::1;::::0;;;;8226:14:1;;8219:22;55104:43:0::1;::::0;::::1;8201:41:1::0;-1:-1:-1;;;;;55104:15:0;;::::1;::::0;:36:::1;::::0;8174:18:1;;55104:43:0::1;8156:92:1::0;51325:178:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;51397:14:::1;::::0;::::1;-1:-1:-1::0;;;51397:14:0;;::::1;;:24;;::::0;::::1;;;;51389:33;;;::::0;::::1;;51433:14;:23:::0;;;::::1;;-1:-1:-1::0;;;51433:23:0::1;::::0;;;::::1;;::::0;;51474:21:::1;::::0;::::1;::::0;::::1;::::0;51450:6;8226:14:1;8219:22;8201:41;;8189:2;8174:18;;8156:92;51474:21:0::1;;;;;;;;51325:178:::0;:::o;14545:400::-;14665:4;14687:228;173:10;14737:7;14759:145;14816:15;14759:145;;;;;;;;;;;;;;;;;173:10;14759:25;;;;:11;:25;;;;;;;;-1:-1:-1;;;;;14759:34:0;;;;;;;;;;;;:38;:145::i;51511:668::-;51570:14;;-1:-1:-1;;;51570:14:0;;;;51562:49;;;;-1:-1:-1;;;51562:49:0;;16476:2:1;51562:49:0;;;16458:21:1;16515:2;16495:18;;;16488:30;16554:24;16534:18;;;16527:52;16596:18;;51562:49:0;16448:172:1;51562:49:0;51630:24;;;;:14;:24;;;;;;51622:66;;;;-1:-1:-1;;;51622:66:0;;13055:2:1;51622:66:0;;;13037:21:1;13094:2;13074:18;;;13067:30;13133:26;13113:18;;;13106:54;13177:18;;51622:66:0;13027:174:1;51622:66:0;51754:29;:15;51774:8;51754:19;:29::i;:::-;173:10;51721:30;;;;:16;:30;;;;;;:62;51699:148;;;;-1:-1:-1;;;51699:148:0;;12292:2:1;51699:148:0;;;12274:21:1;12331:2;12311:18;;;12304:30;12370:34;12350:18;;;12343:62;12441:6;12421:18;;;12414:34;12465:19;;51699:148:0;12264:226:1;51699:148:0;51889:24;;;;:14;:24;;;;;;;;;173:10;51860:26;;:12;:26;;;;;;:53;51957:29;:15;51889:24;51957:19;:29::i;:::-;173:10;51924:30;;;;:16;:30;;;;;:62;;;;51999:15;;-1:-1:-1;;;;;51999:15:0;;:26;;52067:31;173:10;52067:17;:31::i;:::-;51999:110;;-1:-1:-1;;;;;;51999:110:0;;;;;;;-1:-1:-1;;;;;7316:55:1;;;51999:110:0;;;7298:74:1;7388:18;;;7381:34;7271:18;;51999:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52148:12;173:10;;93:98;52148:12;-1:-1:-1;;;;;52127:44:0;;52162:8;52127:44;;;;17246:25:1;;17234:2;17219:18;;17201:76;52127:44:0;;;;;;;;51511:668;:::o;57616:184::-;57745:15;;:47;;;;;-1:-1:-1;;;;;5253:55:1;;;57745:47:0;;;5235:74:1;57713:7:0;;57745:15;;:38;;5208:18:1;;57745:47:0;5190:125:1;11560:216:0;11682:4;11704:42;173:10;11728:9;11739:6;11704:9;:42::i;57987:307::-;58251:15;;:35;;;;;-1:-1:-1;;;;;5253:55:1;;;58251:35:0;;;5235:74:1;58101:7:0;;;;;;;;;;;;58251:15;;;;:26;;5208:18:1;;58251:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58244:42;;;;-1:-1:-1;58244:42:0;;-1:-1:-1;58244:42:0;-1:-1:-1;58244:42:0;-1:-1:-1;58244:42:0;;-1:-1:-1;57987:307:0;-1:-1:-1;;57987:307:0:o;59996:127::-;60080:15;;:35;;;;;-1:-1:-1;;;;;5253:55:1;;;60080:35:0;;;5235:74:1;60056:4:0;;60080:15;;:26;;5208:18:1;;60080:35:0;5190:125:1;54350:244:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;-1:-1:-1;;;;;54443:28:0;::::1;;::::0;;;:19:::1;:28;::::0;;;;;::::1;;:40;;::::0;::::1;;;;54435:49;;;::::0;::::1;;-1:-1:-1::0;;;;;54495:28:0;::::1;;::::0;;;:19:::1;:28;::::0;;;;;;;;:39;;-1:-1:-1;;54495:39:0::1;::::0;::::1;;::::0;;::::1;::::0;;;54552:34;;8201:41:1;;;54552:34:0::1;::::0;8174:18:1;54552:34:0::1;;;;;;;54350:244:::0;;:::o;66568:136::-;66657:15;;:39;;;;;-1:-1:-1;;;;;5253:55:1;;;66657:39:0;;;5235:74:1;66630:7:0;;66657:15;;:30;;5208:18:1;;66657:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;56117:1010::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;56316:2:::1;56302:10;:16;;56294:60;;;::::0;-1:-1:-1;;;56294:60:0;;9997:2:1;56294:60:0::1;::::0;::::1;9979:21:1::0;10036:2;10016:18;;;10009:30;10075:33;10055:18;;;10048:61;10126:18;;56294:60:0::1;9969:181:1::0;56294:60:0::1;56386:2;56373:9;:15;;56365:59;;;::::0;-1:-1:-1;;;56365:59:0;;14171:2:1;56365:59:0::1;::::0;::::1;14153:21:1::0;14210:2;14190:18;;;14183:30;14249:33;14229:18;;;14222:61;14300:18;;56365:59:0::1;14143:181:1::0;56365:59:0::1;56474:1;56457:13;:18;;:41;;;;;56496:2;56479:13;:19;;56457:41;56435:131;;;::::0;-1:-1:-1;;;56435:131:0;;11883:2:1;56435:131:0::1;::::0;::::1;11865:21:1::0;11922:2;11902:18;;;11895:30;11961:34;11941:18;;;11934:62;-1:-1:-1;;;12012:18:1;;;12005:38;12060:19;;56435:131:0::1;11855:230:1::0;56435:131:0::1;56617:1;56599:14;:19;;:43;;;;;56640:2;56622:14;:20;;56599:43;56577:133;;;::::0;-1:-1:-1;;;56577:133:0;;11883:2:1;56577:133:0::1;::::0;::::1;11865:21:1::0;11922:2;11902:18;;;11895:30;11961:34;11941:18;;;11934:62;-1:-1:-1;;;12012:18:1;;;12005:38;12060:19;;56577:133:0::1;11855:230:1::0;56577:133:0::1;56723:14;:27:::0;;;56761:12:::1;:24:::0;;;56796:16:::1;:32:::0;;;56839:17:::1;:34:::0;;;56902:55:::1;56740:10:::0;56902:35:::1;56859:14:::0;56776:9;56902:21:::1;:35::i;:::-;:39:::0;::::1;:55::i;:::-;56886:13;:71:::0;57022:14:::1;::::0;57004:12:::1;::::0;56983:16:::1;::::0;:54:::1;::::0;57022:14;56983:34:::1;::::0;:16;:20:::1;:34::i;:54::-;56968:12;:69:::0;57055:64:::1;::::0;;19458:25:1;;;19514:2;19499:18;;19492:34;;;19542:18;;;19535:34;;;19600:2;19585:18;;19578:34;;;57055:64:0::1;::::0;19445:3:1;19430:19;57055:64:0::1;;;;;;;56117:1010:::0;;;;:::o;51047:270::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;-1:-1:-1;;;;;51119:41:0;;::::1;;::::0;;;:33:::1;:41;::::0;;;;;;;:48;;51163:4:::1;-1:-1:-1::0;;51119:48:0;;::::1;::::0;::::1;::::0;;;51178:19:::1;:27:::0;;;;;;;:34;;;;::::1;::::0;;::::1;::::0;;51223:15:::1;::::0;:44;;-1:-1:-1;;;51223:44:0;;::::1;::::0;::::1;5235:74:1::0;;;;51223:15:0;;::::1;::::0;:36:::1;::::0;5208:18:1;;51223:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;51285:24:0::1;::::0;-1:-1:-1;;;;;5253:55:1;;5235:74;;51285:24:0::1;::::0;-1:-1:-1;5223:2:1;5208:18;;-1:-1:-1;51285:24:0::1;5190:125:1::0;52617:323:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;52725:6:::1;52703:18;;:28;;52695:37;;;::::0;::::1;;52791:15;52769:18;;:37;;52743:141;;;::::0;-1:-1:-1;;;52743:141:0;;16057:2:1;52743:141:0::1;::::0;::::1;16039:21:1::0;16096:2;16076:18;;;16069:30;16135:34;16115:18;;;16108:62;16206:20;16186:18;;;16179:48;16244:19;;52743:141:0::1;16029:240:1::0;52743:141:0::1;52916:16;:6:::0;52926:5:::1;52916:16;:::i;:::-;52895:18;:37:::0;-1:-1:-1;52617:323:0:o;54602:210::-;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;54682:21:::1;::::0;::::1;;:32;;::::0;::::1;;;;54674:41;;;::::0;::::1;;54726:21;:31:::0;;-1:-1:-1;;54726:31:0::1;::::0;::::1;;::::0;;::::1;::::0;;;54775:29:::1;::::0;8201:41:1;;;54775:29:0::1;::::0;8189:2:1;8174:18;54775:29:0::1;8156:92:1::0;66299:261:0;66377:10;66391:1;11321:18;;;;;;;;;;;66367:25;66359:34;;;;;;-1:-1:-1;;;;;66412:22:0;;66429:4;66412:22;;66404:31;;;;;;66448:15;;:52;;;;;66482:10;66448:52;;;6130:34:1;-1:-1:-1;;;;;6200:15:1;;;6180:18;;;6173:43;66448:15:0;;;;:33;;6042:18:1;;66448:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66516:36:0;;;66534:10;6130:34:1;;-1:-1:-1;;;;;6200:15:1;;6195:2;6180:18;;6173:43;66516:36:0;;-1:-1:-1;6042:18:1;;-1:-1:-1;66516:36:0;6024:198:1;55580:281:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;55690:41:::1;55706:18;55726:4;55690:15;:41::i;:::-;55790:15;::::0;55747:59:::1;::::0;-1:-1:-1;;;;;55790:15:0;;::::1;::::0;55747:59;::::1;::::0;::::1;::::0;55790:15:::1;::::0;55747:59:::1;55817:15;:36:::0;;-1:-1:-1;;;;;;55817:36:0::1;-1:-1:-1::0;;;;;55817:36:0;;;::::1;::::0;;;::::1;::::0;;55580:281::o;59156:130::-;59239:15;;:39;;;;;;;;59212:7;;-1:-1:-1;;;;;59239:15:0;;:37;;:39;;;;;;;;;;;;;;:15;:39;;;;;;;;;;58302:317;58571:15;;:40;;;;;;;;17246:25:1;;;58421:7:0;;;;;;;;;;;;-1:-1:-1;;;;;58571:15:0;;;;:33;;17219:18:1;;58571:40:0;17201:76:1;28131:281:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;-1:-1:-1;;;;;28234:22:0;::::1;28212:110;;;::::0;-1:-1:-1;;;28212:110:0;;10717:2:1;28212:110:0::1;::::0;::::1;10699:21:1::0;10756:2;10736:18;;;10729:30;10795:34;10775:18;;;10768:62;10866:8;10846:18;;;10839:36;10892:19;;28212:110:0::1;10689:228:1::0;28212:110:0::1;28359:6;::::0;28338:38:::1;::::0;-1:-1:-1;;;;;28338:38:0;;::::1;::::0;28359:6:::1;::::0;28338:38:::1;::::0;28359:6:::1;::::0;28338:38:::1;28387:6;:17:::0;;-1:-1:-1;;;;;;28387:17:0::1;-1:-1:-1::0;;;;;28387:17:0;;;::::1;::::0;;;::::1;::::0;;28131:281::o;59561:107::-;59614:15;;:46;;;;;59642:10;59614:46;;;5751:74:1;5868:14;;5861:22;5841:18;;;5834:50;-1:-1:-1;;;;;59614:15:0;;;;:27;;5724:18:1;;59614:46:0;5706:184:1;53694:152:0;27398:6;;-1:-1:-1;;;;;27398:6:0;173:10;27398:22;27390:67;;;;-1:-1:-1;;;27390:67:0;;13810:2:1;27390:67:0;;;13792:21:1;;;13829:18;;;13822:30;-1:-1:-1;;;;;;;;;;;13868:18:1;;;13861:62;13940:18;;27390:67:0;13782:182:1;27390:67:0;53807:18:::1;:31:::0;;-1:-1:-1;;;;;;53807:31:0::1;-1:-1:-1::0;;;;;53807:31:0;;;::::1;::::0;;;::::1;::::0;;53694:152::o;22108:181::-;22166:7;;22198:5;22202:1;22198;:5;:::i;:::-;22186:17;;22227:1;22222;:6;;22214:46;;;;-1:-1:-1;;;22214:46:0;;11527:2:1;22214:46:0;;;11509:21:1;11566:2;11546:18;;;11539:30;11605:29;11585:18;;;11578:57;11652:18;;22214:46:0;11499:177:1;22214:46:0;22280:1;22108:181;-1:-1:-1;;;22108:181:0:o;23496:471::-;23554:7;23799:6;23795:47;;-1:-1:-1;23829:1:0;23822:8;;23795:47;23854:9;23866:5;23870:1;23866;:5;:::i;:::-;23854:17;-1:-1:-1;23899:1:0;23890:5;23894:1;23854:17;23890:5;:::i;:::-;:10;23882:56;;;;-1:-1:-1;;;23882:56:0;;13408:2:1;23882:56:0;;;13390:21:1;13447:2;13427:18;;;13420:30;13486:34;13466:18;;;13459:62;13557:3;13537:18;;;13530:31;13578:19;;23882:56:0;13380:223:1;24443:132:0;24501:7;24528:39;24532:1;24535;24528:39;;;;;;;;;;;;;;;;;:3;:39::i;68028:1238::-;68093:24;68110:6;68093:16;:24::i;:::-;68128:19;68150:25;68164:10;;68150:9;;:13;;:25;;;;:::i;:::-;68128:47;;68188:24;68215:187;68365:36;68386:14;;68365:16;;:20;;:36;;;;:::i;:::-;68215:131;68329:16;;68215:95;68298:11;68215:64;68269:9;;68215:35;:53;;:64;;;;:::i;:95::-;:113;;:131::i;:187::-;68188:214;;68415:25;68443:190;68595:37;68617:14;;68595:17;;:21;;:37;;;;:::i;:::-;68443:133;68558:17;;68443:96;68527:11;68443:65;68497:10;;68443:35;:53;;:65;;;;:::i;:190::-;68415:218;-1:-1:-1;68646:17:0;68666:39;:16;68415:218;68666:20;:39::i;:::-;68745:15;;68737:51;;68646:59;;-1:-1:-1;68719:12:0;;-1:-1:-1;;;;;68745:15:0;;;;68646:59;;68719:12;68737:51;68719:12;68737:51;68646:59;68745:15;68737:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68718:70:0;;-1:-1:-1;68819:21:0;;-1:-1:-1;68801:15:0;68866:14;68819:21;68878:1;68866:11;:14::i;:::-;68851:29;-1:-1:-1;68891:17:0;68911:14;68851:29;68911:7;:14;:::i;:::-;68966:18;;68958:49;;68891:34;;-1:-1:-1;68937:15:0;;-1:-1:-1;;;;;68966:18:0;;;;68998:4;;68937:15;68958:49;68937:15;68958:49;68998:4;68966:18;68958:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;69050:18:0;;69042:78;;68936:71;;-1:-1:-1;69021:15:0;;-1:-1:-1;;;;;69050:18:0;;;;69096:9;;69021:15;69042:78;69021:15;69042:78;69096:9;69050:18;69042:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69020:100;;;69138:120;69166:9;69190:7;69212;:21;;;;;69223:10;69212:21;:35;;;;;69237:10;69212:35;69138:120;;;18765:25:1;;;18821:2;18806:18;;18799:34;;;;18876:14;18869:22;18849:18;;;18842:50;18753:2;18738:18;69138:120:0;;;;;;;68028:1238;;;;;;;;;;;:::o;22572:136::-;22630:7;22657:43;22661:1;22664;22657:43;;;;;;;;;;;;;;;;;:3;:43::i;17936:380::-;-1:-1:-1;;;;;18072:19:0;;18064:68;;;;-1:-1:-1;;;18064:68:0;;15291:2:1;18064:68:0;;;15273:21:1;15330:2;15310:18;;;15303:30;15369:34;15349:18;;;15342:62;15440:6;15420:18;;;15413:34;15464:19;;18064:68:0;15263:226:1;18064:68:0;-1:-1:-1;;;;;18151:21:0;;18143:68;;;;-1:-1:-1;;;18143:68:0;;11124:2:1;18143:68:0;;;11106:21:1;11163:2;11143:18;;;11136:30;11202:34;11182:18;;;11175:62;11273:4;11253:18;;;11246:32;11295:19;;18143:68:0;11096:224:1;18143:68:0;-1:-1:-1;;;;;18224:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;18276:32;;17246:25:1;;;18276:32:0;;17219:18:1;18276:32:0;;;;;;;;17936:380;;;:::o;60131:4335::-;-1:-1:-1;;;;;60263:18:0;;60255:68;;;;-1:-1:-1;;;60255:68:0;;14531:2:1;60255:68:0;;;14513:21:1;14570:2;14550:18;;;14543:30;14609:34;14589:18;;;14582:62;-1:-1:-1;;;14660:18:1;;;14653:35;14705:19;;60255:68:0;14503:227:1;60255:68:0;-1:-1:-1;;;;;60342:16:0;;60334:64;;;;-1:-1:-1;;;60334:64:0;;9593:2:1;60334:64:0;;;9575:21:1;9632:2;9612:18;;;9605:30;9671:34;9651:18;;;9644:62;-1:-1:-1;;;9722:18:1;;;9715:33;9765:19;;60334:64:0;9565:225:1;60334:64:0;60431:14;;-1:-1:-1;;;60431:14:0;;;;;:57;;-1:-1:-1;;;;;;60449:39:0;;;;;;:33;:39;;;;;;;;60431:57;:99;;;;60511:19;60492:15;:38;;60431:99;60409:181;;;;-1:-1:-1;;;60409:181:0;;15696:2:1;60409:181:0;;;15678:21:1;;;15715:18;;;15708:30;15774:34;15754:18;;;15747:62;15826:18;;60409:181:0;15668:182:1;60409:181:0;60607:11;60603:3676;;60635:28;60651:4;60657:2;60661:1;60635:15;:28::i;:::-;60131:4335;;;:::o;60603:3676::-;60721:8;;-1:-1:-1;;;60721:8:0;;;;60720:9;:39;;;;-1:-1:-1;;;;;;60734:25:0;;;;;;:19;:25;;;;;;;;60733:26;60720:39;:67;;;;-1:-1:-1;;;;;;60764:23:0;;;;;;:19;:23;;;;;;;;60763:24;60720:67;60702:3577;;;-1:-1:-1;;;;;60831:29:0;;;60814:14;60831:29;;;:25;:29;;;;;;;60882:31;;;;;;;;60831:29;;;;;60882:31;60881:32;:50;;;;-1:-1:-1;60917:14:0;;-1:-1:-1;;;60917:14:0;;;;60881:50;60877:400;;;-1:-1:-1;;;;;60982:22:0;;;;;;:16;:22;;;;;;61008:15;-1:-1:-1;60982:41:0;60952:144;;;;-1:-1:-1;;;60952:144:0;;12697:2:1;60952:144:0;;;12679:21:1;12736:2;12716:18;;;12709:30;12775:31;12755:18;;;12748:59;12824:18;;60952:144:0;12669:179:1;60952:144:0;-1:-1:-1;;;;;61119:22:0;;;;;;:16;:22;;;;;;:27;61115:147;;-1:-1:-1;;;;;61171:22:0;;61196:1;61171:22;;;:16;:22;;;;;;;;:26;;;61220:12;:18;;;;;:22;61115:147;61293:21;61335:9;61331:156;;;-1:-1:-1;61381:17:0;;61331:156;;;-1:-1:-1;61455:16:0;;61331:156;61503:17;61523:51;61559:14;;61523:31;61541:12;;61523:13;:17;;:31;;;;:::i;:51::-;61503:71;;61613:24;;61641:1;61613:29;;:59;;;;;61663:9;61613:59;:179;;;;-1:-1:-1;61776:15:0;;-1:-1:-1;;;;;61760:32:0;;;61776:15;;61760:32;;61613:179;61591:449;;;61931:24;;61921:6;:34;;61891:133;;;;-1:-1:-1;;;61891:133:0;;14937:2:1;61891:133:0;;;14919:21:1;14976:2;14956:18;;;14949:30;15015:27;14995:18;;;14988:55;15060:18;;61891:133:0;14909:175:1;61891:133:0;62105:4;62056:28;11321:18;;;;;;;;;;;62167;;62143:42;;;;;;;62206:43;;-1:-1:-1;;;;;;62218:31:0;;;;;;:25;:31;;;;;;;;62217:32;62206:43;62202:1217;;;62270:8;:15;;-1:-1:-1;;;;62270:15:0;-1:-1:-1;;;62270:15:0;;;62310:21;;62270:15;62310:21;62306:863;;;62356:20;62379:25;62393:10;;62379:9;;:13;;:25;;;;:::i;:::-;62356:48;;62427:24;62454:105;62546:12;62454:61;62505:9;;62454:20;:50;;:61;;;;:::i;:105::-;62427:132;;62582:22;62607:106;62700:12;62607:62;62658:10;;62607:20;:50;;:62;;;;:::i;:106::-;62582:131;;62738:21;62762:104;62853:12;;62762:60;62809:12;;62762:16;:46;;:60;;;;:::i;:104::-;62738:128;;62891:22;62916:103;63005:13;;62916:58;62961:12;;62916:14;:44;;:58;;;;:::i;:103::-;62891:128;-1:-1:-1;63044:18:0;63065:33;62891:128;63084:13;63065:18;:33::i;:::-;63044:54;;63123:26;63138:10;63123:14;:26::i;:::-;62306:863;;;;;;;63234:4;63189:24;11321:18;;;;;;;;;;;63261:38;11321:18;63261:20;:38::i;:::-;-1:-1:-1;63332:1:0;63320:9;:13;;;63352:10;:14;63387:8;:16;;-1:-1:-1;;;;63387:16:0;;;62202:1217;63435:12;63450:30;63476:3;63450:21;:6;63461:9;63450:10;:21::i;:30::-;63435:45;-1:-1:-1;63506:16:0;:6;63435:45;63506:10;:16::i;:::-;63497:25;;63543:9;63539:155;;;63586:10;;:20;;63601:4;63586:14;:20::i;:::-;63573:10;:33;63539:155;;;63659:9;;:19;;63673:4;63659:13;:19::i;:::-;63647:9;:31;63539:155;63710:42;63726:4;63740;63747;63710:15;:42::i;:::-;63783:16;;63820:15;;:28;;;;;;;;17246:25:1;;;-1:-1:-1;;;;;63820:15:0;;;;:23;;17219:18:1;;63820:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63820:28:0;;;;;;;;-1:-1:-1;;63820:28:0;;;;;;;;;;;;:::i;:::-;;;63816:452;;;;;64012:231;;;19458:25:1;;;19514:2;19499:18;;19492:34;;;19542:18;;;19535:34;;;19600:2;19585:18;;19578:34;;;64215:9:0;;64162:4;;64012:231;;19445:3:1;19430:19;64012:231:0;;;;;;;63849:410;;;63816:452;60702:3577;;;;;;;;64291:33;64307:4;64313:2;64317:6;64291:15;:33::i;:::-;64337:15;;-1:-1:-1;;;;;64337:15:0;:26;64364:4;64370:23;64364:4;64370:17;:23::i;:::-;64337:57;;-1:-1:-1;;;;;;64337:57:0;;;;;;;-1:-1:-1;;;;;7316:55:1;;;64337:57:0;;;7298:74:1;7388:18;;;7381:34;7271:18;;64337:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;64405:15:0;;-1:-1:-1;;;;;64405:15:0;;-1:-1:-1;64405:26:0;;-1:-1:-1;64432:2:0;64436:21;64432:2;64436:17;:21::i;:::-;64405:53;;-1:-1:-1;;;;;;64405:53:0;;;;;;;-1:-1:-1;;;;;7316:55:1;;;64405:53:0;;;7298:74:1;7388:18;;;7381:34;7271:18;;64405:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60131:4335;;;:::o;23011:226::-;23131:7;23167:12;23159:6;;;;23151:29;;;;-1:-1:-1;;;23151:29:0;;;;;;;;:::i;:::-;-1:-1:-1;23191:9:0;23203:5;23207:1;23203;:5;:::i;:::-;23191:17;23011:226;-1:-1:-1;;;;;23011:226:0:o;55292:280::-;-1:-1:-1;;;;;55375:31:0;;;;;;:25;:31;;;;;:39;;-1:-1:-1;;55375:39:0;;;;;;;;;;;;55427:80;;55453:15;;:42;;-1:-1:-1;;;55453:42:0;;-1:-1:-1;;;;;5253:55:1;;;55453:42:0;;;5235:74:1;55453:15:0;;;;:36;;5208:18:1;;55453:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55427:80;55524:40;;;;;;-1:-1:-1;;;;;55524:40:0;;;;;;;;55292:280;;:::o;64474:289::-;64580:14;;64540:7;;-1:-1:-1;;;64580:14:0;;;;:175;;-1:-1:-1;;;;;11321:18:0;;11289:7;11321:18;;;;;;;;;;;64580:175;;;-1:-1:-1;;;;;64637:21:0;;;;;;:12;:21;;;;;;64614:103;;64695:3;;64614:54;;64637:30;;64695:3;64637:25;:30::i;:::-;-1:-1:-1;;;;;11321:18:0;;11289:7;11321:18;;;;;;;;;;;64614;11170:177;25071:312;25191:7;25226:12;25219:5;25211:28;;;;-1:-1:-1;;;25211:28:0;;;;;;;;:::i;:::-;-1:-1:-1;25250:9:0;25262:5;25266:1;25262;:5;:::i;65702:589::-;65852:16;;;65866:1;65852:16;;;;;;;;65828:21;;65852:16;;;;;;;;;;-1:-1:-1;65852:16:0;65828:40;;65897:4;65879;65884:1;65879:7;;;;;;-1:-1:-1;;;65879:7:0;;;;;;;;;-1:-1:-1;;;;;65879:23:0;;;:7;;;;;;;;;;:23;;;;65923:15;;:22;;;;;;;;:15;;;;;:20;;:22;;;;;65879:7;;65923:22;;;;;:15;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65913:4;65918:1;65913:7;;;;;;-1:-1:-1;;;65913:7:0;;;;;;;;;-1:-1:-1;;;;;65913:32:0;;;:7;;;;;;;;;:32;65990:15;;65958:62;;65975:4;;65990:15;66008:11;65958:8;:62::i;:::-;66059:15;;:224;;;;;-1:-1:-1;;;;;66059:15:0;;;;:66;;:224;;66140:11;;66059:15;;66210:4;;66237;;66257:15;;66059:224;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65702:589;;:::o;15435:610::-;-1:-1:-1;;;;;15575:20:0;;15567:70;;;;-1:-1:-1;;;15567:70:0;;14531:2:1;15567:70:0;;;14513:21:1;14570:2;14550:18;;;14543:30;14609:34;14589:18;;;14582:62;-1:-1:-1;;;14660:18:1;;;14653:35;14705:19;;15567:70:0;14503:227:1;15567:70:0;-1:-1:-1;;;;;15656:23:0;;15648:71;;;;-1:-1:-1;;;15648:71:0;;9593:2:1;15648:71:0;;;9575:21:1;9632:2;9612:18;;;9605:30;9671:34;9651:18;;;9644:62;-1:-1:-1;;;9722:18:1;;;9715:33;9765:19;;15648:71:0;9565:225:1;15648:71:0;15812:108;15848:6;15812:108;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15812:17:0;;:9;:17;;;;;;;;;;;;:108;:21;:108::i;:::-;-1:-1:-1;;;;;15792:17:0;;;:9;:17;;;;;;;;;;;:128;;;;15954:20;;;;;;;:32;;15979:6;15954:24;:32::i;:::-;-1:-1:-1;;;;;15931:20:0;;;:9;:20;;;;;;;;;;;;:55;;;;16002:35;17246:25:1;;;15931:20:0;;16002:35;;;;;;17219:18:1;16002:35:0;17201:76:1;64771:923:0;64881:12;64896:13;:6;64907:1;64896:10;:13::i;:::-;64881:28;-1:-1:-1;64920:17:0;64940:16;:6;64881:28;64940:10;:16::i;:::-;64920:36;-1:-1:-1;65259:21:0;65325:22;65342:4;65325:16;:22::i;:::-;65478:18;65499:41;:21;65525:14;65499:25;:41::i;:::-;65478:62;;65590:35;65603:9;65614:10;65590:12;:35::i;:::-;65643:43;;;19105:25:1;;;19161:2;19146:18;;19139:34;;;19189:18;;;19182:34;;;65643:43:0;;19093:2:1;19078:18;65643:43:0;;;;;;;64771:923;;;;;:::o;67085:521::-;67265:15;;67233:62;;67250:4;;-1:-1:-1;;;;;67265:15:0;67283:11;67233:8;:62::i;:::-;67338:15;;67542;;67338:260;;;;;67410:4;67338:260;;;7790:34:1;7840:18;;;7833:34;;;67338:15:0;7883:18:1;;;7876:34;;;7926:18;;;7919:34;-1:-1:-1;;;;;67542:15:0;;;7969:19:1;;;7962:44;67572:15:0;8022:19:1;;;8015:35;67338:15:0;;;:31;;67377:9;;7701:19:1;;67338:260:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;14:257:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;812:398::-;880:6;888;941:2;929:9;920:7;916:23;912:32;909:2;;;962:6;954;947:22;909:2;1006:9;993:23;1025:31;1050:5;1025:31;:::i;:::-;1075:5;-1:-1:-1;1132:2:1;1117:18;;1104:32;1145:33;1104:32;1145:33;:::i;:::-;1197:7;1187:17;;;899:311;;;;;:::o;1215:466::-;1292:6;1300;1308;1361:2;1349:9;1340:7;1336:23;1332:32;1329:2;;;1382:6;1374;1367:22;1329:2;1426:9;1413:23;1445:31;1470:5;1445:31;:::i;:::-;1495:5;-1:-1:-1;1552:2:1;1537:18;;1524:32;1565:33;1524:32;1565:33;:::i;:::-;1319:362;;1617:7;;-1:-1:-1;;;1671:2:1;1656:18;;;;1643:32;;1319:362::o;1686:392::-;1751:6;1759;1812:2;1800:9;1791:7;1787:23;1783:32;1780:2;;;1833:6;1825;1818:22;1780:2;1877:9;1864:23;1896:31;1921:5;1896:31;:::i;:::-;1946:5;-1:-1:-1;2003:2:1;1988:18;;1975:32;2016:30;1975:32;2016:30;:::i;2083:567::-;2196:6;2204;2212;2220;2228;2236;2289:3;2277:9;2268:7;2264:23;2260:33;2257:2;;;2311:6;2303;2296:22;2257:2;2348:9;2342:16;2367:31;2392:5;2367:31;:::i;:::-;2462:2;2447:18;;2441:25;2506:2;2491:18;;2485:25;2550:2;2535:18;;2529:25;2594:3;2579:19;;2573:26;2639:3;2624:19;;;2618:26;2417:5;;2441:25;;-1:-1:-1;2485:25:1;;2529;;-1:-1:-1;2573:26:1;-1:-1:-1;2618:26:1;;-1:-1:-1;2247:403:1;-1:-1:-1;;;2247:403:1:o;2655:325::-;2723:6;2731;2784:2;2772:9;2763:7;2759:23;2755:32;2752:2;;;2805:6;2797;2790:22;2752:2;2849:9;2836:23;2868:31;2893:5;2868:31;:::i;:::-;2918:5;2970:2;2955:18;;;;2942:32;;-1:-1:-1;;;2742:238:1:o;2985:251::-;3041:6;3094:2;3082:9;3073:7;3069:23;3065:32;3062:2;;;3115:6;3107;3100:22;3062:2;3159:9;3146:23;3178:28;3200:5;3178:28;:::i;3241:255::-;3308:6;3361:2;3349:9;3340:7;3336:23;3332:32;3329:2;;;3382:6;3374;3367:22;3329:2;3419:9;3413:16;3438:28;3460:5;3438:28;:::i;3501:190::-;3560:6;3613:2;3601:9;3592:7;3588:23;3584:32;3581:2;;;3634:6;3626;3619:22;3581:2;-1:-1:-1;3662:23:1;;3571:120;-1:-1:-1;3571:120:1:o;3696:194::-;3766:6;3819:2;3807:9;3798:7;3794:23;3790:32;3787:2;;;3840:6;3832;3825:22;3787:2;-1:-1:-1;3868:16:1;;3777:113;-1:-1:-1;3777:113:1:o;3895:258::-;3963:6;3971;4024:2;4012:9;4003:7;3999:23;3995:32;3992:2;;;4045:6;4037;4030:22;3992:2;-1:-1:-1;;4073:23:1;;;4143:2;4128:18;;;4115:32;;-1:-1:-1;3982:171:1:o;4158:316::-;4246:6;4254;4262;4315:2;4303:9;4294:7;4290:23;4286:32;4283:2;;;4336:6;4328;4321:22;4283:2;4370:9;4364:16;4354:26;;4420:2;4409:9;4405:18;4399:25;4389:35;;4464:2;4453:9;4449:18;4443:25;4433:35;;4273:201;;;;;:::o;4479:395::-;4565:6;4573;4581;4589;4642:3;4630:9;4621:7;4617:23;4613:33;4610:2;;;4664:6;4656;4649:22;4610:2;-1:-1:-1;;4692:23:1;;;4762:2;4747:18;;4734:32;;-1:-1:-1;4813:2:1;4798:18;;4785:32;;4864:2;4849:18;4836:32;;-1:-1:-1;4600:274:1;-1:-1:-1;4600:274:1:o;8783:603::-;8895:4;8924:2;8953;8942:9;8935:21;8985:6;8979:13;9028:6;9023:2;9012:9;9008:18;9001:34;9053:4;9066:140;9080:6;9077:1;9074:13;9066:140;;;9175:14;;;9171:23;;9165:30;9141:17;;;9160:2;9137:26;9130:66;9095:10;;9066:140;;;9224:6;9221:1;9218:13;9215:2;;;9294:4;9289:2;9280:6;9269:9;9265:22;9261:31;9254:45;9215:2;-1:-1:-1;9370:2:1;9349:15;-1:-1:-1;;9345:29:1;9330:45;;;;9377:2;9326:54;;8904:482;-1:-1:-1;;;8904:482:1:o;17282:1029::-;17544:4;17592:3;17581:9;17577:19;17623:6;17612:9;17605:25;17649:2;17687:6;17682:2;17671:9;17667:18;17660:34;17730:3;17725:2;17714:9;17710:18;17703:31;17754:6;17789;17783:13;17820:6;17812;17805:22;17858:3;17847:9;17843:19;17836:26;;17897:2;17889:6;17885:15;17871:29;;17918:4;17931:218;17945:6;17942:1;17939:13;17931:218;;;18010:13;;-1:-1:-1;;;;;18006:62:1;17994:75;;18124:15;;;;18089:12;;;;17967:1;17960:9;17931:218;;;-1:-1:-1;;;;;;;18205:55:1;;;;18200:2;18185:18;;18178:83;-1:-1:-1;;;18292:3:1;18277:19;18270:35;18166:3;17553:758;-1:-1:-1;;;17553:758:1:o;19812:128::-;19852:3;19883:1;19879:6;19876:1;19873:13;19870:2;;;19889:18;;:::i;:::-;-1:-1:-1;19925:9:1;;19860:80::o;19945:274::-;19985:1;20011;20001:2;;-1:-1:-1;;;20043:1:1;20036:88;20147:4;20144:1;20137:15;20175:4;20172:1;20165:15;20001:2;-1:-1:-1;20204:9:1;;19991:228::o;20224:168::-;20264:7;20330:1;20326;20322:6;20318:14;20315:1;20312:21;20307:1;20300:9;20293:17;20289:45;20286:2;;;20337:18;;:::i;:::-;-1:-1:-1;20377:9:1;;20276:116::o;20397:125::-;20437:4;20465:1;20462;20459:8;20456:2;;;20470:18;;:::i;:::-;-1:-1:-1;20507:9:1;;20446:76::o;20527:437::-;20606:1;20602:12;;;;20649;;;20670:2;;20724:4;20716:6;20712:17;20702:27;;20670:2;20777;20769:6;20766:14;20746:18;20743:38;20740:2;;;-1:-1:-1;;;20811:1:1;20804:88;20915:4;20912:1;20905:15;20943:4;20940:1;20933:15;20740:2;;20582:382;;;:::o;20969:184::-;-1:-1:-1;;;21018:1:1;21011:88;21118:4;21115:1;21108:15;21142:4;21139:1;21132:15;21158:154;-1:-1:-1;;;;;21237:5:1;21233:54;21226:5;21223:65;21213:2;;21302:1;21299;21292:12;21317:118;21403:5;21396:13;21389:21;21382:5;21379:32;21369:2;;21425:1;21422;21415:12

Swarm Source

ipfs://58a930dca684adcddf0226e4202f7551f9505675bf8d4b2b37f47f043ae45591
Loading