ETH Price: $3,501.57 (+2.48%)
Gas: 15 Gwei

Token

Pearl Token (PEARL)
 

Overview

Max Total Supply

10,000,000,000,000 PEARL

Holders

89

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
1,210,621,458.964048880087675814 PEARL

Value
$0.00
0x5C251c9C4a1eA95104e020873cE70C07Fa6d8A20
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
PearlToken

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT

pragma solidity 0.8.11;


// 
/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
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;
    }

    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = x < y ? x : y;
    }

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
}

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

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

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

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

    /**
     * @dev Returns the bep token owner.
     */
    function getOwner() external view returns (address);

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

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

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

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

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

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

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

// 
/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            codehash := extcodehash(account)
        }
        return (codehash != accountHash && codehash != 0x0);
    }

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

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

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

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

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

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

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        require(isContract(target), 'Address: call to non-contract');

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: weiValue}(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

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

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

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

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

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

    function safeDecreaseAllowance(
        IBEP20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(
            value,
            'SafeBEP20: decreased allowance below zero'
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

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

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

// 
/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor() {}

    function _msgSender() internal view returns (address payable) {
        return payable(msg.sender);
    }

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

// 
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
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 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), 'Ownable: new owner is the zero address');
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

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

    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the bep token owner.
     */
    function getOwner() external override view returns (address) {
        return owner();
    }

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

    /**
     * @dev Returns the token decimals.
     */
    function decimals() public override view returns (uint8) {
        return _decimals;
    }

    /**
     * @dev Returns the token symbol.
     */
    function symbol() public override view returns (string memory) {
        return _symbol;
    }

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

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

    /**
     * @dev See {BEP20-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 override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

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

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

    /**
     * @dev See {BEP20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {BEP20};
     *
     * 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 override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(amount, 'BEP20: 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 {BEP20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public 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 {BEP20-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 returns (bool) {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].sub(subtractedValue, 'BEP20: decreased allowance below zero')
        );
        return true;
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `msg.sender`, increasing
     * the total supply.
     *
     * Requirements
     *
     * - `msg.sender` must be the token owner
     */
    function mint(uint256 amount) public onlyOwner returns (bool) {
        _mint(_msgSender(), amount);
        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), 'BEP20: transfer from the zero address');
        require(recipient != address(0), 'BEP20: transfer to the zero address');

        _balances[sender] = _balances[sender].sub(amount, 'BEP20: 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
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), 'BEP20: mint to the zero address');

        _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 {
        require(account != address(0), 'BEP20: burn from the zero address');

        _balances[account] = _balances[account].sub(amount, 'BEP20: 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 is 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 {
        require(owner != address(0), 'BEP20: approve from the zero address');
        require(spender != address(0), 'BEP20: approve to the zero address');

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

    /**
     * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See {_burn} and {_approve}.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(
            account,
            _msgSender(),
            _allowances[account][_msgSender()].sub(amount, 'BEP20: burn amount exceeds allowance')
        );
    }
}

interface IDexRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

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

interface IDexFactory {
    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}

// PearlToken with Governance.
contract PearlToken is BEP20('Pearl Token', 'PEARL') {

    mapping (address => address) internal _delegates;

    /// @notice A checkpoint for marking number of votes from a given block
    struct Checkpoint {
        uint32 fromBlock;
        uint256 votes;
    }

    IDexRouter public immutable dexRouter;
    address public immutable lpPair;

    uint256 public maxBuyAmount;
    uint256 public maxSellAmount;

    address public operationsAddress;
    address public charityAddress;

    bool private swapping;
    uint256 public swapTokensAtAmount;

    bool public limitsInEffect = true;
    bool public tradingActive = false;
    bool public swapEnabled = false;
    
    uint256 public tradingActiveBlock = 0; // 0 means trading is not active
    uint256 public earlyBuyPenaltyEnd; // determines when snipers/bots can sell without extra penalty
    
     // Anti-bot and anti-whale mappings and variables
    mapping(address => uint256) private _holderLastTransferTimestamp; // to hold last Transfers temporarily during launch
    bool public transferDelayEnabled = true;

    bool private gasLimitActive = true;
    uint256 private constant gasPriceLimit = 400 * 1 gwei; // do not allow over x gwei for launch

    uint256 public buyTotalFees;
    uint256 public buyOperationsFee;
    uint256 public buyLiquidityFee;
    uint256 public buyCharityFee;

    uint256 public sellTotalFees;
    uint256 public sellOperationsFee;
    uint256 public sellLiquidityFee;
    uint256 public sellCharityFee;

    uint256 public tokensForOperations;
    uint256 public tokensForLiquidity;
    uint256 public tokensForCharity;
    
    /******************/

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

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

    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);

    event BoughtEarly(address indexed sniper);
    
    event RemovedSniper(address indexed notsnipersupposedly);

    event EnabledTrading();

    event ExcludeFromFees(address indexed account, bool isExcluded);

    event UpdatedMaxBuyAmount(uint256 newAmount);

    event UpdatedMaxSellAmount(uint256 newAmount);

    event UpdatedOperationsAddress(address indexed newWallet);

    event UpdatedCharityAddress(address indexed newWallet);

    event MaxTransactionExclusion(address _address, bool excluded);

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

    event TransferForeignToken(address token, uint256 amount);

    /// @notice A record of votes checkpoints for each account, by index
    mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

    /// @notice The number of checkpoints for each account
    mapping (address => uint32) public numCheckpoints;

    /// @notice The EIP-712 typehash for the contract's domain
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    /// @notice The EIP-712 typehash for the delegation struct used by the contract
    bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    /// @notice A record of states for signing / validating signatures
    mapping (address => uint) public nonces;

      /// @notice An event thats emitted when an account changes its delegate
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /// @notice An event thats emitted when a delegate account's vote balance changes
    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

    constructor() {
        
        address newOwner = msg.sender; // can leave alone if owner is deployer.
        
        IDexRouter _dexRouter = IDexRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

        _excludeFromMaxTransaction(address(_dexRouter), true);
        dexRouter = _dexRouter;
        
        lpPair = IDexFactory(_dexRouter.factory()).createPair(address(this), _dexRouter.WETH());
        _setAutomatedMarketMakerPair(address(lpPair), true);
 
        uint256 totalSupply = 10* 1e12 * 1e18;
        
        maxBuyAmount = totalSupply * 1 / 1000;
        maxSellAmount = totalSupply * 1 / 1000; 
        swapTokensAtAmount = totalSupply * 1 / 10000; // 0.01% swap amount

        buyOperationsFee = 5;
        buyLiquidityFee = 5;
        buyCharityFee = 0;
        buyTotalFees = buyOperationsFee + buyLiquidityFee + buyCharityFee;

        sellOperationsFee = 10;
        sellLiquidityFee = 10;
        sellCharityFee = 0;
        sellTotalFees = sellOperationsFee + sellLiquidityFee + sellCharityFee;

        _excludeFromMaxTransaction(newOwner, true);
        _excludeFromMaxTransaction(address(this), true);
        _excludeFromMaxTransaction(address(0xdead), true);

        excludeFromFees(newOwner, true);

        operationsAddress = address(0x5bFf5d0a17d48dCb3EeCa101eE758cBe5dB68A44);
        charityAddress = address(0x5bFf5d0a17d48dCb3EeCa101eE758cBe5dB68A44);
        
        _mint(newOwner, totalSupply);
        transferOwnership(newOwner);
    }

    receive() external payable {
  	}

    // once enabled, can never be turned off
    function enableTrading() external onlyOwner {
        require(!tradingActive, "Cannot reenable trading");
        tradingActive = true;
        swapEnabled = true;
        tradingActiveBlock = block.number;
        emit EnabledTrading();
    }
    
    // remove limits after token is stable
    function removeLimits() external onlyOwner {
        limitsInEffect = false;
        transferDelayEnabled = false;
        gasLimitActive = false;
    }
    
    // disable Transfer delay - cannot be reenabled
    function disableTransferDelay() external onlyOwner {
        transferDelayEnabled = false;
    }
    
    function updateMaxBuyAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 1 / 1000)/1e18, "Cannot set max buy amount lower than 0.1%");
        maxBuyAmount = newNum * (10**18);
        emit UpdatedMaxBuyAmount(maxBuyAmount);
    }
    
    function updateMaxSellAmount(uint256 newNum) external onlyOwner {
        require(newNum >= (totalSupply() * 1 / 1000)/1e18, "Cannot set max sell amount lower than 0.1%");
        maxSellAmount = newNum * (10**18);
        emit UpdatedMaxSellAmount(maxSellAmount);
    }

    // change the minimum amount of tokens to sell from fees
    function updateSwapTokensAtAmount(uint256 newAmount) external onlyOwner {
  	    require(newAmount >= totalSupply() * 1 / 100000, "Swap amount cannot be lower than 0.001% total supply.");
  	    require(newAmount <= totalSupply() * 1 / 1000, "Swap amount cannot be higher than 0.1% total supply.");
  	    swapTokensAtAmount = newAmount;
  	}
    
    function _excludeFromMaxTransaction(address updAds, bool isExcluded) private {
        _isExcludedMaxTransactionAmount[updAds] = isExcluded;
        emit MaxTransactionExclusion(updAds, isExcluded);
    }

    function airdropToWallets(address[] memory airdropWallets, uint256[] memory amounts) external onlyOwner returns (bool){
        require(!tradingActive, "Trading is already active, cannot airdrop after launch.");
        require(airdropWallets.length == amounts.length, "arrays must be the same length");
        require(airdropWallets.length < 200, "Can only airdrop 200 wallets per txn due to gas limits"); // allows for airdrop + launch at the same exact time, reducing delays and reducing sniper input.
        for(uint256 i = 0; i < airdropWallets.length; i++){
            address wallet = airdropWallets[i];
            uint256 amount = amounts[i];
            super._transfer(msg.sender, wallet, amount);
        }
        return true;
    }
    
    function excludeFromMaxTransaction(address updAds, bool isEx) external onlyOwner {
        if(!isEx){
            require(updAds != lpPair, "Cannot remove uniswap pair from max txn");
        }
        _isExcludedMaxTransactionAmount[updAds] = isEx;
    }

    function setAutomatedMarketMakerPair(address pair, bool value) external onlyOwner {
        require(pair != lpPair, "The pair cannot be removed from automatedMarketMakerPairs");

        _setAutomatedMarketMakerPair(pair, value);
    }

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

        emit SetAutomatedMarketMakerPair(pair, value);
    }

    function updateBuyFees(uint256 _operationsFee, uint256 _liquidityFee, uint256 _charityFee) external onlyOwner {
        buyOperationsFee = _operationsFee;
        buyLiquidityFee = _liquidityFee;
        buyCharityFee = _charityFee;
        buyTotalFees = buyOperationsFee + buyLiquidityFee + buyCharityFee;
        require(buyTotalFees <= 10, "Must keep fees at 10% or less");
    }

    function updateSellFees(uint256 _operationsFee, uint256 _liquidityFee, uint256 _charityFee) external onlyOwner {
        sellOperationsFee = _operationsFee;
        sellLiquidityFee = _liquidityFee;
        sellCharityFee = _charityFee;
        sellTotalFees = sellOperationsFee + sellLiquidityFee + sellCharityFee;
        require(sellTotalFees <= 20, "Must keep fees at 20% or less");
    }

    function excludeFromFees(address account, bool excluded) public onlyOwner {
        _isExcludedFromFees[account] = excluded;
        emit ExcludeFromFees(account, excluded);
    }

    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");
        if(amount == 0){
            super._transfer(from, to, 0);
            return;
        }
        
        if(limitsInEffect){
            if (from != owner() && to != owner() && to != address(0) && to != address(0xdead)){
                if(!tradingActive){
                    require(_isExcludedMaxTransactionAmount[from] || _isExcludedMaxTransactionAmount[to], "Trading is not active.");
                }

                // only use to prevent sniper buys in the first blocks.
                if (gasLimitActive && automatedMarketMakerPairs[from]) {
                    require(tx.gasprice <= gasPriceLimit, "Gas price exceeds limit.");
                }
                
                // at launch if the transfer delay is enabled, ensure the block timestamps for purchasers is set -- during launch.  
                if (transferDelayEnabled){
                    if (to != address(dexRouter) && to != address(lpPair)){
                        require(_holderLastTransferTimestamp[tx.origin] < block.number, "_transfer:: Transfer Delay enabled.  Only one purchase per block allowed.");
                        _holderLastTransferTimestamp[tx.origin] = block.number;
                    }
                }
                 
                //when buy
                if (automatedMarketMakerPairs[from] && !_isExcludedMaxTransactionAmount[to]) {
                        require(amount <= maxBuyAmount, "Buy transfer amount exceeds the max buy.");
                } 
                //when sell
                else if (automatedMarketMakerPairs[to] && !_isExcludedMaxTransactionAmount[from]) {
                        require(amount <= maxSellAmount, "Sell transfer amount exceeds the max sell.");
                }
            }
        }

        uint256 contractTokenBalance = balanceOf(address(this));
        
        bool canSwap = contractTokenBalance >= swapTokensAtAmount;

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

            swapBack();

            swapping = false;
        }

        bool takeFee = true;
        // if any account belongs to _isExcludedFromFee account then remove the fee
        if(_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
            takeFee = false;
        }
        
        uint256 fees = 0;
        // only take fees on buys/sells, do not take on wallet transfers
        if(takeFee){
            if(block.number == tradingActiveBlock && automatedMarketMakerPairs[from]){
                fees = amount * 95 / 100;
                tokensForLiquidity += fees * sellLiquidityFee / sellTotalFees;
                tokensForOperations += fees * sellOperationsFee / sellTotalFees;
                tokensForCharity += fees * sellCharityFee / sellTotalFees;
            }
            // on sell
            if (automatedMarketMakerPairs[to] && sellTotalFees > 0){
                fees = amount * sellTotalFees /100;
                tokensForLiquidity += fees * sellLiquidityFee / sellTotalFees;
                tokensForOperations += fees * sellOperationsFee / sellTotalFees;
                tokensForCharity += fees * sellCharityFee / sellTotalFees;
            }
            // on buy
            else if(automatedMarketMakerPairs[from] && buyTotalFees > 0) {
        	    fees = amount * buyTotalFees / 100;
        	    tokensForLiquidity += fees * buyLiquidityFee / buyTotalFees;
                tokensForOperations += fees * buyOperationsFee / buyTotalFees;
                tokensForCharity += fees * buyCharityFee / buyTotalFees;
            }
            
            if(fees > 0){    
                super._transfer(from, address(this), fees);
            }
        	
        	amount -= fees;
        }

        super._transfer(from, to, amount);
    }

    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] = dexRouter.WETH();

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

        // make the swap
        dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }
    
    function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        // approve token transfer to cover all possible scenarios
        _approve(address(this), address(dexRouter), tokenAmount);

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

    function swapBack() private {
        uint256 contractBalance = balanceOf(address(this));
        uint256 totalTokensToSwap = tokensForLiquidity + tokensForOperations + tokensForCharity;
        
        if(contractBalance == 0 || totalTokensToSwap == 0) {return;}

        if(contractBalance > swapTokensAtAmount * 10){
            contractBalance = swapTokensAtAmount * 10;
        }

        bool success;
        
        // Halve the amount of liquidity tokens
        uint256 liquidityTokens = contractBalance * tokensForLiquidity / totalTokensToSwap / 2;
        
        swapTokensForEth(contractBalance - liquidityTokens); 
        
        uint256 ethBalance = address(this).balance;
        uint256 ethForLiquidity = ethBalance;

        uint256 ethForOperations = ethBalance * tokensForOperations / (totalTokensToSwap - (tokensForLiquidity/2));
        uint256 ethForCharity = ethBalance * tokensForCharity / (totalTokensToSwap - (tokensForLiquidity/2));

        ethForLiquidity -= ethForOperations + ethForCharity;
            
        tokensForLiquidity = 0;
        tokensForOperations = 0;
        
        if(liquidityTokens > 0 && ethForLiquidity > 0){
            addLiquidity(liquidityTokens, ethForLiquidity);
        }
        
        (success,) = address(charityAddress).call{value: ethForCharity}("");
        (success,) = address(operationsAddress).call{value: address(this).balance}("");
    }

    function transferForeignToken(address _token, address _to) external onlyOwner returns (bool _sent) {
        require(_token != address(0), "_token address cannot be 0");
        require(_token != address(this), "Can't withdraw native tokens");
        uint256 _contractBalance = IBEP20(_token).balanceOf(address(this));
        _sent = IBEP20(_token).transfer(_to, _contractBalance);
        emit TransferForeignToken(_token, _contractBalance);
    }

    // withdraw ETH if stuck or someone sends to the address
    function withdrawStuckETH() external onlyOwner {
        bool success;
        (success,) = address(msg.sender).call{value: address(this).balance}("");
    }

    function setOperationsAddress(address _operationsAddress) external onlyOwner {
        require(_operationsAddress != address(0), "_operationsAddress address cannot be 0");
        _isExcludedFromFees[operationsAddress] = false;
        operationsAddress = payable(_operationsAddress);
        _isExcludedFromFees[operationsAddress] = true;
        emit UpdatedOperationsAddress(_operationsAddress);
    }

    function setCharityAddress(address _charityAddress) external onlyOwner {
        require(_charityAddress != address(0), "_operationsAddress address cannot be 0");
        charityAddress = payable(_charityAddress);
        emit UpdatedCharityAddress(_charityAddress);
    }


    /**
     * @notice Delegate votes from `msg.sender` to `delegatee`
     * @param delegator The address to get delegatee for
     */
    function delegates(address delegator)
        external
        view
        returns (address)
    {
        return _delegates[delegator];
    }

   /**
    * @notice Delegate votes from `msg.sender` to `delegatee`
    * @param delegatee The address to delegate votes to
    */
    function delegate(address delegatee) external {
        return _delegate(msg.sender, delegatee);
    }

    /**
     * @notice Delegates votes from signatory to `delegatee`
     * @param delegatee The address to delegate votes to
     * @param nonce The contract state required to match the signature
     * @param expiry The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function delegateBySig(
        address delegatee,
        uint nonce,
        uint expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
    {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name())),
                getChainId(),
                address(this)
            )
        );

        bytes32 structHash = keccak256(
            abi.encode(
                DELEGATION_TYPEHASH,
                delegatee,
                nonce,
                expiry
            )
        );

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                structHash
            )
        );

        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "PEARL::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "PEARL::delegateBySig: invalid nonce");
        require(block.timestamp <= expiry, "PEARL::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }

    /**
     * @notice Gets the current votes balance for `account`
     * @param account The address to get votes balance
     * @return The number of current votes for `account`
     */
    function getCurrentVotes(address account)
        external
        view
        returns (uint256)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    /**
     * @notice Determine the prior number of votes for an account as of a block number
     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
     * @param account The address of the account to check
     * @param blockNumber The block number to get the vote balance at
     * @return The number of votes the account had as of the given block
     */
    function getPriorVotes(address account, uint blockNumber)
        external
        view
        returns (uint256)
    {
        require(blockNumber < block.number, "PEARL::getPriorVotes: not yet determined");

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        // First check most recent balance
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        // Next check implicit zero balance
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _delegate(address delegator, address delegatee)
        internal
    {
        address currentDelegate = _delegates[delegator];
        uint256 delegatorBalance = balanceOf(delegator); // balance of underlying PEARLs (not scaled);
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != address(0)) {
                // decrease old representative
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                uint256 srcRepNew = srcRepOld - amount;
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != address(0)) {
                // increase new representative
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                uint256 dstRepNew = dstRepOld + amount;
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint256 oldVotes,
        uint256 newVotes
    )
        internal
    {
        uint32 blockNumber = safe32(block.number, "PEARL::_writeCheckpoint: block number exceeds 32 bits");

        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    function getChainId() internal view returns (uint) {
        uint256 chainId;
        assembly { chainId := chainid() }
        return chainId;
    }
}

// OysterBar with Governance.
contract OysterBar is BEP20('OysterBar Token', 'OYSTER') {
    /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
    function mint(address _to, uint256 _amount) public onlyOwner {
        _mint(_to, _amount);
        _moveDelegates(address(0), _delegates[_to], _amount);
    }

    function burn(address _from ,uint256 _amount) public onlyOwner {
        _burn(_from, _amount);
        _moveDelegates(address(0), _delegates[_from], _amount);
    }

    // The PEARL TOKEN!
    PearlToken public pearl;


    constructor(
        address _pearl
    ) {
        pearl = PearlToken(payable(_pearl));
    }

    // Safe pearl transfer function, just in case if rounding error causes pool to not have enough PEARLs.
    function safePearlTransfer(address _to, uint256 _amount) public onlyOwner {
        uint256 pearlBal = pearl.balanceOf(address(this));
        if (_amount > pearlBal) {
            pearl.transfer(_to, pearlBal);
        } else {
            pearl.transfer(_to, _amount);
        }
    }

    // Copied and modified from YAM code:
    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
    // Which is copied and modified from COMPOUND:
    // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol

    /// @notice A record of each accounts delegate
    mapping (address => address) internal _delegates;

    /// @notice A checkpoint for marking number of votes from a given block
    struct Checkpoint {
        uint32 fromBlock;
        uint256 votes;
    }

    /// @notice A record of votes checkpoints for each account, by index
    mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

    /// @notice The number of checkpoints for each account
    mapping (address => uint32) public numCheckpoints;

    /// @notice The EIP-712 typehash for the contract's domain
    bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

    /// @notice The EIP-712 typehash for the delegation struct used by the contract
    bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    /// @notice A record of states for signing / validating signatures
    mapping (address => uint) public nonces;

      /// @notice An event thats emitted when an account changes its delegate
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /// @notice An event thats emitted when a delegate account's vote balance changes
    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

    /**
     * @notice Delegate votes from `msg.sender` to `delegatee`
     * @param delegator The address to get delegatee for
     */
    function delegates(address delegator)
        external
        view
        returns (address)
    {
        return _delegates[delegator];
    }

   /**
    * @notice Delegate votes from `msg.sender` to `delegatee`
    * @param delegatee The address to delegate votes to
    */
    function delegate(address delegatee) external {
        return _delegate(msg.sender, delegatee);
    }

    /**
     * @notice Delegates votes from signatory to `delegatee`
     * @param delegatee The address to delegate votes to
     * @param nonce The contract state required to match the signature
     * @param expiry The time at which to expire the signature
     * @param v The recovery byte of the signature
     * @param r Half of the ECDSA signature pair
     * @param s Half of the ECDSA signature pair
     */
    function delegateBySig(
        address delegatee,
        uint nonce,
        uint expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
    {
        bytes32 domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPEHASH,
                keccak256(bytes(name())),
                getChainId(),
                address(this)
            )
        );

        bytes32 structHash = keccak256(
            abi.encode(
                DELEGATION_TYPEHASH,
                delegatee,
                nonce,
                expiry
            )
        );

        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                domainSeparator,
                structHash
            )
        );

        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), "PEARL::delegateBySig: invalid signature");
        require(nonce == nonces[signatory]++, "PEARL::delegateBySig: invalid nonce");
        require(block.timestamp <= expiry, "PEARL::delegateBySig: signature expired");
        return _delegate(signatory, delegatee);
    }

    /**
     * @notice Gets the current votes balance for `account`
     * @param account The address to get votes balance
     * @return The number of current votes for `account`
     */
    function getCurrentVotes(address account)
        external
        view
        returns (uint256)
    {
        uint32 nCheckpoints = numCheckpoints[account];
        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
    }

    /**
     * @notice Determine the prior number of votes for an account as of a block number
     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
     * @param account The address of the account to check
     * @param blockNumber The block number to get the vote balance at
     * @return The number of votes the account had as of the given block
     */
    function getPriorVotes(address account, uint blockNumber)
        external
        view
        returns (uint256)
    {
        require(blockNumber < block.number, "PEARL::getPriorVotes: not yet determined");

        uint32 nCheckpoints = numCheckpoints[account];
        if (nCheckpoints == 0) {
            return 0;
        }

        // First check most recent balance
        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
            return checkpoints[account][nCheckpoints - 1].votes;
        }

        // Next check implicit zero balance
        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = nCheckpoints - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
            Checkpoint memory cp = checkpoints[account][center];
            if (cp.fromBlock == blockNumber) {
                return cp.votes;
            } else if (cp.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _delegate(address delegator, address delegatee)
        internal
    {
        address currentDelegate = _delegates[delegator];
        uint256 delegatorBalance = balanceOf(delegator); // balance of underlying PEARLs (not scaled);
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveDelegates(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
        if (srcRep != dstRep && amount > 0) {
            if (srcRep != address(0)) {
                // decrease old representative
                uint32 srcRepNum = numCheckpoints[srcRep];
                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                uint256 srcRepNew = srcRepOld - amount;
                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
            }

            if (dstRep != address(0)) {
                // increase new representative
                uint32 dstRepNum = numCheckpoints[dstRep];
                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                uint256 dstRepNew = dstRepOld + amount;
                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
            }
        }
    }

    function _writeCheckpoint(
        address delegatee,
        uint32 nCheckpoints,
        uint256 oldVotes,
        uint256 newVotes
    )
        internal
    {
        uint32 blockNumber = safe32(block.number, "PEARL::_writeCheckpoint: block number exceeds 32 bits");

        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
        } else {
            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
            numCheckpoints[delegatee] = nCheckpoints + 1;
        }

        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
    }

    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
        require(n < 2**32, errorMessage);
        return uint32(n);
    }

    function getChainId() internal view returns (uint) {
        uint256 chainId;
        assembly { chainId := chainid() }
        return chainId;
    }
}

// MasterChef is the master of Pearl. He can make Pearl and he is a fair guy.
//
// Note that it's ownable and the owner wields tremendous power. The ownership
// will be transferred to a governance smart contract once PEARL is sufficiently
// distributed and the community can show to govern itself.
//
// Have fun reading it. Hopefully it's bug-free. God bless.
contract MasterChef is Ownable {
    using SafeMath for uint256;
    using SafeBEP20 for IBEP20;

    // Info of each user.
    struct UserInfo {
        uint256 amount;     // How many LP tokens the user has provided.
        uint256 rewardDebt; // Reward debt. See explanation below.
        //
        // We do some fancy math here. Basically, any point in time, the amount of PEARLs
        // entitled to a user but is pending to be distributed is:
        //
        //   pending reward = (user.amount * pool.accPearlPerShare) - user.rewardDebt
        //
        // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens:
        //   1. The pool's `accPearlPerShare` (and `lastRewardBlock`) gets updated.
        //   2. User receives the pending reward sent to his/her address.
        //   3. User's `amount` gets updated.
        //   4. User's `rewardDebt` gets updated.
    }

    // Info of each pool.
    struct PoolInfo {
        IBEP20 lpToken;           // Address of LP token contract.
        uint256 allocPoint;       // How many allocation points assigned to this pool. PEARLs to distribute per block.
        uint256 lastRewardBlock;  // Last block number that PEARLs distribution occurs.
        uint256 accPearlPerShare; // Accumulated PEARLs per share, times 1e12. See below.
    }

    // The PEARL TOKEN!
    PearlToken public pearl;
    // The OYSTER TOKEN!
    OysterBar public oyster;
    // PEARL tokens created per block.
    uint256 public pearlPerBlock;
    // Bonus muliplier for early pearl makers.
    uint256 public BONUS_MULTIPLIER = 0;
    
    // Avoid needing a Souschef by tracking staked pearl internally.
    uint256 public pearlStaked;

    // Info of each pool.
    PoolInfo[] public poolInfo;
    // Info of each user that stakes LP tokens.
    mapping (uint256 => mapping (address => UserInfo)) public userInfo;
    // Total allocation poitns. Must be the sum of all allocation points in all pools.
    uint256 public totalAllocPoint = 0;
    // The block number when PEARL mining starts.
    uint256 public startBlock;

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
    event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);

    constructor(
    ) {
        pearl = new PearlToken();
        oyster = new OysterBar(address(pearl));
        pearlPerBlock = 1e18;
        startBlock = block.number;

        pearl.excludeFromFees(address(this), true);
        pearl.excludeFromMaxTransaction(address(this), true);
        pearl.transfer(msg.sender, pearl.balanceOf(address(this)));
        pearl.transferOwnership(msg.sender);

        // staking pool
        poolInfo.push(PoolInfo({
            lpToken: pearl,
            allocPoint: 1000,
            lastRewardBlock: startBlock,
            accPearlPerShare: 0
        }));

        totalAllocPoint = 1000;

    }

    function updateMultiplier(uint256 multiplierNumber) public onlyOwner {
        BONUS_MULTIPLIER = multiplierNumber;
    }

    function poolLength() external view returns (uint256) {
        return poolInfo.length;
    }

    // Add a new lp to the pool. Can only be called by the owner.
    // XXX DO NOT add the same LP token more than once. Rewards will be messed up if you do.
    function add(uint256 _allocPoint, IBEP20 _lpToken, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
        totalAllocPoint = totalAllocPoint.add(_allocPoint);
        poolInfo.push(PoolInfo({
            lpToken: _lpToken,
            allocPoint: _allocPoint,
            lastRewardBlock: lastRewardBlock,
            accPearlPerShare: 0
        }));
        updateStakingPool();
    }

    // Update the given pool's PEARL allocation point. Can only be called by the owner.
    function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
        uint256 prevAllocPoint = poolInfo[_pid].allocPoint;
        poolInfo[_pid].allocPoint = _allocPoint;
        if (prevAllocPoint != _allocPoint) {
            updateStakingPool();
        }
    }

    function updateStakingPool() internal {
        uint256 length = poolInfo.length;
        uint256 points = 0;
        for (uint256 pid = 1; pid < length; ++pid) {
            points = points.add(poolInfo[pid].allocPoint);
        }
        if (points != 0) {
            points = points.div(3);
            totalAllocPoint = totalAllocPoint.sub(poolInfo[0].allocPoint).add(points);
            poolInfo[0].allocPoint = points;
        }
    }

    // Return reward multiplier over the given _from to _to block.
    function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) {
        return _to.sub(_from).mul(BONUS_MULTIPLIER);
    }

    // View function to see pending PEARLs on frontend.
    function pendingPearl(uint256 _pid, address _user) external view returns (uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        uint256 accPearlPerShare = pool.accPearlPerShare;
        uint256 lpSupply = pool.lpToken.balanceOf(address(this));

        if (_pid == 0){
            lpSupply = pearlStaked;
        }

        if (block.number > pool.lastRewardBlock && lpSupply != 0) {
            uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
            uint256 pearlReward = multiplier.mul(pearlPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
            accPearlPerShare = accPearlPerShare.add(pearlReward.mul(1e12).div(lpSupply));
        }
        return user.amount.mul(accPearlPerShare).div(1e12).sub(user.rewardDebt);
    }

    // Update reward variables for all pools. Be careful of gas spending!
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            updatePool(pid);
        }
    }


    // Update reward variables of the given pool to be up-to-date.
    function updatePool(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        if (block.number <= pool.lastRewardBlock) {
            return;
        }
        uint256 lpSupply = pool.lpToken.balanceOf(address(this));
        if (_pid == 0){
            lpSupply = pearlStaked;
        }
        
        if (lpSupply == 0) {
            pool.lastRewardBlock = block.number;
            return;
        }

        
        uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
        uint256 pearlReward = multiplier.mul(pearlPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
        pool.accPearlPerShare = pool.accPearlPerShare.add(pearlReward.mul(1e12).div(lpSupply));
        pool.lastRewardBlock = block.number;
    }

    // Deposit LP tokens to MasterChef for PEARL allocation.
    function deposit(uint256 _pid, uint256 _amount) public {

        require (_pid != 0, 'deposit PEARL by staking');

        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        updatePool(_pid);
        if (user.amount > 0) {
            uint256 pending = user.amount.mul(pool.accPearlPerShare).div(1e12).sub(user.rewardDebt);
            if(pending > 0) {
                pearl.transfer(msg.sender, pending);
            }
        }
        if (_amount > 0) {
            pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
            user.amount = user.amount.add(_amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPearlPerShare).div(1e12);
        emit Deposit(msg.sender, _pid, _amount);
    }

    // Withdraw LP tokens from MasterChef.
    function withdraw(uint256 _pid, uint256 _amount) public {

        require (_pid != 0, 'withdraw PEARL by unstaking');

        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        require(user.amount >= _amount, "withdraw: not good");
        updatePool(_pid);
        uint256 pending = user.amount.mul(pool.accPearlPerShare).div(1e12).sub(user.rewardDebt);
        if(pending > 0) {
            pearl.transfer(msg.sender, pending);
        }
        if(_amount > 0) {
            user.amount = user.amount.sub(_amount);
            pool.lpToken.safeTransfer(address(msg.sender), _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPearlPerShare).div(1e12);
        emit Withdraw(msg.sender, _pid, _amount);
    }

    // Stake PEARL tokens to MasterChef
    function enterStaking(uint256 _amount) public {
        PoolInfo storage pool = poolInfo[0];
        UserInfo storage user = userInfo[0][msg.sender];
        updatePool(0);
        if (user.amount > 0) {
            uint256 pending = user.amount.mul(pool.accPearlPerShare).div(1e12).sub(user.rewardDebt);
            if(pending > 0) {
                pearl.transfer(msg.sender, pending);
            }
        }
        if(_amount > 0) {
            pool.lpToken.safeTransferFrom(address(msg.sender), address(oyster), _amount);
            user.amount = user.amount.add(_amount);
            pearlStaked += _amount;
        }
        user.rewardDebt = user.amount.mul(pool.accPearlPerShare).div(1e12);

        oyster.mint(msg.sender, _amount);
        emit Deposit(msg.sender, 0, _amount);
    }

    // Withdraw PEARL tokens from STAKING.
    function leaveStaking(uint256 _amount) public {
        PoolInfo storage pool = poolInfo[0];
        UserInfo storage user = userInfo[0][msg.sender];
        require(user.amount >= _amount, "withdraw: not good");
        updatePool(0);
        uint256 pending = user.amount.mul(pool.accPearlPerShare).div(1e12).sub(user.rewardDebt);
        if(pending > 0) {
            pearl.transfer(msg.sender, pending);
        }
        if(_amount > 0) {
            user.amount = user.amount.sub(_amount);
            pearlStaked -= _amount;
            safePearlTransfer(address(msg.sender), _amount);
        }
        user.rewardDebt = user.amount.mul(pool.accPearlPerShare).div(1e12);

        oyster.burn(msg.sender, _amount);
        emit Withdraw(msg.sender, 0, _amount);
    }

    // Withdraw without caring about rewards. EMERGENCY ONLY.
    function emergencyWithdraw(uint256 _pid) public {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][msg.sender];
        pool.lpToken.safeTransfer(address(msg.sender), user.amount);
        emit EmergencyWithdraw(msg.sender, _pid, user.amount);
        if(_pid == 0){
            pearlStaked -= user.amount;
        }
        user.amount = 0;
        user.rewardDebt = 0;
    }

    // Safe pearl transfer function, just in case if rounding error causes pool to not have enough PEARLs.
    function safePearlTransfer(address _to, uint256 _amount) internal {
        oyster.safePearlTransfer(_to, _amount);
    }

    // withdraw if migrating to new staking contract
    function withdrawRewardsOnly(uint256 _amount) external onlyOwner {
        pearl.transfer(msg.sender, _amount);
    }
}

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":"sniper","type":"address"}],"name":"BoughtEarly","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"EnabledTrading","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":false,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"bool","name":"excluded","type":"bool"}],"name":"MaxTransactionExclusion","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":true,"internalType":"address","name":"notsnipersupposedly","type":"address"}],"name":"RemovedSniper","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":"uint256","name":"tokensSwapped","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethReceived","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokensIntoLiquidity","type":"uint256"}],"name":"SwapAndLiquify","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":"uint256","name":"amount","type":"uint256"}],"name":"TransferForeignToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newWallet","type":"address"}],"name":"UpdatedCharityAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"UpdatedMaxBuyAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"UpdatedMaxSellAmount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newWallet","type":"address"}],"name":"UpdatedOperationsAddress","type":"event"},{"inputs":[],"name":"DELEGATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_isExcludedMaxTransactionAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"airdropWallets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"airdropToWallets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":"buyCharityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyLiquidityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyOperationsFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyTotalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"charityAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint32","name":"","type":"uint32"}],"name":"checkpoints","outputs":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint256","name":"votes","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegator","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexRouter","outputs":[{"internalType":"contract IDexRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableTransferDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"earlyBuyPenaltyEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"address","name":"updAds","type":"address"},{"internalType":"bool","name":"isEx","type":"bool"}],"name":"excludeFromMaxTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCurrentVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPriorVotes","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":[],"name":"limitsInEffect","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lpPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBuyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSellAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operationsAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellCharityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellLiquidityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellOperationsFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellTotalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_charityAddress","type":"address"}],"name":"setCharityAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operationsAddress","type":"address"}],"name":"setOperationsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapEnabled","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":"tokensForCharity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensForLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokensForOperations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingActiveBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferDelayEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"transferForeignToken","outputs":[{"internalType":"bool","name":"_sent","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":[{"internalType":"uint256","name":"_operationsFee","type":"uint256"},{"internalType":"uint256","name":"_liquidityFee","type":"uint256"},{"internalType":"uint256","name":"_charityFee","type":"uint256"}],"name":"updateBuyFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNum","type":"uint256"}],"name":"updateMaxBuyAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newNum","type":"uint256"}],"name":"updateMaxSellAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_operationsFee","type":"uint256"},{"internalType":"uint256","name":"_liquidityFee","type":"uint256"},{"internalType":"uint256","name":"_charityFee","type":"uint256"}],"name":"updateSellFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"updateSwapTokensAtAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStuckETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c0604052600d8054600162ffffff199091161790556000600e556011805461ffff19166101011790553480156200003657600080fd5b506040518060400160405280600b81526020016a2832b0b936102a37b5b2b760a91b81525060405180604001604052806005815260200164141150549360da1b81525060006200008b620003eb60201b60201c565b600080546001600160a01b0319166001600160a01b03831690811782556040519293509160008051602062004b7e833981519152908290a3508151620000d9906004906020850190620007e7565b508051620000ef906005906020840190620007e7565b50506006805460ff191660121790555033737a250d5630b4cf539739df2c5dacb4c659f2488d62000122816001620003ef565b6001600160a01b03811660808190526040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa1580156200016d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019391906200088d565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020791906200088d565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af115801562000255573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027b91906200088d565b6001600160a01b031660a08190526200029690600162000452565b6c7e37be2022c0914b26800000006103e8620002b4826001620008ce565b620002c09190620008f0565b6008556103e8620002d3826001620008ce565b620002df9190620008f0565b600955612710620002f2826001620008ce565b620002fe9190620008f0565b600c55600560138190556014819055600060158190559062000321908062000913565b6200032d919062000913565b601255600a60178190556018819055600060198190559062000350908062000913565b6200035c919062000913565b6016556200036c836001620003ef565b62000379306001620003ef565b6200038861dead6001620003ef565b62000395836001620004be565b600a8054735bff5d0a17d48dcb3eeca101ee758cbe5db68a446001600160a01b03199182168117909255600b80549091169091179055620003d783826200056c565b620003e28362000673565b5050506200096b565b3390565b6001600160a01b0382166000818152601e6020908152604091829020805460ff19168515159081179091558251938452908301527f6b4f1be9103e6cbcd38ca4a922334f2c3109b260130a6676a987f94088fd6746910160405180910390a15050565b6001600160a01b0382166000908152601f60205260409020805460ff1916821515179055620004828282620003ef565b604051811515906001600160a01b038416907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab90600090a35050565b6000546001600160a01b031633146200050d5760405162461bcd60e51b8152602060048201819052602482015260008051602062004b5e83398151915260448201526064015b60405180910390fd5b6001600160a01b0382166000818152601d6020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b6001600160a01b038216620005c45760405162461bcd60e51b815260206004820152601f60248201527f42455032303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162000504565b620005e081600354620006cc60201b620023201790919060201c565b6003556001600160a01b0382166000908152600160209081526040909120546200061591839062002320620006cc821b17901c565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90620006679085815260200190565b60405180910390a35050565b6000546001600160a01b03163314620006be5760405162461bcd60e51b8152602060048201819052602482015260008051602062004b5e833981519152604482015260640162000504565b620006c98162000736565b50565b600080620006db838562000913565b9050838110156200072f5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015260640162000504565b9392505050565b6001600160a01b0381166200079d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000504565b600080546040516001600160a01b038085169392169160008051602062004b7e83398151915291a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b828054620007f5906200092e565b90600052602060002090601f01602090048101928262000819576000855562000864565b82601f106200083457805160ff191683800117855562000864565b8280016001018555821562000864579182015b828111156200086457825182559160200191906001019062000847565b506200087292915062000876565b5090565b5b8082111562000872576000815560010162000877565b600060208284031215620008a057600080fd5b81516001600160a01b03811681146200072f57600080fd5b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615620008eb57620008eb620008b8565b500290565b6000826200090e57634e487b7160e01b600052601260045260246000fd5b500490565b60008219821115620009295762000929620008b8565b500190565b600181811c908216806200094357607f821691505b602082108114156200096557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05161418e620009d06000396000818161065b0152818161136a01528181611a3001526128ce01526000818161043c01528181612891015281816135e9015281816136a2015281816136de0152818161375001526137ad015261418e6000f3fe6080604052600436106103f35760003560e01c80638366e79a11610208578063c3cda52011610118578063e884f260116100ab578063f11a24d31161007a578063f11a24d314610c6d578063f2fde38b14610c83578063f5648a4f14610ca3578063f637434214610cb8578063fb002c9714610cce57600080fd5b8063e884f26014610bc0578063ea4cfe1214610bd5578063ee40166e14610bf5578063f1127ed814610c0b57600080fd5b8063dc3f0d0f116100e7578063dc3f0d0f14610b10578063dd62ed3e14610b30578063e2f4560514610b76578063e7a324dc14610b8c57600080fd5b8063c3cda52014610aa0578063c876d0b914610ac0578063d257b34f14610ada578063d85ba06314610afa57600080fd5b8063a1dc92bc1161019b578063b4b5ea571161016a578063b4b5ea57146109f1578063b62496f514610a11578063bbc0c74214610a41578063c024666814610a60578063c17b5b8c14610a8057600080fd5b8063a1dc92bc1461097b578063a457c2d714610991578063a9059cbb146109b1578063afcf2fc4146109d157600080fd5b80638da5cb5b116101d75780638da5cb5b146108f357806395d89b41146109265780639a7a23d61461093b578063a0712d681461095b57600080fd5b80638366e79a146108bd57806388e765ff146108dd578063893d20e8146108f35780638a8c523c1461091157600080fd5b8063499b8394116103035780636ddd171311610296578063751039fc11610265578063751039fc1461081b5780637571336a14610830578063782d6fe1146108505780637ecebe00146108705780638095d5641461089d57600080fd5b80636ddd1713146107685780636fcfff451461078857806370a08231146107d0578063715018a61461080657600080fd5b80635a139dd4116102d25780635a139dd4146107065780635c19a95c1461071c57806366d602ae1461073c5780636a486a8e1461075257600080fd5b8063499b83941461067d5780634a62bb651461069d5780634f77f6c0146106b7578063587cde1e146106cd57600080fd5b80631fc851bd116103865780632be32b61116103555780632be32b61146105d1578063313ce567146105f1578063395093511461061357806344249f0414610633578063452ed4f11461064957600080fd5b80631fc851bd1461054757806320606b701461055d5780632307b4411461059157806323b872dd146105b157600080fd5b80630d7f1441116103c25780630d7f1441146104c857806310d5de53146104ec57806318160ddd1461051c5780631a8145bb1461053157600080fd5b806306fdde03146103ff5780630758d9241461042a578063095ea7b3146104765780630c9be46d146104a657600080fd5b366103fa57005b600080fd5b34801561040b57600080fd5b50610414610ce4565b60405161042191906139fa565b60405180910390f35b34801561043657600080fd5b5061045e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610421565b34801561048257600080fd5b50610496610491366004613a64565b610d76565b6040519015158152602001610421565b3480156104b257600080fd5b506104c66104c1366004613a90565b610d8d565b005b3480156104d457600080fd5b506104de60195481565b604051908152602001610421565b3480156104f857600080fd5b50610496610507366004613a90565b601e6020526000908152604090205460ff1681565b34801561052857600080fd5b506003546104de565b34801561053d57600080fd5b506104de601b5481565b34801561055357600080fd5b506104de600f5481565b34801561056957600080fd5b506104de7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b34801561059d57600080fd5b506104966105ac366004613b83565b610e30565b3480156105bd57600080fd5b506104966105cc366004613c45565b61100c565b3480156105dd57600080fd5b506104c66105ec366004613c86565b61106b565b3480156105fd57600080fd5b5060065460405160ff9091168152602001610421565b34801561061f57600080fd5b5061049661062e366004613a64565b611178565b34801561063f57600080fd5b506104de601c5481565b34801561065557600080fd5b5061045e7f000000000000000000000000000000000000000000000000000000000000000081565b34801561068957600080fd5b506104c6610698366004613a90565b6111ae565b3480156106a957600080fd5b50600d546104969060ff1681565b3480156106c357600080fd5b506104de60175481565b3480156106d957600080fd5b5061045e6106e8366004613a90565b6001600160a01b039081166000908152600760205260409020541690565b34801561071257600080fd5b506104de60135481565b34801561072857600080fd5b506104c6610737366004613a90565b611277565b34801561074857600080fd5b506104de60095481565b34801561075e57600080fd5b506104de60165481565b34801561077457600080fd5b50600d546104969062010000900460ff1681565b34801561079457600080fd5b506107bb6107a3366004613a90565b60216020526000908152604090205463ffffffff1681565b60405163ffffffff9091168152602001610421565b3480156107dc57600080fd5b506104de6107eb366004613a90565b6001600160a01b031660009081526001602052604090205490565b34801561081257600080fd5b506104c6611284565b34801561082757600080fd5b506104c66112f8565b34801561083c57600080fd5b506104c661084b366004613cad565b611339565b34801561085c57600080fd5b506104de61086b366004613a64565b611425565b34801561087c57600080fd5b506104de61088b366004613a90565b60226020526000908152604090205481565b3480156108a957600080fd5b506104c66108b8366004613ce6565b611683565b3480156108c957600080fd5b506104966108d8366004613d12565b61172b565b3480156108e957600080fd5b506104de60085481565b3480156108ff57600080fd5b506000546001600160a01b031661045e565b34801561091d57600080fd5b506104c6611933565b34801561093257600080fd5b506104146119f5565b34801561094757600080fd5b506104c6610956366004613cad565b611a04565b34801561096757600080fd5b50610496610976366004613c86565b611ae4565b34801561098757600080fd5b506104de60155481565b34801561099d57600080fd5b506104966109ac366004613a64565b611b21565b3480156109bd57600080fd5b506104966109cc366004613a64565b611b70565b3480156109dd57600080fd5b50600b5461045e906001600160a01b031681565b3480156109fd57600080fd5b506104de610a0c366004613a90565b611b7d565b348015610a1d57600080fd5b50610496610a2c366004613a90565b601f6020526000908152604090205460ff1681565b348015610a4d57600080fd5b50600d5461049690610100900460ff1681565b348015610a6c57600080fd5b506104c6610a7b366004613cad565b611bf1565b348015610a8c57600080fd5b506104c6610a9b366004613ce6565b611c7a565b348015610aac57600080fd5b506104c6610abb366004613d40565b611d1d565b348015610acc57600080fd5b506011546104969060ff1681565b348015610ae657600080fd5b506104c6610af5366004613c86565b611fee565b348015610b0657600080fd5b506104de60125481565b348015610b1c57600080fd5b506104c6610b2b366004613c86565b612139565b348015610b3c57600080fd5b506104de610b4b366004613d12565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b348015610b8257600080fd5b506104de600c5481565b348015610b9857600080fd5b506104de7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b348015610bcc57600080fd5b506104c6612240565b348015610be157600080fd5b50600a5461045e906001600160a01b031681565b348015610c0157600080fd5b506104de600e5481565b348015610c1757600080fd5b50610c51610c26366004613da2565b6020808052600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6040805163ffffffff9093168352602083019190915201610421565b348015610c7957600080fd5b506104de60145481565b348015610c8f57600080fd5b506104c6610c9e366004613a90565b612276565b348015610caf57600080fd5b506104c66122a9565b348015610cc457600080fd5b506104de60185481565b348015610cda57600080fd5b506104de601a5481565b606060048054610cf390613dd9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1f90613dd9565b8015610d6c5780601f10610d4157610100808354040283529160200191610d6c565b820191906000526020600020905b815481529060010190602001808311610d4f57829003601f168201915b5050505050905090565b6000610d8333848461237f565b5060015b92915050565b6000546001600160a01b03163314610dc05760405162461bcd60e51b8152600401610db790613e14565b60405180910390fd5b6001600160a01b038116610de65760405162461bcd60e51b8152600401610db790613e49565b600b80546001600160a01b0319166001600160a01b0383169081179091556040517fff6a822e9e2c4fe74d4f27fcde00b94c5abb41dd24b73e718952279715fa663290600090a250565b600080546001600160a01b03163314610e5b5760405162461bcd60e51b8152600401610db790613e14565b600d54610100900460ff1615610ed95760405162461bcd60e51b815260206004820152603760248201527f54726164696e6720697320616c7265616479206163746976652c2063616e6e6f60448201527f742061697264726f70206166746572206c61756e63682e0000000000000000006064820152608401610db7565b8151835114610f2a5760405162461bcd60e51b815260206004820152601e60248201527f617272617973206d757374206265207468652073616d65206c656e67746800006044820152606401610db7565b60c8835110610f9a5760405162461bcd60e51b815260206004820152603660248201527f43616e206f6e6c792061697264726f70203230302077616c6c657473207065726044820152752074786e2064756520746f20676173206c696d69747360501b6064820152608401610db7565b60005b8351811015611002576000848281518110610fba57610fba613e8f565b602002602001015190506000848381518110610fd857610fd8613e8f565b60200260200101519050610fed3383836124a4565b50508080610ffa90613ebb565b915050610f9d565b5060019392505050565b600061101984848461262a565b6110028433611066856040518060600160405280602881526020016140b1602891396001600160a01b038a1660009081526002602090815260408083203384529091529020549190612f06565b61237f565b6000546001600160a01b031633146110955760405162461bcd60e51b8152600401610db790613e14565b670de0b6b3a76400006103e86110aa60035490565b6110b5906001613ed6565b6110bf9190613f0b565b6110c99190613f0b565b81101561112a5760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f7420736574206d61782062757920616d6f756e74206c6f776572206044820152687468616e20302e312560b81b6064820152608401610db7565b61113c81670de0b6b3a7640000613ed6565b60088190556040519081527ffcc0366804aaa8dbf88a2924100c733b70dec8445957a5d5f8ff92898de41009906020015b60405180910390a150565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610d839185906110669086612320565b6000546001600160a01b031633146111d85760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0381166111fe5760405162461bcd60e51b8152600401610db790613e49565b600a80546001600160a01b039081166000908152601d6020526040808220805460ff1990811690915584546001600160a01b0319169386169384179094558282528082208054909416600117909355915190917f4efa56652237561d0f1fd31311aeaaa41f3b754a461545ed3cf6ced5876d298291a250565b6112813382612f40565b50565b6000546001600160a01b031633146112ae5760405162461bcd60e51b8152600401610db790613e14565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146113225760405162461bcd60e51b8152600401610db790613e14565b600d805460ff191690556011805461ffff19169055565b6000546001600160a01b031633146113635760405162461bcd60e51b8152600401610db790613e14565b806113fa577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614156113fa5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f742072656d6f766520756e697377617020706169722066726f6d2060448201526636b0bc103a3c3760c91b6064820152608401610db7565b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b60004382106114875760405162461bcd60e51b815260206004820152602860248201527f504541524c3a3a6765745072696f72566f7465733a206e6f74207965742064656044820152671d195c9b5a5b995960c21b6064820152608401610db7565b6001600160a01b03831660009081526021602052604090205463ffffffff16806114b5576000915050610d87565b6001600160a01b0384166000908152602080526040812084916114d9600185613f1f565b63ffffffff90811682526020820192909252604001600020541611611541576001600160a01b038416600090815260208052604081209061151b600184613f1f565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610d87565b6001600160a01b03841660009081526020808052604080832083805290915290205463ffffffff1683101561157a576000915050610d87565b600080611588600184613f1f565b90505b8163ffffffff168163ffffffff16111561164e57600060026115ad8484613f1f565b6115b79190613f44565b6115c19083613f1f565b6001600160a01b03881660009081526020808052604080832063ffffffff808616855290835292819020815180830190925280549093168082526001909301549181019190915291925087141561162257602001519450610d879350505050565b805163ffffffff1687111561163957819350611647565b611644600183613f1f565b92505b505061158b565b506001600160a01b03851660009081526020808052604080832063ffffffff9094168352929052206001015491505092915050565b6000546001600160a01b031633146116ad5760405162461bcd60e51b8152600401610db790613e14565b601383905560148290556015819055806116c78385613f67565b6116d19190613f67565b6012819055600a10156117265760405162461bcd60e51b815260206004820152601d60248201527f4d757374206b656570206665657320617420313025206f72206c6573730000006044820152606401610db7565b505050565b600080546001600160a01b031633146117565760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0383166117ac5760405162461bcd60e51b815260206004820152601a60248201527f5f746f6b656e20616464726573732063616e6e6f7420626520300000000000006044820152606401610db7565b6001600160a01b0383163014156118055760405162461bcd60e51b815260206004820152601c60248201527f43616e2774207769746864726177206e617469766520746f6b656e73000000006044820152606401610db7565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa15801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613f7f565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509085169063a9059cbb906044016020604051808303816000875af11580156118c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e79190613f98565b604080516001600160a01b0387168152602081018490529193507fdeda980967fcead7b61e78ac46a4da14274af29e894d4d61e8b81ec38ab3e438910160405180910390a15092915050565b6000546001600160a01b0316331461195d5760405162461bcd60e51b8152600401610db790613e14565b600d54610100900460ff16156119b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207265656e61626c652074726164696e670000000000000000006044820152606401610db7565b600d805462ffff0019166201010017905543600e556040517fa56feb2d31b9a7424db0be063fd450863979c9e2382cf5110f869bd1ad361bb790600090a1565b606060058054610cf390613dd9565b6000546001600160a01b03163314611a2e5760405162461bcd60e51b8152600401610db790613e14565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415611ad65760405162461bcd60e51b815260206004820152603960248201527f54686520706169722063616e6e6f742062652072656d6f7665642066726f6d2060448201527f6175746f6d617465644d61726b65744d616b65725061697273000000000000006064820152608401610db7565b611ae08282612fba565b5050565b600080546001600160a01b03163314611b0f5760405162461bcd60e51b8152600401610db790613e14565b611b193383613024565b506001919050565b6000610d83338461106685604051806060016040528060258152602001614134602591393360009081526002602090815260408083206001600160a01b038d1684529091529020549190612f06565b6000610d8333848461262a565b6001600160a01b03811660009081526021602052604081205463ffffffff1680611ba8576000611bea565b6001600160a01b0383166000908152602080526040812090611bcb600184613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b9392505050565b6000546001600160a01b03163314611c1b5760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0382166000818152601d6020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b6000546001600160a01b03163314611ca45760405162461bcd60e51b8152600401610db790613e14565b60178390556018829055601981905580611cbe8385613f67565b611cc89190613f67565b6016819055601410156117265760405162461bcd60e51b815260206004820152601d60248201527f4d757374206b656570206665657320617420323025206f72206c6573730000006044820152606401610db7565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866611d48610ce4565b80519060200120611d564690565b60408051602080820195909552808201939093526060830191909152306080808401919091528151808403909101815260a0830182528051908401207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60c08401526001600160a01b038b1660e084015261010083018a90526101208084018a90528251808503909101815261014084019092528151919093012061190160f01b610160830152610162820183905261018282018190529192506000906101a20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015611e82573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611ef55760405162461bcd60e51b815260206004820152602760248201527f504541524c3a3a64656c656761746542795369673a20696e76616c6964207369604482015266676e617475726560c81b6064820152608401610db7565b6001600160a01b0381166000908152602260205260408120805491611f1983613ebb565b919050558914611f775760405162461bcd60e51b815260206004820152602360248201527f504541524c3a3a64656c656761746542795369673a20696e76616c6964206e6f6044820152626e636560e81b6064820152608401610db7565b87421115611fd75760405162461bcd60e51b815260206004820152602760248201527f504541524c3a3a64656c656761746542795369673a207369676e617475726520604482015266195e1c1a5c995960ca1b6064820152608401610db7565b611fe1818b612f40565b505050505b505050505050565b6000546001600160a01b031633146120185760405162461bcd60e51b8152600401610db790613e14565b620186a061202560035490565b612030906001613ed6565b61203a9190613f0b565b8110156120a75760405162461bcd60e51b815260206004820152603560248201527f5377617020616d6f756e742063616e6e6f74206265206c6f776572207468616e60448201527410181718181892903a37ba30b61039bab838363c9760591b6064820152608401610db7565b6103e86120b360035490565b6120be906001613ed6565b6120c89190613f0b565b8111156121345760405162461bcd60e51b815260206004820152603460248201527f5377617020616d6f756e742063616e6e6f742062652068696768657220746861604482015273371018171892903a37ba30b61039bab838363c9760611b6064820152608401610db7565b600c55565b6000546001600160a01b031633146121635760405162461bcd60e51b8152600401610db790613e14565b670de0b6b3a76400006103e861217860035490565b612183906001613ed6565b61218d9190613f0b565b6121979190613f0b565b8110156121f95760405162461bcd60e51b815260206004820152602a60248201527f43616e6e6f7420736574206d61782073656c6c20616d6f756e74206c6f776572604482015269207468616e20302e312560b01b6064820152608401610db7565b61220b81670de0b6b3a7640000613ed6565b60098190556040519081527f53c4eb831d8cfeb750f1c62590d8cd30f4c6f0380d29a05caa09f0d92588560e9060200161116d565b6000546001600160a01b0316331461226a5760405162461bcd60e51b8152600401610db790613e14565b6011805460ff19169055565b6000546001600160a01b031633146122a05760405162461bcd60e51b8152600401610db790613e14565b6112818161310a565b6000546001600160a01b031633146122d35760405162461bcd60e51b8152600401610db790613e14565b604051600090339047908381818185875af1925050503d8060008114612315576040519150601f19603f3d011682016040523d82523d6000602084013e61231a565b606091505b50505050565b60008061232d8385613f67565b905083811015611bea5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610db7565b6001600160a01b0383166123e15760405162461bcd60e51b8152602060048201526024808201527f42455032303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610db7565b6001600160a01b0382166124425760405162461bcd60e51b815260206004820152602260248201527f42455032303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610db7565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383166125085760405162461bcd60e51b815260206004820152602560248201527f42455032303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610db7565b6001600160a01b03821661256a5760405162461bcd60e51b815260206004820152602360248201527f42455032303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610db7565b6125a78160405180606001604052806026815260200161410e602691396001600160a01b0386166000908152600160205260409020549190612f06565b6001600160a01b0380851660009081526001602052604080822093909355908416815220546125d69082612320565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124979085815260200190565b6001600160a01b03831661268e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610db7565b6001600160a01b0382166126f05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610db7565b8061270157611726838360006124a4565b600d5460ff1615612b0a576000546001600160a01b0384811691161480159061273857506000546001600160a01b03838116911614155b801561274c57506001600160a01b03821615155b801561276357506001600160a01b03821661dead14155b15612b0a57600d54610100900460ff166127fb576001600160a01b0383166000908152601e602052604090205460ff16806127b657506001600160a01b0382166000908152601e602052604090205460ff165b6127fb5760405162461bcd60e51b81526020600482015260166024820152752a3930b234b7339034b9903737ba1030b1ba34bb329760511b6044820152606401610db7565b601154610100900460ff16801561282a57506001600160a01b0383166000908152601f602052604090205460ff165b1561288457645d21dba0003a11156128845760405162461bcd60e51b815260206004820152601860248201527f4761732070726963652065786365656473206c696d69742e00000000000000006044820152606401610db7565b60115460ff16156129b1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415801561290357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b156129b15732600090815260106020526040902054431161299e5760405162461bcd60e51b815260206004820152604960248201527f5f7472616e736665723a3a205472616e736665722044656c617920656e61626c60448201527f65642e20204f6e6c79206f6e652070757263686173652070657220626c6f636b6064820152681030b63637bbb2b21760b91b608482015260a401610db7565b3260009081526010602052604090204390555b6001600160a01b0383166000908152601f602052604090205460ff1680156129f257506001600160a01b0382166000908152601e602052604090205460ff16155b15612a5f57600854811115612a5a5760405162461bcd60e51b815260206004820152602860248201527f427579207472616e7366657220616d6f756e742065786365656473207468652060448201526736b0bc10313abc9760c11b6064820152608401610db7565b612b0a565b6001600160a01b0382166000908152601f602052604090205460ff168015612aa057506001600160a01b0383166000908152601e602052604090205460ff16155b15612b0a57600954811115612b0a5760405162461bcd60e51b815260206004820152602a60248201527f53656c6c207472616e7366657220616d6f756e742065786365656473207468656044820152691036b0bc1039b2b6361760b11b6064820152608401610db7565b30600090815260016020526040902054600c5481108015908190612b365750600d5462010000900460ff165b8015612b4c5750600b54600160a01b900460ff16155b8015612b7157506001600160a01b0385166000908152601f602052604090205460ff16155b8015612b9657506001600160a01b0385166000908152601d602052604090205460ff16155b8015612bbb57506001600160a01b0384166000908152601d602052604090205460ff16155b15612be957600b805460ff60a01b1916600160a01b179055612bdb6131ca565b600b805460ff60a01b191690555b6001600160a01b0385166000908152601d602052604090205460019060ff1680612c2b57506001600160a01b0385166000908152601d602052604090205460ff165b15612c34575060005b60008115612ef257600e5443148015612c6557506001600160a01b0387166000908152601f602052604090205460ff165b15612d15576064612c7786605f613ed6565b612c819190613f0b565b905060165460185482612c949190613ed6565b612c9e9190613f0b565b601b6000828254612caf9190613f67565b9091555050601654601754612cc49083613ed6565b612cce9190613f0b565b601a6000828254612cdf9190613f67565b9091555050601654601954612cf49083613ed6565b612cfe9190613f0b565b601c6000828254612d0f9190613f67565b90915550505b6001600160a01b0386166000908152601f602052604090205460ff168015612d3f57506000601654115b15612df757606460165486612d549190613ed6565b612d5e9190613f0b565b905060165460185482612d719190613ed6565b612d7b9190613f0b565b601b6000828254612d8c9190613f67565b9091555050601654601754612da19083613ed6565b612dab9190613f0b565b601a6000828254612dbc9190613f67565b9091555050601654601954612dd19083613ed6565b612ddb9190613f0b565b601c6000828254612dec9190613f67565b90915550612ed49050565b6001600160a01b0387166000908152601f602052604090205460ff168015612e2157506000601254115b15612ed457606460125486612e369190613ed6565b612e409190613f0b565b905060125460145482612e539190613ed6565b612e5d9190613f0b565b601b6000828254612e6e9190613f67565b9091555050601254601354612e839083613ed6565b612e8d9190613f0b565b601a6000828254612e9e9190613f67565b9091555050601254601554612eb39083613ed6565b612ebd9190613f0b565b601c6000828254612ece9190613f67565b90915550505b8015612ee557612ee58730836124a4565b612eef8186613fb5565b94505b612efd8787876124a4565b50505050505050565b60008184841115612f2a5760405162461bcd60e51b8152600401610db791906139fa565b506000612f378486613fb5565b95945050505050565b6001600160a01b03828116600081815260076020818152604080842080546001845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461231a8284836133d2565b6001600160a01b0382166000908152601f60205260409020805460ff1916821515179055612fe8828261352f565b604051811515906001600160a01b038416907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab90600090a35050565b6001600160a01b03821661307a5760405162461bcd60e51b815260206004820152601f60248201527f42455032303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610db7565b6003546130879082612320565b6003556001600160a01b0382166000908152600160205260409020546130ad9082612320565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906130fe9085815260200190565b60405180910390a35050565b6001600160a01b03811661316f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610db7565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3060009081526001602052604081205490506000601c54601a54601b546131f19190613f67565b6131fb9190613f67565b9050811580613208575080155b15613211575050565b600c5461321f90600a613ed6565b82111561323757600c5461323490600a613ed6565b91505b600080600283601b548661324b9190613ed6565b6132559190613f0b565b61325f9190613f0b565b905061327361326e8286613fb5565b613592565b601b544790819060009061328990600290613f0b565b6132939087613fb5565b601a546132a09085613ed6565b6132aa9190613f0b565b905060006002601b546132bd9190613f0b565b6132c79088613fb5565b601c546132d49086613ed6565b6132de9190613f0b565b90506132ea8183613f67565b6132f49084613fb5565b6000601b819055601a559250841580159061330f5750600083115b1561331e5761331e858461374a565b600b546040516001600160a01b03909116908290600081818185875af1925050503d806000811461336b576040519150601f19603f3d011682016040523d82523d6000602084013e613370565b606091505b5050600a546040519197506001600160a01b0316904790600081818185875af1925050503d80600081146133c0576040519150601f19603f3d011682016040523d82523d6000602084013e6133c5565b606091505b5050505050505050505050565b816001600160a01b0316836001600160a01b0316141580156133f45750600081115b15611726576001600160a01b03831615613496576001600160a01b03831660009081526021602052604081205463ffffffff169081613434576000613476565b6001600160a01b0385166000908152602080526040812090613457600185613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006134848483613fb5565b90506134928684848461382b565b5050505b6001600160a01b03821615611726576001600160a01b03821660009081526021602052604081205463ffffffff1690816134d1576000613513565b6001600160a01b03841660009081526020805260408120906134f4600185613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006135218483613f67565b9050611fe68584848461382b565b6001600160a01b0382166000818152601e6020908152604091829020805460ff19168515159081179091558251938452908301527f6b4f1be9103e6cbcd38ca4a922334f2c3109b260130a6676a987f94088fd6746910160405180910390a15050565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106135c7576135c7613e8f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015613645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136699190613fcc565b8160018151811061367c5761367c613e8f565b60200260200101906001600160a01b031690816001600160a01b0316815250506136c7307f00000000000000000000000000000000000000000000000000000000000000008461237f565b60405163791ac94760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063791ac9479061371c908590600090869030904290600401613fe9565b600060405180830381600087803b15801561373657600080fd5b505af1158015611fe6573d6000803e3d6000fd5b613775307f00000000000000000000000000000000000000000000000000000000000000008461237f565b60405163f305d71960e01b815230600482015260248101839052600060448201819052606482015261dead60848201524260a48201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f305d71990839060c40160606040518083038185885af11580156137ff573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613824919061405a565b5050505050565b600061384f436040518060600160405280603581526020016140d9603591396139ca565b905060008463ffffffff161180156138a857506001600160a01b0385166000908152602080526040812063ffffffff83169161388c600188613f1f565b63ffffffff908116825260208201929092526040016000205416145b156138f0576001600160a01b0385166000908152602080526040812083916138d1600188613f1f565b63ffffffff16815260208101919091526040016000206001015561397f565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a1660009081528280528581208a851682529092529390209151825463ffffffff19169116178155905160019182015561394e908590614088565b6001600160a01b0386166000908152602160205260409020805463ffffffff191663ffffffff929092169190911790555b60408051848152602081018490526001600160a01b038716917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a25050505050565b60008164010000000084106139f25760405162461bcd60e51b8152600401610db791906139fa565b509192915050565b600060208083528351808285015260005b81811015613a2757858101830151858201604001528201613a0b565b81811115613a39576000604083870101525b50601f01601f1916929092016040019392505050565b6001600160a01b038116811461128157600080fd5b60008060408385031215613a7757600080fd5b8235613a8281613a4f565b946020939093013593505050565b600060208284031215613aa257600080fd5b8135611bea81613a4f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613aec57613aec613aad565b604052919050565b600067ffffffffffffffff821115613b0e57613b0e613aad565b5060051b60200190565b600082601f830112613b2957600080fd5b81356020613b3e613b3983613af4565b613ac3565b82815260059290921b84018101918181019086841115613b5d57600080fd5b8286015b84811015613b785780358352918301918301613b61565b509695505050505050565b60008060408385031215613b9657600080fd5b823567ffffffffffffffff80821115613bae57600080fd5b818501915085601f830112613bc257600080fd5b81356020613bd2613b3983613af4565b82815260059290921b84018101918181019089841115613bf157600080fd5b948201945b83861015613c18578535613c0981613a4f565b82529482019490820190613bf6565b96505086013592505080821115613c2e57600080fd5b50613c3b85828601613b18565b9150509250929050565b600080600060608486031215613c5a57600080fd5b8335613c6581613a4f565b92506020840135613c7581613a4f565b929592945050506040919091013590565b600060208284031215613c9857600080fd5b5035919050565b801515811461128157600080fd5b60008060408385031215613cc057600080fd5b8235613ccb81613a4f565b91506020830135613cdb81613c9f565b809150509250929050565b600080600060608486031215613cfb57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613d2557600080fd5b8235613d3081613a4f565b91506020830135613cdb81613a4f565b60008060008060008060c08789031215613d5957600080fd5b8635613d6481613a4f565b95506020870135945060408701359350606087013560ff81168114613d8857600080fd5b9598949750929560808101359460a0909101359350915050565b60008060408385031215613db557600080fd5b8235613dc081613a4f565b9150602083013563ffffffff81168114613cdb57600080fd5b600181811c90821680613ded57607f821691505b60208210811415613e0e57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526026908201527f5f6f7065726174696f6e734164647265737320616464726573732063616e6e6f60408201526507420626520360d41b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415613ecf57613ecf613ea5565b5060010190565b6000816000190483118215151615613ef057613ef0613ea5565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613f1a57613f1a613ef5565b500490565b600063ffffffff83811690831681811015613f3c57613f3c613ea5565b039392505050565b600063ffffffff80841680613f5b57613f5b613ef5565b92169190910492915050565b60008219821115613f7a57613f7a613ea5565b500190565b600060208284031215613f9157600080fd5b5051919050565b600060208284031215613faa57600080fd5b8151611bea81613c9f565b600082821015613fc757613fc7613ea5565b500390565b600060208284031215613fde57600080fd5b8151611bea81613a4f565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156140395784516001600160a01b031683529383019391830191600101614014565b50506001600160a01b03969096166060850152505050608001529392505050565b60008060006060848603121561406f57600080fd5b8351925060208401519150604084015190509250925092565b600063ffffffff8083168185168083038211156140a7576140a7613ea5565b0194935050505056fe42455032303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365504541524c3a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d6265722065786365656473203332206269747342455032303a207472616e7366657220616d6f756e7420657863656564732062616c616e636542455032303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220978f9ba368807d6ca36bd58b6f12b9cd953fe8e98061d85d3ec5d37eef4217af64736f6c634300080b00334f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65728be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0

Deployed Bytecode

0x6080604052600436106103f35760003560e01c80638366e79a11610208578063c3cda52011610118578063e884f260116100ab578063f11a24d31161007a578063f11a24d314610c6d578063f2fde38b14610c83578063f5648a4f14610ca3578063f637434214610cb8578063fb002c9714610cce57600080fd5b8063e884f26014610bc0578063ea4cfe1214610bd5578063ee40166e14610bf5578063f1127ed814610c0b57600080fd5b8063dc3f0d0f116100e7578063dc3f0d0f14610b10578063dd62ed3e14610b30578063e2f4560514610b76578063e7a324dc14610b8c57600080fd5b8063c3cda52014610aa0578063c876d0b914610ac0578063d257b34f14610ada578063d85ba06314610afa57600080fd5b8063a1dc92bc1161019b578063b4b5ea571161016a578063b4b5ea57146109f1578063b62496f514610a11578063bbc0c74214610a41578063c024666814610a60578063c17b5b8c14610a8057600080fd5b8063a1dc92bc1461097b578063a457c2d714610991578063a9059cbb146109b1578063afcf2fc4146109d157600080fd5b80638da5cb5b116101d75780638da5cb5b146108f357806395d89b41146109265780639a7a23d61461093b578063a0712d681461095b57600080fd5b80638366e79a146108bd57806388e765ff146108dd578063893d20e8146108f35780638a8c523c1461091157600080fd5b8063499b8394116103035780636ddd171311610296578063751039fc11610265578063751039fc1461081b5780637571336a14610830578063782d6fe1146108505780637ecebe00146108705780638095d5641461089d57600080fd5b80636ddd1713146107685780636fcfff451461078857806370a08231146107d0578063715018a61461080657600080fd5b80635a139dd4116102d25780635a139dd4146107065780635c19a95c1461071c57806366d602ae1461073c5780636a486a8e1461075257600080fd5b8063499b83941461067d5780634a62bb651461069d5780634f77f6c0146106b7578063587cde1e146106cd57600080fd5b80631fc851bd116103865780632be32b61116103555780632be32b61146105d1578063313ce567146105f1578063395093511461061357806344249f0414610633578063452ed4f11461064957600080fd5b80631fc851bd1461054757806320606b701461055d5780632307b4411461059157806323b872dd146105b157600080fd5b80630d7f1441116103c25780630d7f1441146104c857806310d5de53146104ec57806318160ddd1461051c5780631a8145bb1461053157600080fd5b806306fdde03146103ff5780630758d9241461042a578063095ea7b3146104765780630c9be46d146104a657600080fd5b366103fa57005b600080fd5b34801561040b57600080fd5b50610414610ce4565b60405161042191906139fa565b60405180910390f35b34801561043657600080fd5b5061045e7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b039091168152602001610421565b34801561048257600080fd5b50610496610491366004613a64565b610d76565b6040519015158152602001610421565b3480156104b257600080fd5b506104c66104c1366004613a90565b610d8d565b005b3480156104d457600080fd5b506104de60195481565b604051908152602001610421565b3480156104f857600080fd5b50610496610507366004613a90565b601e6020526000908152604090205460ff1681565b34801561052857600080fd5b506003546104de565b34801561053d57600080fd5b506104de601b5481565b34801561055357600080fd5b506104de600f5481565b34801561056957600080fd5b506104de7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b34801561059d57600080fd5b506104966105ac366004613b83565b610e30565b3480156105bd57600080fd5b506104966105cc366004613c45565b61100c565b3480156105dd57600080fd5b506104c66105ec366004613c86565b61106b565b3480156105fd57600080fd5b5060065460405160ff9091168152602001610421565b34801561061f57600080fd5b5061049661062e366004613a64565b611178565b34801561063f57600080fd5b506104de601c5481565b34801561065557600080fd5b5061045e7f0000000000000000000000003a0cb47dbea6c4baed196dc07381c2e6749729cb81565b34801561068957600080fd5b506104c6610698366004613a90565b6111ae565b3480156106a957600080fd5b50600d546104969060ff1681565b3480156106c357600080fd5b506104de60175481565b3480156106d957600080fd5b5061045e6106e8366004613a90565b6001600160a01b039081166000908152600760205260409020541690565b34801561071257600080fd5b506104de60135481565b34801561072857600080fd5b506104c6610737366004613a90565b611277565b34801561074857600080fd5b506104de60095481565b34801561075e57600080fd5b506104de60165481565b34801561077457600080fd5b50600d546104969062010000900460ff1681565b34801561079457600080fd5b506107bb6107a3366004613a90565b60216020526000908152604090205463ffffffff1681565b60405163ffffffff9091168152602001610421565b3480156107dc57600080fd5b506104de6107eb366004613a90565b6001600160a01b031660009081526001602052604090205490565b34801561081257600080fd5b506104c6611284565b34801561082757600080fd5b506104c66112f8565b34801561083c57600080fd5b506104c661084b366004613cad565b611339565b34801561085c57600080fd5b506104de61086b366004613a64565b611425565b34801561087c57600080fd5b506104de61088b366004613a90565b60226020526000908152604090205481565b3480156108a957600080fd5b506104c66108b8366004613ce6565b611683565b3480156108c957600080fd5b506104966108d8366004613d12565b61172b565b3480156108e957600080fd5b506104de60085481565b3480156108ff57600080fd5b506000546001600160a01b031661045e565b34801561091d57600080fd5b506104c6611933565b34801561093257600080fd5b506104146119f5565b34801561094757600080fd5b506104c6610956366004613cad565b611a04565b34801561096757600080fd5b50610496610976366004613c86565b611ae4565b34801561098757600080fd5b506104de60155481565b34801561099d57600080fd5b506104966109ac366004613a64565b611b21565b3480156109bd57600080fd5b506104966109cc366004613a64565b611b70565b3480156109dd57600080fd5b50600b5461045e906001600160a01b031681565b3480156109fd57600080fd5b506104de610a0c366004613a90565b611b7d565b348015610a1d57600080fd5b50610496610a2c366004613a90565b601f6020526000908152604090205460ff1681565b348015610a4d57600080fd5b50600d5461049690610100900460ff1681565b348015610a6c57600080fd5b506104c6610a7b366004613cad565b611bf1565b348015610a8c57600080fd5b506104c6610a9b366004613ce6565b611c7a565b348015610aac57600080fd5b506104c6610abb366004613d40565b611d1d565b348015610acc57600080fd5b506011546104969060ff1681565b348015610ae657600080fd5b506104c6610af5366004613c86565b611fee565b348015610b0657600080fd5b506104de60125481565b348015610b1c57600080fd5b506104c6610b2b366004613c86565b612139565b348015610b3c57600080fd5b506104de610b4b366004613d12565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b348015610b8257600080fd5b506104de600c5481565b348015610b9857600080fd5b506104de7fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf81565b348015610bcc57600080fd5b506104c6612240565b348015610be157600080fd5b50600a5461045e906001600160a01b031681565b348015610c0157600080fd5b506104de600e5481565b348015610c1757600080fd5b50610c51610c26366004613da2565b6020808052600092835260408084209091529082529020805460019091015463ffffffff9091169082565b6040805163ffffffff9093168352602083019190915201610421565b348015610c7957600080fd5b506104de60145481565b348015610c8f57600080fd5b506104c6610c9e366004613a90565b612276565b348015610caf57600080fd5b506104c66122a9565b348015610cc457600080fd5b506104de60185481565b348015610cda57600080fd5b506104de601a5481565b606060048054610cf390613dd9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d1f90613dd9565b8015610d6c5780601f10610d4157610100808354040283529160200191610d6c565b820191906000526020600020905b815481529060010190602001808311610d4f57829003601f168201915b5050505050905090565b6000610d8333848461237f565b5060015b92915050565b6000546001600160a01b03163314610dc05760405162461bcd60e51b8152600401610db790613e14565b60405180910390fd5b6001600160a01b038116610de65760405162461bcd60e51b8152600401610db790613e49565b600b80546001600160a01b0319166001600160a01b0383169081179091556040517fff6a822e9e2c4fe74d4f27fcde00b94c5abb41dd24b73e718952279715fa663290600090a250565b600080546001600160a01b03163314610e5b5760405162461bcd60e51b8152600401610db790613e14565b600d54610100900460ff1615610ed95760405162461bcd60e51b815260206004820152603760248201527f54726164696e6720697320616c7265616479206163746976652c2063616e6e6f60448201527f742061697264726f70206166746572206c61756e63682e0000000000000000006064820152608401610db7565b8151835114610f2a5760405162461bcd60e51b815260206004820152601e60248201527f617272617973206d757374206265207468652073616d65206c656e67746800006044820152606401610db7565b60c8835110610f9a5760405162461bcd60e51b815260206004820152603660248201527f43616e206f6e6c792061697264726f70203230302077616c6c657473207065726044820152752074786e2064756520746f20676173206c696d69747360501b6064820152608401610db7565b60005b8351811015611002576000848281518110610fba57610fba613e8f565b602002602001015190506000848381518110610fd857610fd8613e8f565b60200260200101519050610fed3383836124a4565b50508080610ffa90613ebb565b915050610f9d565b5060019392505050565b600061101984848461262a565b6110028433611066856040518060600160405280602881526020016140b1602891396001600160a01b038a1660009081526002602090815260408083203384529091529020549190612f06565b61237f565b6000546001600160a01b031633146110955760405162461bcd60e51b8152600401610db790613e14565b670de0b6b3a76400006103e86110aa60035490565b6110b5906001613ed6565b6110bf9190613f0b565b6110c99190613f0b565b81101561112a5760405162461bcd60e51b815260206004820152602960248201527f43616e6e6f7420736574206d61782062757920616d6f756e74206c6f776572206044820152687468616e20302e312560b81b6064820152608401610db7565b61113c81670de0b6b3a7640000613ed6565b60088190556040519081527ffcc0366804aaa8dbf88a2924100c733b70dec8445957a5d5f8ff92898de41009906020015b60405180910390a150565b3360008181526002602090815260408083206001600160a01b03871684529091528120549091610d839185906110669086612320565b6000546001600160a01b031633146111d85760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0381166111fe5760405162461bcd60e51b8152600401610db790613e49565b600a80546001600160a01b039081166000908152601d6020526040808220805460ff1990811690915584546001600160a01b0319169386169384179094558282528082208054909416600117909355915190917f4efa56652237561d0f1fd31311aeaaa41f3b754a461545ed3cf6ced5876d298291a250565b6112813382612f40565b50565b6000546001600160a01b031633146112ae5760405162461bcd60e51b8152600401610db790613e14565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031633146113225760405162461bcd60e51b8152600401610db790613e14565b600d805460ff191690556011805461ffff19169055565b6000546001600160a01b031633146113635760405162461bcd60e51b8152600401610db790613e14565b806113fa577f0000000000000000000000003a0cb47dbea6c4baed196dc07381c2e6749729cb6001600160a01b0316826001600160a01b031614156113fa5760405162461bcd60e51b815260206004820152602760248201527f43616e6e6f742072656d6f766520756e697377617020706169722066726f6d2060448201526636b0bc103a3c3760c91b6064820152608401610db7565b6001600160a01b03919091166000908152601e60205260409020805460ff1916911515919091179055565b60004382106114875760405162461bcd60e51b815260206004820152602860248201527f504541524c3a3a6765745072696f72566f7465733a206e6f74207965742064656044820152671d195c9b5a5b995960c21b6064820152608401610db7565b6001600160a01b03831660009081526021602052604090205463ffffffff16806114b5576000915050610d87565b6001600160a01b0384166000908152602080526040812084916114d9600185613f1f565b63ffffffff90811682526020820192909252604001600020541611611541576001600160a01b038416600090815260208052604081209061151b600184613f1f565b63ffffffff1663ffffffff16815260200190815260200160002060010154915050610d87565b6001600160a01b03841660009081526020808052604080832083805290915290205463ffffffff1683101561157a576000915050610d87565b600080611588600184613f1f565b90505b8163ffffffff168163ffffffff16111561164e57600060026115ad8484613f1f565b6115b79190613f44565b6115c19083613f1f565b6001600160a01b03881660009081526020808052604080832063ffffffff808616855290835292819020815180830190925280549093168082526001909301549181019190915291925087141561162257602001519450610d879350505050565b805163ffffffff1687111561163957819350611647565b611644600183613f1f565b92505b505061158b565b506001600160a01b03851660009081526020808052604080832063ffffffff9094168352929052206001015491505092915050565b6000546001600160a01b031633146116ad5760405162461bcd60e51b8152600401610db790613e14565b601383905560148290556015819055806116c78385613f67565b6116d19190613f67565b6012819055600a10156117265760405162461bcd60e51b815260206004820152601d60248201527f4d757374206b656570206665657320617420313025206f72206c6573730000006044820152606401610db7565b505050565b600080546001600160a01b031633146117565760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0383166117ac5760405162461bcd60e51b815260206004820152601a60248201527f5f746f6b656e20616464726573732063616e6e6f7420626520300000000000006044820152606401610db7565b6001600160a01b0383163014156118055760405162461bcd60e51b815260206004820152601c60248201527f43616e2774207769746864726177206e617469766520746f6b656e73000000006044820152606401610db7565b6040516370a0823160e01b81523060048201526000906001600160a01b038516906370a0823190602401602060405180830381865afa15801561184c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118709190613f7f565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509085169063a9059cbb906044016020604051808303816000875af11580156118c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e79190613f98565b604080516001600160a01b0387168152602081018490529193507fdeda980967fcead7b61e78ac46a4da14274af29e894d4d61e8b81ec38ab3e438910160405180910390a15092915050565b6000546001600160a01b0316331461195d5760405162461bcd60e51b8152600401610db790613e14565b600d54610100900460ff16156119b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207265656e61626c652074726164696e670000000000000000006044820152606401610db7565b600d805462ffff0019166201010017905543600e556040517fa56feb2d31b9a7424db0be063fd450863979c9e2382cf5110f869bd1ad361bb790600090a1565b606060058054610cf390613dd9565b6000546001600160a01b03163314611a2e5760405162461bcd60e51b8152600401610db790613e14565b7f0000000000000000000000003a0cb47dbea6c4baed196dc07381c2e6749729cb6001600160a01b0316826001600160a01b03161415611ad65760405162461bcd60e51b815260206004820152603960248201527f54686520706169722063616e6e6f742062652072656d6f7665642066726f6d2060448201527f6175746f6d617465644d61726b65744d616b65725061697273000000000000006064820152608401610db7565b611ae08282612fba565b5050565b600080546001600160a01b03163314611b0f5760405162461bcd60e51b8152600401610db790613e14565b611b193383613024565b506001919050565b6000610d83338461106685604051806060016040528060258152602001614134602591393360009081526002602090815260408083206001600160a01b038d1684529091529020549190612f06565b6000610d8333848461262a565b6001600160a01b03811660009081526021602052604081205463ffffffff1680611ba8576000611bea565b6001600160a01b0383166000908152602080526040812090611bcb600184613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b9392505050565b6000546001600160a01b03163314611c1b5760405162461bcd60e51b8152600401610db790613e14565b6001600160a01b0382166000818152601d6020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7910160405180910390a25050565b6000546001600160a01b03163314611ca45760405162461bcd60e51b8152600401610db790613e14565b60178390556018829055601981905580611cbe8385613f67565b611cc89190613f67565b6016819055601410156117265760405162461bcd60e51b815260206004820152601d60248201527f4d757374206b656570206665657320617420323025206f72206c6573730000006044820152606401610db7565b60007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a866611d48610ce4565b80519060200120611d564690565b60408051602080820195909552808201939093526060830191909152306080808401919091528151808403909101815260a0830182528051908401207fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60c08401526001600160a01b038b1660e084015261010083018a90526101208084018a90528251808503909101815261014084019092528151919093012061190160f01b610160830152610162820183905261018282018190529192506000906101a20160408051601f198184030181528282528051602091820120600080855291840180845281905260ff8a169284019290925260608301889052608083018790529092509060019060a0016020604051602081039080840390855afa158015611e82573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116611ef55760405162461bcd60e51b815260206004820152602760248201527f504541524c3a3a64656c656761746542795369673a20696e76616c6964207369604482015266676e617475726560c81b6064820152608401610db7565b6001600160a01b0381166000908152602260205260408120805491611f1983613ebb565b919050558914611f775760405162461bcd60e51b815260206004820152602360248201527f504541524c3a3a64656c656761746542795369673a20696e76616c6964206e6f6044820152626e636560e81b6064820152608401610db7565b87421115611fd75760405162461bcd60e51b815260206004820152602760248201527f504541524c3a3a64656c656761746542795369673a207369676e617475726520604482015266195e1c1a5c995960ca1b6064820152608401610db7565b611fe1818b612f40565b505050505b505050505050565b6000546001600160a01b031633146120185760405162461bcd60e51b8152600401610db790613e14565b620186a061202560035490565b612030906001613ed6565b61203a9190613f0b565b8110156120a75760405162461bcd60e51b815260206004820152603560248201527f5377617020616d6f756e742063616e6e6f74206265206c6f776572207468616e60448201527410181718181892903a37ba30b61039bab838363c9760591b6064820152608401610db7565b6103e86120b360035490565b6120be906001613ed6565b6120c89190613f0b565b8111156121345760405162461bcd60e51b815260206004820152603460248201527f5377617020616d6f756e742063616e6e6f742062652068696768657220746861604482015273371018171892903a37ba30b61039bab838363c9760611b6064820152608401610db7565b600c55565b6000546001600160a01b031633146121635760405162461bcd60e51b8152600401610db790613e14565b670de0b6b3a76400006103e861217860035490565b612183906001613ed6565b61218d9190613f0b565b6121979190613f0b565b8110156121f95760405162461bcd60e51b815260206004820152602a60248201527f43616e6e6f7420736574206d61782073656c6c20616d6f756e74206c6f776572604482015269207468616e20302e312560b01b6064820152608401610db7565b61220b81670de0b6b3a7640000613ed6565b60098190556040519081527f53c4eb831d8cfeb750f1c62590d8cd30f4c6f0380d29a05caa09f0d92588560e9060200161116d565b6000546001600160a01b0316331461226a5760405162461bcd60e51b8152600401610db790613e14565b6011805460ff19169055565b6000546001600160a01b031633146122a05760405162461bcd60e51b8152600401610db790613e14565b6112818161310a565b6000546001600160a01b031633146122d35760405162461bcd60e51b8152600401610db790613e14565b604051600090339047908381818185875af1925050503d8060008114612315576040519150601f19603f3d011682016040523d82523d6000602084013e61231a565b606091505b50505050565b60008061232d8385613f67565b905083811015611bea5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610db7565b6001600160a01b0383166123e15760405162461bcd60e51b8152602060048201526024808201527f42455032303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610db7565b6001600160a01b0382166124425760405162461bcd60e51b815260206004820152602260248201527f42455032303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610db7565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b0383166125085760405162461bcd60e51b815260206004820152602560248201527f42455032303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610db7565b6001600160a01b03821661256a5760405162461bcd60e51b815260206004820152602360248201527f42455032303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610db7565b6125a78160405180606001604052806026815260200161410e602691396001600160a01b0386166000908152600160205260409020549190612f06565b6001600160a01b0380851660009081526001602052604080822093909355908416815220546125d69082612320565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124979085815260200190565b6001600160a01b03831661268e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610db7565b6001600160a01b0382166126f05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610db7565b8061270157611726838360006124a4565b600d5460ff1615612b0a576000546001600160a01b0384811691161480159061273857506000546001600160a01b03838116911614155b801561274c57506001600160a01b03821615155b801561276357506001600160a01b03821661dead14155b15612b0a57600d54610100900460ff166127fb576001600160a01b0383166000908152601e602052604090205460ff16806127b657506001600160a01b0382166000908152601e602052604090205460ff165b6127fb5760405162461bcd60e51b81526020600482015260166024820152752a3930b234b7339034b9903737ba1030b1ba34bb329760511b6044820152606401610db7565b601154610100900460ff16801561282a57506001600160a01b0383166000908152601f602052604090205460ff165b1561288457645d21dba0003a11156128845760405162461bcd60e51b815260206004820152601860248201527f4761732070726963652065786365656473206c696d69742e00000000000000006044820152606401610db7565b60115460ff16156129b1577f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b0316826001600160a01b03161415801561290357507f0000000000000000000000003a0cb47dbea6c4baed196dc07381c2e6749729cb6001600160a01b0316826001600160a01b031614155b156129b15732600090815260106020526040902054431161299e5760405162461bcd60e51b815260206004820152604960248201527f5f7472616e736665723a3a205472616e736665722044656c617920656e61626c60448201527f65642e20204f6e6c79206f6e652070757263686173652070657220626c6f636b6064820152681030b63637bbb2b21760b91b608482015260a401610db7565b3260009081526010602052604090204390555b6001600160a01b0383166000908152601f602052604090205460ff1680156129f257506001600160a01b0382166000908152601e602052604090205460ff16155b15612a5f57600854811115612a5a5760405162461bcd60e51b815260206004820152602860248201527f427579207472616e7366657220616d6f756e742065786365656473207468652060448201526736b0bc10313abc9760c11b6064820152608401610db7565b612b0a565b6001600160a01b0382166000908152601f602052604090205460ff168015612aa057506001600160a01b0383166000908152601e602052604090205460ff16155b15612b0a57600954811115612b0a5760405162461bcd60e51b815260206004820152602a60248201527f53656c6c207472616e7366657220616d6f756e742065786365656473207468656044820152691036b0bc1039b2b6361760b11b6064820152608401610db7565b30600090815260016020526040902054600c5481108015908190612b365750600d5462010000900460ff165b8015612b4c5750600b54600160a01b900460ff16155b8015612b7157506001600160a01b0385166000908152601f602052604090205460ff16155b8015612b9657506001600160a01b0385166000908152601d602052604090205460ff16155b8015612bbb57506001600160a01b0384166000908152601d602052604090205460ff16155b15612be957600b805460ff60a01b1916600160a01b179055612bdb6131ca565b600b805460ff60a01b191690555b6001600160a01b0385166000908152601d602052604090205460019060ff1680612c2b57506001600160a01b0385166000908152601d602052604090205460ff165b15612c34575060005b60008115612ef257600e5443148015612c6557506001600160a01b0387166000908152601f602052604090205460ff165b15612d15576064612c7786605f613ed6565b612c819190613f0b565b905060165460185482612c949190613ed6565b612c9e9190613f0b565b601b6000828254612caf9190613f67565b9091555050601654601754612cc49083613ed6565b612cce9190613f0b565b601a6000828254612cdf9190613f67565b9091555050601654601954612cf49083613ed6565b612cfe9190613f0b565b601c6000828254612d0f9190613f67565b90915550505b6001600160a01b0386166000908152601f602052604090205460ff168015612d3f57506000601654115b15612df757606460165486612d549190613ed6565b612d5e9190613f0b565b905060165460185482612d719190613ed6565b612d7b9190613f0b565b601b6000828254612d8c9190613f67565b9091555050601654601754612da19083613ed6565b612dab9190613f0b565b601a6000828254612dbc9190613f67565b9091555050601654601954612dd19083613ed6565b612ddb9190613f0b565b601c6000828254612dec9190613f67565b90915550612ed49050565b6001600160a01b0387166000908152601f602052604090205460ff168015612e2157506000601254115b15612ed457606460125486612e369190613ed6565b612e409190613f0b565b905060125460145482612e539190613ed6565b612e5d9190613f0b565b601b6000828254612e6e9190613f67565b9091555050601254601354612e839083613ed6565b612e8d9190613f0b565b601a6000828254612e9e9190613f67565b9091555050601254601554612eb39083613ed6565b612ebd9190613f0b565b601c6000828254612ece9190613f67565b90915550505b8015612ee557612ee58730836124a4565b612eef8186613fb5565b94505b612efd8787876124a4565b50505050505050565b60008184841115612f2a5760405162461bcd60e51b8152600401610db791906139fa565b506000612f378486613fb5565b95945050505050565b6001600160a01b03828116600081815260076020818152604080842080546001845282862054949093528787166001600160a01b03198416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a461231a8284836133d2565b6001600160a01b0382166000908152601f60205260409020805460ff1916821515179055612fe8828261352f565b604051811515906001600160a01b038416907fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab90600090a35050565b6001600160a01b03821661307a5760405162461bcd60e51b815260206004820152601f60248201527f42455032303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610db7565b6003546130879082612320565b6003556001600160a01b0382166000908152600160205260409020546130ad9082612320565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906130fe9085815260200190565b60405180910390a35050565b6001600160a01b03811661316f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610db7565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3060009081526001602052604081205490506000601c54601a54601b546131f19190613f67565b6131fb9190613f67565b9050811580613208575080155b15613211575050565b600c5461321f90600a613ed6565b82111561323757600c5461323490600a613ed6565b91505b600080600283601b548661324b9190613ed6565b6132559190613f0b565b61325f9190613f0b565b905061327361326e8286613fb5565b613592565b601b544790819060009061328990600290613f0b565b6132939087613fb5565b601a546132a09085613ed6565b6132aa9190613f0b565b905060006002601b546132bd9190613f0b565b6132c79088613fb5565b601c546132d49086613ed6565b6132de9190613f0b565b90506132ea8183613f67565b6132f49084613fb5565b6000601b819055601a559250841580159061330f5750600083115b1561331e5761331e858461374a565b600b546040516001600160a01b03909116908290600081818185875af1925050503d806000811461336b576040519150601f19603f3d011682016040523d82523d6000602084013e613370565b606091505b5050600a546040519197506001600160a01b0316904790600081818185875af1925050503d80600081146133c0576040519150601f19603f3d011682016040523d82523d6000602084013e6133c5565b606091505b5050505050505050505050565b816001600160a01b0316836001600160a01b0316141580156133f45750600081115b15611726576001600160a01b03831615613496576001600160a01b03831660009081526021602052604081205463ffffffff169081613434576000613476565b6001600160a01b0385166000908152602080526040812090613457600185613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006134848483613fb5565b90506134928684848461382b565b5050505b6001600160a01b03821615611726576001600160a01b03821660009081526021602052604081205463ffffffff1690816134d1576000613513565b6001600160a01b03841660009081526020805260408120906134f4600185613f1f565b63ffffffff1663ffffffff168152602001908152602001600020600101545b905060006135218483613f67565b9050611fe68584848461382b565b6001600160a01b0382166000818152601e6020908152604091829020805460ff19168515159081179091558251938452908301527f6b4f1be9103e6cbcd38ca4a922334f2c3109b260130a6676a987f94088fd6746910160405180910390a15050565b60408051600280825260608201835260009260208301908036833701905050905030816000815181106135c7576135c7613e8f565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015613645573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136699190613fcc565b8160018151811061367c5761367c613e8f565b60200260200101906001600160a01b031690816001600160a01b0316815250506136c7307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d8461237f565b60405163791ac94760e01b81526001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d169063791ac9479061371c908590600090869030904290600401613fe9565b600060405180830381600087803b15801561373657600080fd5b505af1158015611fe6573d6000803e3d6000fd5b613775307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d8461237f565b60405163f305d71960e01b815230600482015260248101839052600060448201819052606482015261dead60848201524260a48201527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03169063f305d71990839060c40160606040518083038185885af11580156137ff573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190613824919061405a565b5050505050565b600061384f436040518060600160405280603581526020016140d9603591396139ca565b905060008463ffffffff161180156138a857506001600160a01b0385166000908152602080526040812063ffffffff83169161388c600188613f1f565b63ffffffff908116825260208201929092526040016000205416145b156138f0576001600160a01b0385166000908152602080526040812083916138d1600188613f1f565b63ffffffff16815260208101919091526040016000206001015561397f565b60408051808201825263ffffffff838116825260208083018681526001600160a01b038a1660009081528280528581208a851682529092529390209151825463ffffffff19169116178155905160019182015561394e908590614088565b6001600160a01b0386166000908152602160205260409020805463ffffffff191663ffffffff929092169190911790555b60408051848152602081018490526001600160a01b038716917fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724910160405180910390a25050505050565b60008164010000000084106139f25760405162461bcd60e51b8152600401610db791906139fa565b509192915050565b600060208083528351808285015260005b81811015613a2757858101830151858201604001528201613a0b565b81811115613a39576000604083870101525b50601f01601f1916929092016040019392505050565b6001600160a01b038116811461128157600080fd5b60008060408385031215613a7757600080fd5b8235613a8281613a4f565b946020939093013593505050565b600060208284031215613aa257600080fd5b8135611bea81613a4f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613aec57613aec613aad565b604052919050565b600067ffffffffffffffff821115613b0e57613b0e613aad565b5060051b60200190565b600082601f830112613b2957600080fd5b81356020613b3e613b3983613af4565b613ac3565b82815260059290921b84018101918181019086841115613b5d57600080fd5b8286015b84811015613b785780358352918301918301613b61565b509695505050505050565b60008060408385031215613b9657600080fd5b823567ffffffffffffffff80821115613bae57600080fd5b818501915085601f830112613bc257600080fd5b81356020613bd2613b3983613af4565b82815260059290921b84018101918181019089841115613bf157600080fd5b948201945b83861015613c18578535613c0981613a4f565b82529482019490820190613bf6565b96505086013592505080821115613c2e57600080fd5b50613c3b85828601613b18565b9150509250929050565b600080600060608486031215613c5a57600080fd5b8335613c6581613a4f565b92506020840135613c7581613a4f565b929592945050506040919091013590565b600060208284031215613c9857600080fd5b5035919050565b801515811461128157600080fd5b60008060408385031215613cc057600080fd5b8235613ccb81613a4f565b91506020830135613cdb81613c9f565b809150509250929050565b600080600060608486031215613cfb57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215613d2557600080fd5b8235613d3081613a4f565b91506020830135613cdb81613a4f565b60008060008060008060c08789031215613d5957600080fd5b8635613d6481613a4f565b95506020870135945060408701359350606087013560ff81168114613d8857600080fd5b9598949750929560808101359460a0909101359350915050565b60008060408385031215613db557600080fd5b8235613dc081613a4f565b9150602083013563ffffffff81168114613cdb57600080fd5b600181811c90821680613ded57607f821691505b60208210811415613e0e57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526026908201527f5f6f7065726174696f6e734164647265737320616464726573732063616e6e6f60408201526507420626520360d41b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415613ecf57613ecf613ea5565b5060010190565b6000816000190483118215151615613ef057613ef0613ea5565b500290565b634e487b7160e01b600052601260045260246000fd5b600082613f1a57613f1a613ef5565b500490565b600063ffffffff83811690831681811015613f3c57613f3c613ea5565b039392505050565b600063ffffffff80841680613f5b57613f5b613ef5565b92169190910492915050565b60008219821115613f7a57613f7a613ea5565b500190565b600060208284031215613f9157600080fd5b5051919050565b600060208284031215613faa57600080fd5b8151611bea81613c9f565b600082821015613fc757613fc7613ea5565b500390565b600060208284031215613fde57600080fd5b8151611bea81613a4f565b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b818110156140395784516001600160a01b031683529383019391830191600101614014565b50506001600160a01b03969096166060850152505050608001529392505050565b60008060006060848603121561406f57600080fd5b8351925060208401519150604084015190509250925092565b600063ffffffff8083168185168083038211156140a7576140a7613ea5565b0194935050505056fe42455032303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365504541524c3a3a5f7772697465436865636b706f696e743a20626c6f636b206e756d6265722065786365656473203332206269747342455032303a207472616e7366657220616d6f756e7420657863656564732062616c616e636542455032303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220978f9ba368807d6ca36bd58b6f12b9cd953fe8e98061d85d3ec5d37eef4217af64736f6c634300080b0033

Deployed Bytecode Sourcemap

33856:24993:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25098:92;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34137:37;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;799:32:1;;;781:51;;769:2;754:18;34137:37:0;616:222:1;26585:161:0;;;;;;;;;;-1:-1:-1;26585:161:0;;;;;:::i;:::-;;:::i;:::-;;;1464:14:1;;1457:22;1439:41;;1427:2;1412:18;26585:161:0;1299:187:1;51816:276:0;;;;;;;;;;-1:-1:-1;51816:276:0;;;;;:::i;:::-;;:::i;:::-;;35376:29;;;;;;;;;;;;;;;;;;;1889:25:1;;;1877:2;1862:18;35376:29:0;1743:177:1;35680:64:0;;;;;;;;;;-1:-1:-1;35680:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;25574:100;;;;;;;;;;-1:-1:-1;25654:12:0;;25574:100;;35455:33;;;;;;;;;;;;;;;;34640;;;;;;;;;;;;;;;;37119:122;;;;;;;;;;;;37161:80;37119:122;;41418:758;;;;;;;;;;-1:-1:-1;41418:758:0;;;;;:::i;:::-;;:::i;27217:397::-;;;;;;;;;;-1:-1:-1;27217:397:0;;;;;:::i;:::-;;:::i;40220:269::-;;;;;;;;;;-1:-1:-1;40220:269:0;;;;;:::i;:::-;;:::i;25257:92::-;;;;;;;;;;-1:-1:-1;25332:9:0;;25257:92;;25332:9;;;;5382:36:1;;5370:2;5355:18;25257:92:0;5240:184:1;28022:210:0;;;;;;;;;;-1:-1:-1;28022:210:0;;;;;:::i;:::-;;:::i;35495:31::-;;;;;;;;;;;;;;;;34181;;;;;;;;;;;;;;;51398:410;;;;;;;;;;-1:-1:-1;51398:410:0;;;;;:::i;:::-;;:::i;34439:33::-;;;;;;;;;;-1:-1:-1;34439:33:0;;;;;;;;35299:32;;;;;;;;;;;;;;;;52242:149;;;;;;;;;;-1:-1:-1;52242:149:0;;;;;:::i;:::-;-1:-1:-1;;;;;52362:21:0;;;52330:7;52362:21;;;:10;:21;;;;;;;;52242:149;35152:31;;;;;;;;;;;;;;;;52535:104;;;;;;;;;;-1:-1:-1;52535:104:0;;;;;:::i;:::-;;:::i;34255:28::-;;;;;;;;;;;;;;;;35264;;;;;;;;;;;;;;;;34519:31;;;;;;;;;;-1:-1:-1;34519:31:0;;;;;;;;;;;36997:49;;;;;;;;;;-1:-1:-1;36997:49:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5811:10:1;5799:23;;;5781:42;;5769:2;5754:18;36997:49:0;5637:192:1;25736:119:0;;;;;;;;;;-1:-1:-1;25736:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;25829:18:0;25802:7;25829:18;;;:9;:18;;;;;;;25736:119;22097:140;;;;;;;;;;;;;:::i;39889:156::-;;;;;;;;;;;;;:::i;42188:260::-;;;;;;;;;;-1:-1:-1;42188:260:0;;;;;:::i;:::-;;:::i;55153:1254::-;;;;;;;;;;-1:-1:-1;55153:1254:0;;;;;:::i;:::-;;:::i;37533:39::-;;;;;;;;;;-1:-1:-1;37533:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;42959:389;;;;;;;;;;-1:-1:-1;42959:389:0;;;;;:::i;:::-;;:::i;50704:456::-;;;;;;;;;;-1:-1:-1;50704:456:0;;;;;:::i;:::-;;:::i;34221:27::-;;;;;;;;;;;;;;;;24941:94;;;;;;;;;;-1:-1:-1;24993:7:0;21520:6;-1:-1:-1;;;;;21520:6:0;24941:94;;39584:249;;;;;;;;;;;;;:::i;25414:96::-;;;;;;;;;;;;;:::i;42456:239::-;;;;;;;;;;-1:-1:-1;42456:239:0;;;;;:::i;:::-;;:::i;29263:130::-;;;;;;;;;;-1:-1:-1;29263:130:0;;;;;:::i;:::-;;:::i;35227:28::-;;;;;;;;;;;;;;;;28734:311;;;;;;;;;;-1:-1:-1;28734:311:0;;;;;:::i;:::-;;:::i;26067:167::-;;;;;;;;;;-1:-1:-1;26067:167:0;;;;;:::i;:::-;;:::i;34331:29::-;;;;;;;;;;-1:-1:-1;34331:29:0;;;;-1:-1:-1;;;;;34331:29:0;;;54467:255;;;;;;;;;;-1:-1:-1;54467:255:0;;;;;:::i;:::-;;:::i;35902:58::-;;;;;;;;;;-1:-1:-1;35902:58:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;34479:33;;;;;;;;;;-1:-1:-1;34479:33:0;;;;;;;;;;;43762:182;;;;;;;;;;-1:-1:-1;43762:182:0;;;;;:::i;:::-;;:::i;43356:398::-;;;;;;;;;;-1:-1:-1;43356:398:0;;;;;:::i;:::-;;:::i;53073:1193::-;;;;;;;;;;-1:-1:-1;53073:1193:0;;;;;:::i;:::-;;:::i;34928:39::-;;;;;;;;;;-1:-1:-1;34928:39:0;;;;;;;;40845:346;;;;;;;;;;-1:-1:-1;40845:346:0;;;;;:::i;:::-;;:::i;35118:27::-;;;;;;;;;;;;;;;;40501:274;;;;;;;;;;-1:-1:-1;40501:274:0;;;;;:::i;:::-;;:::i;26296:143::-;;;;;;;;;;-1:-1:-1;26296:143:0;;;;;:::i;:::-;-1:-1:-1;;;;;26404:18:0;;;26377:7;26404:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;26296:143;34397:33;;;;;;;;;;;;;;;;37335:117;;;;;;;;;;;;37381:71;37335:117;;40110:98;;;;;;;;;;;;;:::i;34292:32::-;;;;;;;;;;-1:-1:-1;34292:32:0;;;;-1:-1:-1;;;;;34292:32:0;;;34563:37;;;;;;;;;;;;;;;;36858:70;;;;;;;;;;-1:-1:-1;36858:70:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8376:10:1;8364:23;;;8346:42;;8419:2;8404:18;;8397:34;;;;8319:18;36858:70:0;8174:263:1;35190:30:0;;;;;;;;;;;;;;;;22392:109;;;;;;;;;;-1:-1:-1;22392:109:0;;;;;:::i;:::-;;:::i;51230:160::-;;;;;;;;;;;;;:::i;35338:31::-;;;;;;;;;;;;;;;;35414:34;;;;;;;;;;;;;;;;25098:92;25144:13;25177:5;25170:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25098:92;:::o;26585:161::-;26660:4;26677:39;20193:10;26700:7;26709:6;26677:8;:39::i;:::-;-1:-1:-1;26734:4:0;26585:161;;;;;:::o;51816:276::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;51906:29:0;::::1;51898:80;;;;-1:-1:-1::0;;;51898:80:0::1;;;;;;;:::i;:::-;51989:14;:41:::0;;-1:-1:-1;;;;;;51989:41:0::1;-1:-1:-1::0;;;;;51989:41:0;::::1;::::0;;::::1;::::0;;;52046:38:::1;::::0;::::1;::::0;-1:-1:-1;;52046:38:0::1;51816:276:::0;:::o;41418:758::-;41531:4;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;41556:13:::1;::::0;::::1;::::0;::::1;;;41555:14;41547:82;;;::::0;-1:-1:-1;;;41547:82:0;;9797:2:1;41547:82:0::1;::::0;::::1;9779:21:1::0;9836:2;9816:18;;;9809:30;9875:34;9855:18;;;9848:62;9946:25;9926:18;;;9919:53;9989:19;;41547:82:0::1;9595:419:1::0;41547:82:0::1;41673:7;:14;41648;:21;:39;41640:82;;;::::0;-1:-1:-1;;;41640:82:0;;10221:2:1;41640:82:0::1;::::0;::::1;10203:21:1::0;10260:2;10240:18;;;10233:30;10299:32;10279:18;;;10272:60;10349:18;;41640:82:0::1;10019:354:1::0;41640:82:0::1;41765:3;41741:14;:21;:27;41733:94;;;::::0;-1:-1:-1;;;41733:94:0;;10580:2:1;41733:94:0::1;::::0;::::1;10562:21:1::0;10619:2;10599:18;;;10592:30;10658:34;10638:18;;;10631:62;-1:-1:-1;;;10709:18:1;;;10702:52;10771:19;;41733:94:0::1;10378:418:1::0;41733:94:0::1;41940:9;41936:211;41959:14;:21;41955:1;:25;41936:211;;;42001:14;42018;42033:1;42018:17;;;;;;;;:::i;:::-;;;;;;;42001:34;;42050:14;42067:7;42075:1;42067:10;;;;;;;;:::i;:::-;;;;;;;42050:27;;42092:43;42108:10;42120:6;42128;42092:15;:43::i;:::-;41986:161;;41982:3;;;;;:::i;:::-;;;;41936:211;;;-1:-1:-1::0;42164:4:0::1;::::0;41418:758;-1:-1:-1;;;41418:758:0:o;27217:397::-;27349:4;27366:36;27376:6;27384:9;27395:6;27366:9;:36::i;:::-;27413:171;27436:6;20193:10;27484:89;27522:6;27484:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;27484:19:0;;;;;;:11;:19;;;;;;;;20193:10;27484:33;;;;;;;;;;:37;:89::i;:::-;27413:8;:171::i;40220:269::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;40339:4:::1;40333;40313:13;25654:12:::0;;;25574:100;40313:13:::1;:17;::::0;40329:1:::1;40313:17;:::i;:::-;:24;;;;:::i;:::-;40312:31;;;;:::i;:::-;40302:6;:41;;40294:95;;;::::0;-1:-1:-1;;;40294:95:0;;11837:2:1;40294:95:0::1;::::0;::::1;11819:21:1::0;11876:2;11856:18;;;11849:30;11915:34;11895:18;;;11888:62;-1:-1:-1;;;11966:18:1;;;11959:39;12015:19;;40294:95:0::1;11635:405:1::0;40294:95:0::1;40415:17;:6:::0;40425::::1;40415:17;:::i;:::-;40400:12;:32:::0;;;40448:33:::1;::::0;1889:25:1;;;40448:33:0::1;::::0;1877:2:1;1862:18;40448:33:0::1;;;;;;;;40220:269:::0;:::o;28022:210::-;20193:10;28102:4;28151:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;28151:34:0;;;;;;;;;;28102:4;;28119:83;;28142:7;;28151:50;;28190:10;28151:38;:50::i;51398:410::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51494:32:0;::::1;51486:83;;;;-1:-1:-1::0;;;51486:83:0::1;;;;;;;:::i;:::-;51600:17;::::0;;-1:-1:-1;;;;;51600:17:0;;::::1;51621:5;51580:38:::0;;;:19:::1;:38;::::0;;;;;:46;;-1:-1:-1;;51580:46:0;;::::1;::::0;;;51637:47;;-1:-1:-1;;;;;;51637:47:0::1;::::0;;::::1;::::0;;::::1;::::0;;;51695:38;;;;;;:45;;;;::::1;-1:-1:-1::0;51695:45:0::1;::::0;;;51756:44;;51637:47;;51756:44:::1;::::0;::::1;51398:410:::0;:::o;52535:104::-;52599:32;52609:10;52621:9;52599;:32::i;:::-;52535:104;:::o;22097:140::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;22196:1:::1;22180:6:::0;;22159:40:::1;::::0;-1:-1:-1;;;;;22180:6:0;;::::1;::::0;22159:40:::1;::::0;22196:1;;22159:40:::1;22227:1;22210:19:::0;;-1:-1:-1;;;;;;22210:19:0::1;::::0;;22097:140::o;39889:156::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;39943:14:::1;:22:::0;;-1:-1:-1;;39943:22:0::1;::::0;;39976:20:::1;:28:::0;;-1:-1:-1;;40015:22:0;;;39889:156::o;42188:260::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;42284:4:::1;42280:104;;42322:6;-1:-1:-1::0;;;;;42312:16:0::1;:6;-1:-1:-1::0;;;;;42312:16:0::1;;;42304:68;;;::::0;-1:-1:-1;;;42304:68:0;;12247:2:1;42304:68:0::1;::::0;::::1;12229:21:1::0;12286:2;12266:18;;;12259:30;12325:34;12305:18;;;12298:62;-1:-1:-1;;;12376:18:1;;;12369:37;12423:19;;42304:68:0::1;12045:403:1::0;42304:68:0::1;-1:-1:-1::0;;;;;42394:39:0;;;::::1;;::::0;;;:31:::1;:39;::::0;;;;:46;;-1:-1:-1;;42394:46:0::1;::::0;::::1;;::::0;;;::::1;::::0;;42188:260::o;55153:1254::-;55261:7;55308:12;55294:11;:26;55286:79;;;;-1:-1:-1;;;55286:79:0;;12655:2:1;55286:79:0;;;12637:21:1;12694:2;12674:18;;;12667:30;12733:34;12713:18;;;12706:62;-1:-1:-1;;;12784:18:1;;;12777:38;12832:19;;55286:79:0;12453:404:1;55286:79:0;-1:-1:-1;;;;;55400:23:0;;55378:19;55400:23;;;:14;:23;;;;;;;;55438:17;55434:58;;55479:1;55472:8;;;;;55434:58;-1:-1:-1;;;;;55552:20:0;;;;;;:11;:20;;;;;55604:11;;55573:16;55588:1;55573:12;:16;:::i;:::-;55552:38;;;;;;;;;;;;;;;-1:-1:-1;55552:38:0;:48;;:63;55548:147;;-1:-1:-1;;;;;55639:20:0;;;;;;:11;:20;;;;;;55660:16;55675:1;55660:12;:16;:::i;:::-;55639:38;;;;;;;;;;;;;;;:44;;;55632:51;;;;;55548:147;-1:-1:-1;;;;;55756:20:0;;;;;;:11;:20;;;;;;;:23;;;;;;;;:33;:23;:33;:47;-1:-1:-1;55752:88:0;;;55827:1;55820:8;;;;;55752:88;55852:12;;55894:16;55909:1;55894:12;:16;:::i;:::-;55879:31;;55921:428;55936:5;55928:13;;:5;:13;;;55921:428;;;55958:13;56000:1;55983:13;55991:5;55983;:13;:::i;:::-;55982:19;;;;:::i;:::-;55974:27;;:5;:27;:::i;:::-;-1:-1:-1;;;;;56066:20:0;;56043;56066;;;:11;:20;;;;;;;:28;;;;;;;;;;;;;56043:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;55958:43;;-1:-1:-1;56113:27:0;;56109:229;;;56168:8;;;;-1:-1:-1;56161:15:0;;-1:-1:-1;;;;56161:15:0;56109:229;56202:12;;:26;;;-1:-1:-1;56198:140:0;;;56257:6;56249:14;;56198:140;;;56312:10;56321:1;56312:6;:10;:::i;:::-;56304:18;;56198:140;55943:406;;55921:428;;;-1:-1:-1;;;;;;56366:20:0;;;;;;:11;:20;;;;;;;:27;;;;;;;;;;:33;;;;-1:-1:-1;;55153:1254:0;;;;:::o;42959:389::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;43080:16:::1;:33:::0;;;43124:15:::1;:31:::0;;;43166:13:::1;:27:::0;;;43182:11;43219:34:::1;43142:13:::0;43099:14;43219:34:::1;:::i;:::-;:50;;;;:::i;:::-;43204:12;:65:::0;;;43304:2:::1;-1:-1:-1::0;43288:18:0::1;43280:60;;;::::0;-1:-1:-1;;;43280:60:0;;13619:2:1;43280:60:0::1;::::0;::::1;13601:21:1::0;13658:2;13638:18;;;13631:30;13697:31;13677:18;;;13670:59;13746:18;;43280:60:0::1;13417:353:1::0;43280:60:0::1;42959:389:::0;;;:::o;50704:456::-;50791:10;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;50822:20:0;::::1;50814:59;;;::::0;-1:-1:-1;;;50814:59:0;;13977:2:1;50814:59:0::1;::::0;::::1;13959:21:1::0;14016:2;13996:18;;;13989:30;14055:28;14035:18;;;14028:56;14101:18;;50814:59:0::1;13775:350:1::0;50814:59:0::1;-1:-1:-1::0;;;;;50892:23:0;::::1;50910:4;50892:23;;50884:64;;;::::0;-1:-1:-1;;;50884:64:0;;14332:2:1;50884:64:0::1;::::0;::::1;14314:21:1::0;14371:2;14351:18;;;14344:30;14410;14390:18;;;14383:58;14458:18;;50884:64:0::1;14130:352:1::0;50884:64:0::1;50986:39;::::0;-1:-1:-1;;;50986:39:0;;51019:4:::1;50986:39;::::0;::::1;781:51:1::0;50959:24:0::1;::::0;-1:-1:-1;;;;;50986:24:0;::::1;::::0;::::1;::::0;754:18:1;;50986:39:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51044:46;::::0;-1:-1:-1;;;51044:46:0;;-1:-1:-1;;;;;14868:32:1;;;51044:46:0::1;::::0;::::1;14850:51:1::0;14917:18;;;14910:34;;;50959:66:0;;-1:-1:-1;51044:23:0;;::::1;::::0;::::1;::::0;14823:18:1;;51044:46:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51106;::::0;;-1:-1:-1;;;;;14868:32:1;;14850:51;;14932:2;14917:18;;14910:34;;;51036:54:0;;-1:-1:-1;51106:46:0::1;::::0;14823:18:1;51106:46:0::1;;;;;;;50803:357;50704:456:::0;;;;:::o;39584:249::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;39648:13:::1;::::0;::::1;::::0;::::1;;;39647:14;39639:50;;;::::0;-1:-1:-1;;;39639:50:0;;15407:2:1;39639:50:0::1;::::0;::::1;15389:21:1::0;15446:2;15426:18;;;15419:30;15485:25;15465:18;;;15458:53;15528:18;;39639:50:0::1;15205:347:1::0;39639:50:0::1;39700:13;:20:::0;;-1:-1:-1;;39731:18:0;;;;;39781:12:::1;39760:18;:33:::0;39809:16:::1;::::0;::::1;::::0;-1:-1:-1;;39809:16:0::1;39584:249::o:0;25414:96::-;25462:13;25495:7;25488:14;;;;;:::i;42456:239::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;42565:6:::1;-1:-1:-1::0;;;;;42557:14:0::1;:4;-1:-1:-1::0;;;;;42557:14:0::1;;;42549:84;;;::::0;-1:-1:-1;;;42549:84:0;;15759:2:1;42549:84:0::1;::::0;::::1;15741:21:1::0;15798:2;15778:18;;;15771:30;15837:34;15817:18;;;15810:62;15908:27;15888:18;;;15881:55;15953:19;;42549:84:0::1;15557:421:1::0;42549:84:0::1;42646:41;42675:4;42681:5;42646:28;:41::i;:::-;42456:239:::0;;:::o;29263:130::-;29319:4;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;29336:27:::1;20193:10:::0;29356:6:::1;29336:5;:27::i;:::-;-1:-1:-1::0;29381:4:0::1;29263:130:::0;;;:::o;28734:311::-;28819:4;28836:179;20193:10;28886:7;28908:96;28947:15;28908:96;;;;;;;;;;;;;;;;;20193:10;28908:25;;;;:11;:25;;;;;;;;-1:-1:-1;;;;;28908:34:0;;;;;;;;;;;;:38;:96::i;26067:167::-;26145:4;26162:42;20193:10;26186:9;26197:6;26162:9;:42::i;54467:255::-;-1:-1:-1;;;;;54606:23:0;;54559:7;54606:23;;;:14;:23;;;;;;;;54647:16;:67;;54713:1;54647:67;;;-1:-1:-1;;;;;54666:20:0;;;;;;:11;:20;;;;;;54687:16;54702:1;54687:12;:16;:::i;:::-;54666:38;;;;;;;;;;;;;;;:44;;;54647:67;54640:74;54467:255;-1:-1:-1;;;54467:255:0:o;43762:182::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;43847:28:0;::::1;;::::0;;;:19:::1;:28;::::0;;;;;;;;:39;;-1:-1:-1;;43847:39:0::1;::::0;::::1;;::::0;;::::1;::::0;;;43902:34;;1439:41:1;;;43902:34:0::1;::::0;1412:18:1;43902:34:0::1;;;;;;;43762:182:::0;;:::o;43356:398::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;43478:17:::1;:34:::0;;;43523:16:::1;:32:::0;;;43566:14:::1;:28:::0;;;43583:11;43621:36:::1;43542:13:::0;43498:14;43621:36:::1;:::i;:::-;:53;;;;:::i;:::-;43605:13;:69:::0;;;43710:2:::1;-1:-1:-1::0;43693:19:0::1;43685:61;;;::::0;-1:-1:-1;;;43685:61:0;;16185:2:1;43685:61:0::1;::::0;::::1;16167:21:1::0;16224:2;16204:18;;;16197:30;16263:31;16243:18;;;16236:59;16312:18;;43685:61:0::1;15983:353:1::0;53073:1193:0;53266:23;37161:80;53395:6;:4;:6::i;:::-;53379:24;;;;;;53422:12;58803:9;;58693:153;53422:12;53316:165;;;;;;;16572:25:1;;;;16613:18;;;16606:34;;;;16656:18;;;16649:34;;;;53461:4:0;16699:18:1;;;;16692:60;;;;53316:165:0;;;;;;;;;;16544:19:1;;;53316:165:0;;53292:200;;;;;;37381:71;53550:140;;;16994:25:1;-1:-1:-1;;;;;17055:32:1;;17035:18;;;17028:60;17104:18;;;17097:34;;;17147:18;;;;17140:34;;;53550:140:0;;;;;;;;;;16966:19:1;;;53550:140:0;;;53526:175;;;;;;;-1:-1:-1;;;53755:123:0;;;17443:27:1;17486:11;;;17479:27;;;17522:12;;;17515:28;;;53292:200:0;;-1:-1:-1;;;17559:12:1;;53755:123:0;;;-1:-1:-1;;53755:123:0;;;;;;;;;53731:158;;53755:123;53731:158;;;;53902:17;53922:26;;;;;;;;;17809:25:1;;;17882:4;17870:17;;17850:18;;;17843:45;;;;17904:18;;;17897:34;;;17947:18;;;17940:34;;;53731:158:0;;-1:-1:-1;53902:17:0;53922:26;;17781:19:1;;53922:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;53922:26:0;;-1:-1:-1;;53922:26:0;;;-1:-1:-1;;;;;;;53967:23:0;;53959:75;;;;-1:-1:-1;;;53959:75:0;;18187:2:1;53959:75:0;;;18169:21:1;18226:2;18206:18;;;18199:30;18265:34;18245:18;;;18238:62;-1:-1:-1;;;18316:18:1;;;18309:37;18363:19;;53959:75:0;17985:403:1;53959:75:0;-1:-1:-1;;;;;54062:17:0;;;;;;:6;:17;;;;;:19;;;;;;:::i;:::-;;;;;54053:5;:28;54045:76;;;;-1:-1:-1;;;54045:76:0;;18595:2:1;54045:76:0;;;18577:21:1;18634:2;18614:18;;;18607:30;18673:34;18653:18;;;18646:62;-1:-1:-1;;;18724:18:1;;;18717:33;18767:19;;54045:76:0;18393:399:1;54045:76:0;54159:6;54140:15;:25;;54132:77;;;;-1:-1:-1;;;54132:77:0;;18999:2:1;54132:77:0;;;18981:21:1;19038:2;19018:18;;;19011:30;19077:34;19057:18;;;19050:62;-1:-1:-1;;;19128:18:1;;;19121:37;19175:19;;54132:77:0;18797:403:1;54132:77:0;54227:31;54237:9;54248;54227;:31::i;:::-;54220:38;;;;53073:1193;;;;;;;:::o;40845:346::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;40968:6:::1;40948:13;25654:12:::0;;;25574:100;40948:13:::1;:17;::::0;40964:1:::1;40948:17;:::i;:::-;:26;;;;:::i;:::-;40935:9;:39;;40927:105;;;::::0;-1:-1:-1;;;40927:105:0;;19407:2:1;40927:105:0::1;::::0;::::1;19389:21:1::0;19446:2;19426:18;;;19419:30;19485:34;19465:18;;;19458:62;-1:-1:-1;;;19536:18:1;;;19529:51;19597:19;;40927:105:0::1;19205:417:1::0;40927:105:0::1;41083:4;41063:13;25654:12:::0;;;25574:100;41063:13:::1;:17;::::0;41079:1:::1;41063:17;:::i;:::-;:24;;;;:::i;:::-;41050:9;:37;;41042:102;;;::::0;-1:-1:-1;;;41042:102:0;;19829:2:1;41042:102:0::1;::::0;::::1;19811:21:1::0;19868:2;19848:18;;;19841:30;19907:34;19887:18;;;19880:62;-1:-1:-1;;;19958:18:1;;;19951:50;20018:19;;41042:102:0::1;19627:416:1::0;41042:102:0::1;41154:18;:30:::0;40845:346::o;40501:274::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;40621:4:::1;40615;40595:13;25654:12:::0;;;25574:100;40595:13:::1;:17;::::0;40611:1:::1;40595:17;:::i;:::-;:24;;;;:::i;:::-;40594:31;;;;:::i;:::-;40584:6;:41;;40576:96;;;::::0;-1:-1:-1;;;40576:96:0;;20250:2:1;40576:96:0::1;::::0;::::1;20232:21:1::0;20289:2;20269:18;;;20262:30;20328:34;20308:18;;;20301:62;-1:-1:-1;;;20379:18:1;;;20372:40;20429:19;;40576:96:0::1;20048:406:1::0;40576:96:0::1;40699:17;:6:::0;40709::::1;40699:17;:::i;:::-;40683:13;:33:::0;;;40732:35:::1;::::0;1889:25:1;;;40732:35:0::1;::::0;1877:2:1;1862:18;40732:35:0::1;1743:177:1::0;40110:98:0;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;40172:20:::1;:28:::0;;-1:-1:-1;;40172:28:0::1;::::0;;40110:98::o;22392:109::-;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;22465:28:::1;22484:8;22465:18;:28::i;51230:160::-:0;21667:6;;-1:-1:-1;;;;;21667:6:0;20193:10;21667:22;21659:67;;;;-1:-1:-1;;;21659:67:0;;;;;;;:::i;:::-;51324:58:::1;::::0;51288:12:::1;::::0;51332:10:::1;::::0;51356:21:::1;::::0;51288:12;51324:58;51288:12;51324:58;51356:21;51332:10;51324:58:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;51230:160:0:o;909:181::-;967:7;;999:5;1003:1;999;:5;:::i;:::-;987:17;;1028:1;1023;:6;;1015:46;;;;-1:-1:-1;;;1015:46:0;;20871:2:1;1015:46:0;;;20853:21:1;20910:2;20890:18;;;20883:30;20949:29;20929:18;;;20922:57;20996:18;;1015:46:0;20669:351:1;32105:372:0;-1:-1:-1;;;;;32233:19:0;;32225:68;;;;-1:-1:-1;;;32225:68:0;;21227:2:1;32225:68:0;;;21209:21:1;21266:2;21246:18;;;21239:30;21305:34;21285:18;;;21278:62;-1:-1:-1;;;21356:18:1;;;21349:34;21400:19;;32225:68:0;21025:400:1;32225:68:0;-1:-1:-1;;;;;32312:21:0;;32304:68;;;;-1:-1:-1;;;32304:68:0;;21632:2:1;32304:68:0;;;21614:21:1;21671:2;21651:18;;;21644:30;21710:34;21690:18;;;21683:62;-1:-1:-1;;;21761:18:1;;;21754:32;21803:19;;32304:68:0;21430:398:1;32304:68:0;-1:-1:-1;;;;;32385:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;32437:32;;1889:25:1;;;32437:32:0;;1862:18:1;32437:32:0;;;;;;;;32105:372;;;:::o;29883:513::-;-1:-1:-1;;;;;30023:20:0;;30015:70;;;;-1:-1:-1;;;30015:70:0;;22035:2:1;30015:70:0;;;22017:21:1;22074:2;22054:18;;;22047:30;22113:34;22093:18;;;22086:62;-1:-1:-1;;;22164:18:1;;;22157:35;22209:19;;30015:70:0;21833:401:1;30015:70:0;-1:-1:-1;;;;;30104:23:0;;30096:71;;;;-1:-1:-1;;;30096:71:0;;22441:2:1;30096:71:0;;;22423:21:1;22480:2;22460:18;;;22453:30;22519:34;22499:18;;;22492:62;-1:-1:-1;;;22570:18:1;;;22563:33;22613:19;;30096:71:0;22239:399:1;30096:71:0;30200;30222:6;30200:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30200:17:0;;;;;;:9;:17;;;;;;;:71;:21;:71::i;:::-;-1:-1:-1;;;;;30180:17:0;;;;;;;:9;:17;;;;;;:91;;;;30305:20;;;;;;;:32;;30330:6;30305:24;:32::i;:::-;-1:-1:-1;;;;;30282:20:0;;;;;;;:9;:20;;;;;;;:55;;;;30353:35;;;;;;;;;;30381:6;1889:25:1;;1877:2;1862:18;;1743:177;43952:4179:0;-1:-1:-1;;;;;44052:18:0;;44044:68;;;;-1:-1:-1;;;44044:68:0;;22845:2:1;44044:68:0;;;22827:21:1;22884:2;22864:18;;;22857:30;22923:34;22903:18;;;22896:62;-1:-1:-1;;;22974:18:1;;;22967:35;23019:19;;44044:68:0;22643:401:1;44044:68:0;-1:-1:-1;;;;;44131:16:0;;44123:64;;;;-1:-1:-1;;;44123:64:0;;23251:2:1;44123:64:0;;;23233:21:1;23290:2;23270:18;;;23263:30;23329:34;23309:18;;;23302:62;-1:-1:-1;;;23380:18:1;;;23373:33;23423:19;;44123:64:0;23049:399:1;44123:64:0;44201:11;44198:91;;44228:28;44244:4;44250:2;44254:1;44228:15;:28::i;44198:91::-;44312:14;;;;44309:1670;;;21493:7;21520:6;-1:-1:-1;;;;;44346:15:0;;;21520:6;;44346:15;;;;:32;;-1:-1:-1;21493:7:0;21520:6;-1:-1:-1;;;;;44365:13:0;;;21520:6;;44365:13;;44346:32;:52;;;;-1:-1:-1;;;;;;44382:16:0;;;;44346:52;:77;;;;-1:-1:-1;;;;;;44402:21:0;;44416:6;44402:21;;44346:77;44342:1626;;;44447:13;;;;;;;44443:172;;-1:-1:-1;;;;;44492:37:0;;;;;;:31;:37;;;;;;;;;:76;;-1:-1:-1;;;;;;44533:35:0;;;;;;:31;:35;;;;;;;;44492:76;44484:111;;;;-1:-1:-1;;;44484:111:0;;23655:2:1;44484:111:0;;;23637:21:1;23694:2;23674:18;;;23667:30;-1:-1:-1;;;23713:18:1;;;23706:52;23775:18;;44484:111:0;23453:346:1;44484:111:0;44712:14;;;;;;;:49;;;;-1:-1:-1;;;;;;44730:31:0;;;;;;:25;:31;;;;;;;;44712:49;44708:163;;;35058:12;44794:11;:28;;44786:65;;;;-1:-1:-1;;;44786:65:0;;24006:2:1;44786:65:0;;;23988:21:1;24045:2;24025:18;;;24018:30;24084:26;24064:18;;;24057:54;24128:18;;44786:65:0;23804:348:1;44786:65:0;45045:20;;;;45041:393;;;45107:9;-1:-1:-1;;;;;45093:24:0;:2;-1:-1:-1;;;;;45093:24:0;;;:49;;;;;45135:6;-1:-1:-1;;;;;45121:21:0;:2;-1:-1:-1;;;;;45121:21:0;;;45093:49;45089:326;;;45207:9;45178:39;;;;:28;:39;;;;;;45220:12;-1:-1:-1;45170:140:0;;;;-1:-1:-1;;;45170:140:0;;24359:2:1;45170:140:0;;;24341:21:1;24398:2;24378:18;;;24371:30;24437:34;24417:18;;;24410:62;24508:34;24488:18;;;24481:62;-1:-1:-1;;;24559:19:1;;;24552:40;24609:19;;45170:140:0;24157:477:1;45170:140:0;45366:9;45337:39;;;;:28;:39;;;;;45379:12;45337:54;;45089:326;-1:-1:-1;;;;;45503:31:0;;;;;;:25;:31;;;;;;;;:71;;;;-1:-1:-1;;;;;;45539:35:0;;;;;;:31;:35;;;;;;;;45538:36;45503:71;45499:454;;;45621:12;;45611:6;:22;;45603:75;;;;-1:-1:-1;;;45603:75:0;;24841:2:1;45603:75:0;;;24823:21:1;24880:2;24860:18;;;24853:30;24919:34;24899:18;;;24892:62;-1:-1:-1;;;24970:18:1;;;24963:38;25018:19;;45603:75:0;24639:404:1;45603:75:0;45499:454;;;-1:-1:-1;;;;;45755:29:0;;;;;;:25;:29;;;;;;;;:71;;;;-1:-1:-1;;;;;;45789:37:0;;;;;;:31;:37;;;;;;;;45788:38;45755:71;45751:202;;;45873:13;;45863:6;:23;;45855:78;;;;-1:-1:-1;;;45855:78:0;;25250:2:1;45855:78:0;;;25232:21:1;25289:2;25269:18;;;25262:30;25328:34;25308:18;;;25301:62;-1:-1:-1;;;25379:18:1;;;25372:40;25429:19;;45855:78:0;25048:406:1;45855:78:0;46040:4;45991:28;25829:18;;;:9;:18;;;;;;46106;;46082:42;;;;;;;46140:22;;-1:-1:-1;46151:11:0;;;;;;;46140:22;:35;;;;-1:-1:-1;46167:8:0;;-1:-1:-1;;;46167:8:0;;;;46166:9;46140:35;:71;;;;-1:-1:-1;;;;;;46180:31:0;;;;;;:25;:31;;;;;;;;46179:32;46140:71;:101;;;;-1:-1:-1;;;;;;46216:25:0;;;;;;:19;:25;;;;;;;;46215:26;46140:101;:129;;;;-1:-1:-1;;;;;;46246:23:0;;;;;;:19;:23;;;;;;;;46245:24;46140:129;46137:236;;;46286:8;:15;;-1:-1:-1;;;;46286:15:0;-1:-1:-1;;;46286:15:0;;;46318:10;:8;:10::i;:::-;46345:8;:16;;-1:-1:-1;;;;46345:16:0;;;46137:236;-1:-1:-1;;;;;46503:25:0;;46385:12;46503:25;;;:19;:25;;;;;;46400:4;;46503:25;;;:52;;-1:-1:-1;;;;;;46532:23:0;;;;;;:19;:23;;;;;;;;46503:52;46500:99;;;-1:-1:-1;46582:5:0;46500:99;46619:12;46723:7;46720:1358;;;46765:18;;46749:12;:34;:69;;;;-1:-1:-1;;;;;;46787:31:0;;;;;;:25;:31;;;;;;;;46749:69;46746:370;;;46859:3;46845:11;:6;46854:2;46845:11;:::i;:::-;:17;;;;:::i;:::-;46838:24;;46929:13;;46910:16;;46903:4;:23;;;;:::i;:::-;:39;;;;:::i;:::-;46881:18;;:61;;;;;;;:::i;:::-;;;;-1:-1:-1;;47011:13:0;;46991:17;;46984:24;;:4;:24;:::i;:::-;:40;;;;:::i;:::-;46961:19;;:63;;;;;;;:::i;:::-;;;;-1:-1:-1;;47087:13:0;;47070:14;;47063:21;;:4;:21;:::i;:::-;:37;;;;:::i;:::-;47043:16;;:57;;;;;;;:::i;:::-;;;;-1:-1:-1;;46746:370:0;-1:-1:-1;;;;;47158:29:0;;;;;;:25;:29;;;;;;;;:50;;;;;47207:1;47191:13;;:17;47158:50;47154:755;;;47259:3;47244:13;;47235:6;:22;;;;:::i;:::-;:27;;;;:::i;:::-;47228:34;;47329:13;;47310:16;;47303:4;:23;;;;:::i;:::-;:39;;;;:::i;:::-;47281:18;;:61;;;;;;;:::i;:::-;;;;-1:-1:-1;;47411:13:0;;47391:17;;47384:24;;:4;:24;:::i;:::-;:40;;;;:::i;:::-;47361:19;;:63;;;;;;;:::i;:::-;;;;-1:-1:-1;;47487:13:0;;47470:14;;47463:21;;:4;:21;:::i;:::-;:37;;;;:::i;:::-;47443:16;;:57;;;;;;;:::i;:::-;;;;-1:-1:-1;47154:755:0;;-1:-1:-1;47154:755:0;;-1:-1:-1;;;;;47561:31:0;;;;;;:25;:31;;;;;;;;:51;;;;;47611:1;47596:12;;:16;47561:51;47558:351;;;47661:3;47646:12;;47637:6;:21;;;;:::i;:::-;:27;;;;:::i;:::-;47630:34;;47727:12;;47709:15;;47702:4;:22;;;;:::i;:::-;:37;;;;:::i;:::-;47680:18;;:59;;;;;;;:::i;:::-;;;;-1:-1:-1;;47807:12:0;;47788:16;;47781:23;;:4;:23;:::i;:::-;:38;;;;:::i;:::-;47758:19;;:61;;;;;;;:::i;:::-;;;;-1:-1:-1;;47881:12:0;;47865:13;;47858:20;;:4;:20;:::i;:::-;:35;;;;:::i;:::-;47838:16;;:55;;;;;;;:::i;:::-;;;;-1:-1:-1;;47558:351:0;47940:8;;47937:93;;47972:42;47988:4;48002;48009;47972:15;:42::i;:::-;48052:14;48062:4;48052:14;;:::i;:::-;;;46720:1358;48090:33;48106:4;48112:2;48116:6;48090:15;:33::i;:::-;44031:4100;;;;43952:4179;;;:::o;1812:226::-;1932:7;1968:12;1960:6;;;;1952:29;;;;-1:-1:-1;;;1952:29:0;;;;;;;;:::i;:::-;-1:-1:-1;1992:9:0;2004:5;2008:1;2004;:5;:::i;:::-;1992:17;1812:226;-1:-1:-1;;;;;1812:226:0:o;56415:439::-;-1:-1:-1;;;;;56532:21:0;;;56506:23;56532:21;;;:10;:21;;;;;;;;;;25829:9;:18;;;;;;56668:21;;;;:33;;;-1:-1:-1;;;;;;56668:33:0;;;;;;;56719:54;;56532:21;;;;;25829:18;;56668:33;;56532:21;;;56719:54;;56506:23;56719:54;56786:60;56801:15;56818:9;56829:16;56786:14;:60::i;42703:248::-;-1:-1:-1;;;;;42786:31:0;;;;;;:25;:31;;;;;:39;;-1:-1:-1;;42786:39:0;;;;;;;42846;42786:31;:39;42846:26;:39::i;:::-;42903:40;;;;;;-1:-1:-1;;;;;42903:40:0;;;;;;;;42703:248;;:::o;30677:308::-;-1:-1:-1;;;;;30753:21:0;;30745:65;;;;-1:-1:-1;;;30745:65:0;;25791:2:1;30745:65:0;;;25773:21:1;25830:2;25810:18;;;25803:30;25869:33;25849:18;;;25842:61;25920:18;;30745:65:0;25589:355:1;30745:65:0;30838:12;;:24;;30855:6;30838:16;:24::i;:::-;30823:12;:39;-1:-1:-1;;;;;30894:18:0;;;;;;:9;:18;;;;;;:30;;30917:6;30894:22;:30::i;:::-;-1:-1:-1;;;;;30873:18:0;;;;;;:9;:18;;;;;;:51;;;;30940:37;;30873:18;;;30940:37;;;;30970:6;1889:25:1;;1877:2;1862:18;;1743:177;30940:37:0;;;;;;;;30677:308;;:::o;22607:229::-;-1:-1:-1;;;;;22681:22:0;;22673:73;;;;-1:-1:-1;;;22673:73:0;;26151:2:1;22673:73:0;;;26133:21:1;26190:2;26170:18;;;26163:30;26229:34;26209:18;;;26202:62;-1:-1:-1;;;26280:18:1;;;26273:36;26326:19;;22673:73:0;25949:402:1;22673:73:0;22783:6;;;22762:38;;-1:-1:-1;;;;;22762:38:0;;;;22783:6;;;22762:38;;;22811:6;:17;;-1:-1:-1;;;;;;22811:17:0;-1:-1:-1;;;;;22811:17:0;;;;;;;;;;22607:229::o;49241:1455::-;49324:4;49280:23;25829:18;;;:9;:18;;;;;;49280:50;;49341:25;49412:16;;49390:19;;49369:18;;:40;;;;:::i;:::-;:59;;;;:::i;:::-;49341:87;-1:-1:-1;49452:20:0;;;:46;;-1:-1:-1;49476:22:0;;49452:46;49449:60;;;49501:7;;49241:1455::o;49449:60::-;49542:18;;:23;;49563:2;49542:23;:::i;:::-;49524:15;:41;49521:113;;;49599:18;;:23;;49620:2;49599:23;:::i;:::-;49581:41;;49521:113;49646:12;49728:23;49813:1;49793:17;49772:18;;49754:15;:36;;;;:::i;:::-;:56;;;;:::i;:::-;:60;;;;:::i;:::-;49728:86;-1:-1:-1;49835:51:0;49852:33;49728:86;49852:15;:33;:::i;:::-;49835:16;:51::i;:::-;50094:18;;49929:21;;;;49908:18;;50094:20;;50113:1;;50094:20;:::i;:::-;50073:42;;:17;:42;:::i;:::-;50050:19;;50037:32;;:10;:32;:::i;:::-;:79;;;;:::i;:::-;50010:106;;50127:21;50224:1;50205:18;;:20;;;;:::i;:::-;50184:42;;:17;:42;:::i;:::-;50164:16;;50151:29;;:10;:29;:::i;:::-;:76;;;;:::i;:::-;50127:100;-1:-1:-1;50259:32:0;50127:100;50259:16;:32;:::i;:::-;50240:51;;;;:::i;:::-;50337:1;50316:18;:22;;;50349:19;:23;50240:51;-1:-1:-1;50396:19:0;;;;;:42;;;50437:1;50419:15;:19;50396:42;50393:119;;;50454:46;50467:15;50484;50454:12;:46::i;:::-;50553:14;;50545:54;;-1:-1:-1;;;;;50553:14:0;;;;50581:13;;50545:54;;;;50581:13;50553:14;50545:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;50631:17:0;;50623:65;;50532:67;;-1:-1:-1;;;;;;50631:17:0;;50662:21;;50623:65;;;;50662:21;50631:17;50623:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;49241:1455:0:o;56862:941::-;56968:6;-1:-1:-1;;;;;56958:16:0;:6;-1:-1:-1;;;;;56958:16:0;;;:30;;;;;56987:1;56978:6;:10;56958:30;56954:842;;;-1:-1:-1;;;;;57009:20:0;;;57005:382;;-1:-1:-1;;;;;57117:22:0;;57098:16;57117:22;;;:14;:22;;;;;;;;;57178:13;:60;;57237:1;57178:60;;;-1:-1:-1;;;;;57194:19:0;;;;;;:11;:19;;;;;;57214:13;57226:1;57214:9;:13;:::i;:::-;57194:34;;;;;;;;;;;;;;;:40;;;57178:60;57158:80;-1:-1:-1;57257:17:0;57277:18;57289:6;57158:80;57277:18;:::i;:::-;57257:38;;57314:57;57331:6;57339:9;57350;57361;57314:16;:57::i;:::-;57031:356;;;57005:382;-1:-1:-1;;;;;57407:20:0;;;57403:382;;-1:-1:-1;;;;;57515:22:0;;57496:16;57515:22;;;:14;:22;;;;;;;;;57576:13;:60;;57635:1;57576:60;;;-1:-1:-1;;;;;57592:19:0;;;;;;:11;:19;;;;;;57612:13;57624:1;57612:9;:13;:::i;:::-;57592:34;;;;;;;;;;;;;;;:40;;;57576:60;57556:80;-1:-1:-1;57655:17:0;57675:18;57687:6;57556:80;57675:18;:::i;:::-;57655:38;;57712:57;57729:6;57737:9;57748;57759;57712:16;:57::i;41203:207::-;-1:-1:-1;;;;;41291:39:0;;;;;;:31;:39;;;;;;;;;:52;;-1:-1:-1;;41291:52:0;;;;;;;;;;41359:43;;26524:51:1;;;26591:18;;;26584:50;41359:43:0;;26497:18:1;41359:43:0;;;;;;;41203:207;;:::o;48139:573::-;48291:16;;;48305:1;48291:16;;;;;;;;48267:21;;48291:16;;;;;;;;;;-1:-1:-1;48291:16:0;48267:40;;48336:4;48318;48323:1;48318:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1;;;;;48318:23:0;;;-1:-1:-1;;;;;48318:23:0;;;;;48362:9;-1:-1:-1;;;;;48362:14:0;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48352:4;48357:1;48352:7;;;;;;;;:::i;:::-;;;;;;:26;-1:-1:-1;;;;;48352:26:0;;;-1:-1:-1;;;;;48352:26:0;;;;;48391:56;48408:4;48423:9;48435:11;48391:8;:56::i;:::-;48486:218;;-1:-1:-1;;;48486:218:0;;-1:-1:-1;;;;;48486:9:0;:60;;;;:218;;48561:11;;48587:1;;48631:4;;48658;;48678:15;;48486:218;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48724:509;48872:56;48889:4;48904:9;48916:11;48872:8;:56::i;:::-;48971:254;;-1:-1:-1;;;48971:254:0;;49037:4;48971:254;;;28227:34:1;28277:18;;;28270:34;;;49083:1:0;28320:18:1;;;28313:34;;;28363:18;;;28356:34;49177:6:0;28406:19:1;;;28399:44;49199:15:0;28459:19:1;;;28452:35;48971:9:0;-1:-1:-1;;;;;48971:25:0;;;;49004:9;;28161:19:1;;48971:254:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;48724:509;;:::o;57811:705::-;57990:18;58011:77;58018:12;58011:77;;;;;;;;;;;;;;;;;:6;:77::i;:::-;57990:98;;58120:1;58105:12;:16;;;:85;;;;-1:-1:-1;;;;;;58125:22:0;;;;;;:11;:22;;;;;:65;;;;58148:16;58163:1;58148:12;:16;:::i;:::-;58125:40;;;;;;;;;;;;;;;-1:-1:-1;58125:40:0;:50;;:65;58105:85;58101:339;;;-1:-1:-1;;;;;58207:22:0;;;;;;:11;:22;;;;;58256:8;;58230:16;58245:1;58230:12;:16;:::i;:::-;58207:40;;;;;;;;;;;;;-1:-1:-1;58207:40:0;:46;;:57;58101:339;;;58336:33;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;58297:22:0;;-1:-1:-1;58297:22:0;;;;;;;;;:36;;;;;;;;;;;:72;;;;-1:-1:-1;;58297:72:0;;;;;;;;-1:-1:-1;58297:72:0;;;;58412:16;;58297:36;;58412:16;:::i;:::-;-1:-1:-1;;;;;58384:25:0;;;;;;:14;:25;;;;;:44;;-1:-1:-1;;58384:44:0;;;;;;;;;;;;58101:339;58457:51;;;29216:25:1;;;29272:2;29257:18;;29250:34;;;-1:-1:-1;;;;;58457:51:0;;;;;29189:18:1;58457:51:0;;;;;;;57979:537;57811:705;;;;:::o;58524:161::-;58599:6;58637:12;58630:5;58626:9;;58618:32;;;;-1:-1:-1;;;58618:32:0;;;;;;;;:::i;:::-;-1:-1:-1;58675:1:0;;58524:161;-1:-1:-1;;58524:161:0:o;14:597:1:-;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:1;574:15;-1:-1:-1;;570:29:1;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:1:o;843:131::-;-1:-1:-1;;;;;918:31:1;;908:42;;898:70;;964:1;961;954:12;979:315;1047:6;1055;1108:2;1096:9;1087:7;1083:23;1079:32;1076:52;;;1124:1;1121;1114:12;1076:52;1163:9;1150:23;1182:31;1207:5;1182:31;:::i;:::-;1232:5;1284:2;1269:18;;;;1256:32;;-1:-1:-1;;;979:315:1:o;1491:247::-;1550:6;1603:2;1591:9;1582:7;1578:23;1574:32;1571:52;;;1619:1;1616;1609:12;1571:52;1658:9;1645:23;1677:31;1702:5;1677:31;:::i;2107:127::-;2168:10;2163:3;2159:20;2156:1;2149:31;2199:4;2196:1;2189:15;2223:4;2220:1;2213:15;2239:275;2310:2;2304:9;2375:2;2356:13;;-1:-1:-1;;2352:27:1;2340:40;;2410:18;2395:34;;2431:22;;;2392:62;2389:88;;;2457:18;;:::i;:::-;2493:2;2486:22;2239:275;;-1:-1:-1;2239:275:1:o;2519:183::-;2579:4;2612:18;2604:6;2601:30;2598:56;;;2634:18;;:::i;:::-;-1:-1:-1;2679:1:1;2675:14;2691:4;2671:25;;2519:183::o;2707:662::-;2761:5;2814:3;2807:4;2799:6;2795:17;2791:27;2781:55;;2832:1;2829;2822:12;2781:55;2868:6;2855:20;2894:4;2918:60;2934:43;2974:2;2934:43;:::i;:::-;2918:60;:::i;:::-;3012:15;;;3098:1;3094:10;;;;3082:23;;3078:32;;;3043:12;;;;3122:15;;;3119:35;;;3150:1;3147;3140:12;3119:35;3186:2;3178:6;3174:15;3198:142;3214:6;3209:3;3206:15;3198:142;;;3280:17;;3268:30;;3318:12;;;;3231;;3198:142;;;-1:-1:-1;3358:5:1;2707:662;-1:-1:-1;;;;;;2707:662:1:o;3374:1215::-;3492:6;3500;3553:2;3541:9;3532:7;3528:23;3524:32;3521:52;;;3569:1;3566;3559:12;3521:52;3609:9;3596:23;3638:18;3679:2;3671:6;3668:14;3665:34;;;3695:1;3692;3685:12;3665:34;3733:6;3722:9;3718:22;3708:32;;3778:7;3771:4;3767:2;3763:13;3759:27;3749:55;;3800:1;3797;3790:12;3749:55;3836:2;3823:16;3858:4;3882:60;3898:43;3938:2;3898:43;:::i;3882:60::-;3976:15;;;4058:1;4054:10;;;;4046:19;;4042:28;;;4007:12;;;;4082:19;;;4079:39;;;4114:1;4111;4104:12;4079:39;4138:11;;;;4158:217;4174:6;4169:3;4166:15;4158:217;;;4254:3;4241:17;4271:31;4296:5;4271:31;:::i;:::-;4315:18;;4191:12;;;;4353;;;;4158:217;;;4394:5;-1:-1:-1;;4437:18:1;;4424:32;;-1:-1:-1;;4468:16:1;;;4465:36;;;4497:1;4494;4487:12;4465:36;;4520:63;4575:7;4564:8;4553:9;4549:24;4520:63;:::i;:::-;4510:73;;;3374:1215;;;;;:::o;4594:456::-;4671:6;4679;4687;4740:2;4728:9;4719:7;4715:23;4711:32;4708:52;;;4756:1;4753;4746:12;4708:52;4795:9;4782:23;4814:31;4839:5;4814:31;:::i;:::-;4864:5;-1:-1:-1;4921:2:1;4906:18;;4893:32;4934:33;4893:32;4934:33;:::i;:::-;4594:456;;4986:7;;-1:-1:-1;;;5040:2:1;5025:18;;;;5012:32;;4594:456::o;5055:180::-;5114:6;5167:2;5155:9;5146:7;5142:23;5138:32;5135:52;;;5183:1;5180;5173:12;5135:52;-1:-1:-1;5206:23:1;;5055:180;-1:-1:-1;5055:180:1:o;5834:118::-;5920:5;5913:13;5906:21;5899:5;5896:32;5886:60;;5942:1;5939;5932:12;5957:382;6022:6;6030;6083:2;6071:9;6062:7;6058:23;6054:32;6051:52;;;6099:1;6096;6089:12;6051:52;6138:9;6125:23;6157:31;6182:5;6157:31;:::i;:::-;6207:5;-1:-1:-1;6264:2:1;6249:18;;6236:32;6277:30;6236:32;6277:30;:::i;:::-;6326:7;6316:17;;;5957:382;;;;;:::o;6344:316::-;6421:6;6429;6437;6490:2;6478:9;6469:7;6465:23;6461:32;6458:52;;;6506:1;6503;6496:12;6458:52;-1:-1:-1;;6529:23:1;;;6599:2;6584:18;;6571:32;;-1:-1:-1;6650:2:1;6635:18;;;6622:32;;6344:316;-1:-1:-1;6344:316:1:o;6665:388::-;6733:6;6741;6794:2;6782:9;6773:7;6769:23;6765:32;6762:52;;;6810:1;6807;6800:12;6762:52;6849:9;6836:23;6868:31;6893:5;6868:31;:::i;:::-;6918:5;-1:-1:-1;6975:2:1;6960:18;;6947:32;6988:33;6947:32;6988:33;:::i;7058:687::-;7160:6;7168;7176;7184;7192;7200;7253:3;7241:9;7232:7;7228:23;7224:33;7221:53;;;7270:1;7267;7260:12;7221:53;7309:9;7296:23;7328:31;7353:5;7328:31;:::i;:::-;7378:5;-1:-1:-1;7430:2:1;7415:18;;7402:32;;-1:-1:-1;7481:2:1;7466:18;;7453:32;;-1:-1:-1;7537:2:1;7522:18;;7509:32;7585:4;7572:18;;7560:31;;7550:59;;7605:1;7602;7595:12;7550:59;7058:687;;;;-1:-1:-1;7058:687:1;;7682:3;7667:19;;7654:33;;7734:3;7719:19;;;7706:33;;-1:-1:-1;7058:687:1;-1:-1:-1;;7058:687:1:o;7750:419::-;7817:6;7825;7878:2;7866:9;7857:7;7853:23;7849:32;7846:52;;;7894:1;7891;7884:12;7846:52;7933:9;7920:23;7952:31;7977:5;7952:31;:::i;:::-;8002:5;-1:-1:-1;8059:2:1;8044:18;;8031:32;8107:10;8094:24;;8082:37;;8072:65;;8133:1;8130;8123:12;8442:380;8521:1;8517:12;;;;8564;;;8585:61;;8639:4;8631:6;8627:17;8617:27;;8585:61;8692:2;8684:6;8681:14;8661:18;8658:38;8655:161;;;8738:10;8733:3;8729:20;8726:1;8719:31;8773:4;8770:1;8763:15;8801:4;8798:1;8791:15;8655:161;;8442:380;;;:::o;8827:356::-;9029:2;9011:21;;;9048:18;;;9041:30;9107:34;9102:2;9087:18;;9080:62;9174:2;9159:18;;8827:356::o;9188:402::-;9390:2;9372:21;;;9429:2;9409:18;;;9402:30;9468:34;9463:2;9448:18;;9441:62;-1:-1:-1;;;9534:2:1;9519:18;;9512:36;9580:3;9565:19;;9188:402::o;10801:127::-;10862:10;10857:3;10853:20;10850:1;10843:31;10893:4;10890:1;10883:15;10917:4;10914:1;10907:15;10933:127;10994:10;10989:3;10985:20;10982:1;10975:31;11025:4;11022:1;11015:15;11049:4;11046:1;11039:15;11065:135;11104:3;-1:-1:-1;;11125:17:1;;11122:43;;;11145:18;;:::i;:::-;-1:-1:-1;11192:1:1;11181:13;;11065:135::o;11205:168::-;11245:7;11311:1;11307;11303:6;11299:14;11296:1;11293:21;11288:1;11281:9;11274:17;11270:45;11267:71;;;11318:18;;:::i;:::-;-1:-1:-1;11358:9:1;;11205:168::o;11378:127::-;11439:10;11434:3;11430:20;11427:1;11420:31;11470:4;11467:1;11460:15;11494:4;11491:1;11484:15;11510:120;11550:1;11576;11566:35;;11581:18;;:::i;:::-;-1:-1:-1;11615:9:1;;11510:120::o;12862:221::-;12901:4;12930:10;12990;;;;12960;;13012:12;;;13009:38;;;13027:18;;:::i;:::-;13064:13;;12862:221;-1:-1:-1;;;12862:221:1:o;13088:191::-;13127:1;13153:10;13190:2;13187:1;13183:10;13212:3;13202:37;;13219:18;;:::i;:::-;13257:10;;13253:20;;;;;13088:191;-1:-1:-1;;13088:191:1:o;13284:128::-;13324:3;13355:1;13351:6;13348:1;13345:13;13342:39;;;13361:18;;:::i;:::-;-1:-1:-1;13397:9:1;;13284:128::o;14487:184::-;14557:6;14610:2;14598:9;14589:7;14585:23;14581:32;14578:52;;;14626:1;14623;14616:12;14578:52;-1:-1:-1;14649:16:1;;14487:184;-1:-1:-1;14487:184:1:o;14955:245::-;15022:6;15075:2;15063:9;15054:7;15050:23;15046:32;15043:52;;;15091:1;15088;15081:12;15043:52;15123:9;15117:16;15142:28;15164:5;15142:28;:::i;25459:125::-;25499:4;25527:1;25524;25521:8;25518:34;;;25532:18;;:::i;:::-;-1:-1:-1;25569:9:1;;25459:125::o;26645:251::-;26715:6;26768:2;26756:9;26747:7;26743:23;26739:32;26736:52;;;26784:1;26781;26774:12;26736:52;26816:9;26810:16;26835:31;26860:5;26835:31;:::i;26901:980::-;27163:4;27211:3;27200:9;27196:19;27242:6;27231:9;27224:25;27268:2;27306:6;27301:2;27290:9;27286:18;27279:34;27349:3;27344:2;27333:9;27329:18;27322:31;27373:6;27408;27402:13;27439:6;27431;27424:22;27477:3;27466:9;27462:19;27455:26;;27516:2;27508:6;27504:15;27490:29;;27537:1;27547:195;27561:6;27558:1;27555:13;27547:195;;;27626:13;;-1:-1:-1;;;;;27622:39:1;27610:52;;27717:15;;;;27682:12;;;;27658:1;27576:9;27547:195;;;-1:-1:-1;;;;;;;27798:32:1;;;;27793:2;27778:18;;27771:60;-1:-1:-1;;;27862:3:1;27847:19;27840:35;27759:3;26901:980;-1:-1:-1;;;26901:980:1:o;28498:306::-;28586:6;28594;28602;28655:2;28643:9;28634:7;28630:23;28626:32;28623:52;;;28671:1;28668;28661:12;28623:52;28700:9;28694:16;28684:26;;28750:2;28739:9;28735:18;28729:25;28719:35;;28794:2;28783:9;28779:18;28773:25;28763:35;;28498:306;;;;;:::o;28809:228::-;28848:3;28876:10;28913:2;28910:1;28906:10;28943:2;28940:1;28936:10;28974:3;28970:2;28966:12;28961:3;28958:21;28955:47;;;28982:18;;:::i;:::-;29018:13;;28809:228;-1:-1:-1;;;;28809:228:1:o

Swarm Source

ipfs://978f9ba368807d6ca36bd58b6f12b9cd953fe8e98061d85d3ec5d37eef4217af
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.