Contract 0x0c4b3e1ba4Ef62B62AB2DBA4A2aA28d50e176B85

 
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x6ecb3e519d0e302284c437db5139e3adce1fa1aa5f6898cff24a05df1f24567e0x61010060235113002022-01-09 8:42:11512 days 12 hrs ago0x236eccab8cdcfedb099de85c4060024ba3ce4d46 IN  Create: SigmaControllerV10 MATIC0.1699974535
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SigmaControllerV1

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license
File 1 of 18 : ControllerConstants.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;


contract ControllerConstants {
  // Minimum number of tokens in an index.
  uint256 public constant MIN_INDEX_SIZE = 2;

  // Maximum number of tokens in an index.
  uint256 public constant MAX_INDEX_SIZE = 10;

  // Minimum balance for a token (only applied at initialization)
  uint256 public constant MIN_BALANCE = 1e6;

  // Identifier for the pool initializer implementation on the proxy manager.
  bytes32 public constant INITIALIZER_IMPLEMENTATION_ID = keccak256("SigmaPoolInitializerV1.sol");

  // Identifier for the unbound token seller implementation on the proxy manager.
  bytes32 public constant SELLER_IMPLEMENTATION_ID = keccak256("SigmaUnboundTokenSellerV1.sol");

  // Identifier for the index pool implementation on the proxy manager.
  bytes32 public constant POOL_IMPLEMENTATION_ID = keccak256("SigmaIndexPoolV1.sol");

  // Time between reweigh/reindex calls.
  uint256 public constant POOL_REWEIGH_DELAY = 1 weeks;

  // The number of reweighs which occur before a pool is re-indexed.
  uint8 public constant REWEIGHS_BEFORE_REINDEX = 3;

  // TWAP parameters for assessing current price
  uint32 public constant SHORT_TWAP_MIN_TIME_ELAPSED = 20 minutes;
  uint32 public constant SHORT_TWAP_MAX_TIME_ELAPSED = 2 days;
}

File 2 of 18 : ScoredTokenLists.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

/* ========== Internal Libraries ========== */
import "../lib/ScoreLibrary.sol";

/* ========== Internal Interfaces ========== */
import "../interfaces/ICirculatingMarketCapOracle.sol";
import "../interfaces/IScoringStrategy.sol";

/* ========== Internal Inheritance ========== */
import "../OwnableProxy.sol";


/**
 * @title ScoredTokenLists
 * @author d1ll0n
 *
 * @dev This contract stores token lists sorted and filtered using arbitrary scoring strategies.
 *
 * Each token list contains an array of tokens, a scoring strategy address, minimum and maximum
 * scores for the list, and a mapping for which tokens are included.
 *
 * A scoring strategy is a smart contract which implements the `getTokenScores`, which scores
 * tokens using an arbitrary methodology.
 *
 * Token lists are sorted in descending order by the scores returned by the list's scoring strategy,
 * and filtered according to the minimum/maximum scores.
 *
 * The contract owner can create a new token list with a metadata hash used to query
 * additional details about its purpose and inclusion criteria from IPFS.
 *
 * The owner can add and remove tokens from the lists.
 */
contract ScoredTokenLists is OwnableProxy {
  using ScoreLibrary for address[];
  using ScoreLibrary for uint256[];
  using ScoreLibrary for uint256;

/* ==========  Constants  ========== */
  // Maximum number of tokens in a token list
  uint256 public constant MAX_LIST_TOKENS = 25;

  // Uniswap TWAP oracle
  IIndexedUniswapV2Oracle public immutable uniswapOracle;

/* ==========  Events  ========== */

  /** @dev Emitted when a new token list is created. */
  event TokenListAdded(
    uint256 listID,
    bytes32 metadataHash,
    address scoringStrategy,
    uint128 minimumScore,
    uint128 maximumScore
  );

  /** @dev Emitted when a token list is sorted and filtered. */
  event TokenListSorted(uint256 listID);

  /** @dev Emitted when a token is added to a list. */
  event TokenAdded(address token, uint256 listID);

  /** @dev Emitted when a token is removed from a list. */
  event TokenRemoved(address token, uint256 listID);

/* ==========  Structs  ========== */

  /**
   * @dev Token list storage structure.
   * @param minimumScore Minimum market cap for included tokens
   * @param maximumScore Maximum market cap for included tokens
   * @param scoringStrategy Address of the scoring strategy contract used
   * @param tokens Array of included tokens
   * @param isIncludedToken Mapping of included tokens
   */
  struct TokenList {
    uint128 minimumScore;
    uint128 maximumScore;
    address scoringStrategy;
    address[] tokens;
    mapping(address => bool) isIncludedToken;
  }

/* ==========  Storage  ========== */

  // Chainlink or other circulating market cap oracle
  ICirculatingMarketCapOracle public circulatingMarketCapOracle;

  // Number of categories that exist.
  uint256 public tokenListCount;
  mapping(uint256 => TokenList) internal _lists;

/* ========== Modifiers ========== */

  modifier validTokenList(uint256 listID) {
    require(listID <= tokenListCount && listID > 0, "ERR_LIST_ID");
    _;
  }

/* ==========  Constructor  ========== */

  /**
   * @dev Deploy the controller and configure the addresses
   * of the related contracts.
   */
  constructor(IIndexedUniswapV2Oracle _oracle) public OwnableProxy() {
    uniswapOracle = _oracle;
  }

/* ==========  Configuration  ========== */

  /**
   * @dev Initialize the categories with the owner address.
   * This sets up the contract which is deployed as a singleton proxy.
   */
  function initialize() public virtual {
    _initializeOwnership();
  }

/* ==========  Permissioned List Management  ========== */

  /**
   * @dev Creates a new token list.
   *
   * @param metadataHash Hash of metadata about the token list which can
   * be distributed on IPFS.
   */
  function createTokenList(
    bytes32 metadataHash,
    address scoringStrategy,
    uint128 minimumScore,
    uint128 maximumScore
  )
    external
    onlyOwner
  {
    require(minimumScore > 0, "ERR_NULL_MIN_CAP");
    require(maximumScore > minimumScore, "ERR_MAX_CAP");
    require(scoringStrategy != address(0), "ERR_NULL_ADDRESS");
    uint256 listID = ++tokenListCount;
    TokenList storage list = _lists[listID];
    list.scoringStrategy = scoringStrategy;
    list.minimumScore = minimumScore;
    list.maximumScore = maximumScore;
    emit TokenListAdded(listID, metadataHash, scoringStrategy, minimumScore, maximumScore);
  }

  /**
   * @dev Adds a new token to a token list.
   *
   * @param listID Token list identifier.
   * @param token Token to add to the list.
   */
  function addToken(uint256 listID, address token) external onlyOwner validTokenList(listID) {
    TokenList storage list = _lists[listID];
    require(
      list.tokens.length < MAX_LIST_TOKENS,
      "ERR_MAX_LIST_TOKENS"
    );
    _addToken(list, token);
    uniswapOracle.updatePrice(token);
    emit TokenAdded(token, listID);
  }

  /**
   * @dev Add tokens to a token list.
   *
   * @param listID Token list identifier.
   * @param tokens Array of tokens to add to the list.
   */
  function addTokens(uint256 listID, address[] calldata tokens)
    external
    onlyOwner
    validTokenList(listID)
  {
    TokenList storage list = _lists[listID];
    require(
      list.tokens.length + tokens.length <= MAX_LIST_TOKENS,
      "ERR_MAX_LIST_TOKENS"
    );
    for (uint256 i = 0; i < tokens.length; i++) {
      address token = tokens[i];
      _addToken(list, token);
      emit TokenAdded(token, listID);
    }
    uniswapOracle.updatePrices(tokens);
  }

  /**
   * @dev Remove token from a token list.
   *
   * @param listID Token list identifier.
   * @param token Token to remove from the list.
   */
  function removeToken(uint256 listID, address token) external onlyOwner validTokenList(listID) {
    TokenList storage list = _lists[listID];
    uint256 i = 0;
    uint256 len = list.tokens.length;
    require(len > 0, "ERR_EMPTY_LIST");
    require(list.isIncludedToken[token], "ERR_TOKEN_NOT_BOUND");
    list.isIncludedToken[token] = false;
    for (; i < len; i++) {
      if (list.tokens[i] == token) {
        uint256 last = len - 1;
        if (i != last) {
          address lastToken = list.tokens[last];
          list.tokens[i] = lastToken;
        }
        list.tokens.pop();
        emit TokenRemoved(token, listID);
        return;
      }
    }
  }

/* ==========  Public List Updates  ========== */

  /**
   * @dev Updates the prices on the Uniswap oracle for all the tokens in a token list.
   */
  function updateTokenPrices(uint256 listID)
    external
    validTokenList(listID)
    returns (bool[] memory pricesUpdated)
  {
    pricesUpdated = uniswapOracle.updatePrices(_lists[listID].tokens);
  }

  /**
   * @dev Returns the tokens and scores in the token list for `listID` after
   * sorting and filtering the tokens according to the list's configuration.
   */
  function sortAndFilterTokens(uint256 listID)
    external
    validTokenList(listID)
  {
    TokenList storage list = _lists[listID];
    address[] memory tokens = list.tokens;
    uint256[] memory marketCaps = IScoringStrategy(list.scoringStrategy).getTokenScores(tokens);
    address[] memory removedTokens = tokens.sortAndFilterReturnRemoved(
      marketCaps,
      list.minimumScore,
      list.maximumScore
    );
    _lists[listID].tokens = tokens;
    for (uint256 i = 0; i < removedTokens.length; i++) {
      address token = removedTokens[i];
      list.isIncludedToken[token] = false;
      emit TokenRemoved(token, listID);
    }
  }


/* ==========  Score Queries  ========== */

  /**
   * @dev Returns the tokens and market caps for `catego
   */
  function getSortedAndFilteredTokensAndScores(uint256 listID)
    public
    view
    validTokenList(listID)
    returns (
      address[] memory tokens,
      uint256[] memory scores
    )
  {
    TokenList storage list = _lists[listID];
    tokens = list.tokens;
    scores = IScoringStrategy(list.scoringStrategy).getTokenScores(tokens);
    tokens.sortAndFilter(
      scores,
      list.minimumScore,
      list.maximumScore
    );
  }

/* ==========  Token List Queries  ========== */

  /**
   * @dev Returns boolean stating whether `token` is a member of the list `listID`.
   */
  function isTokenInlist(uint256 listID, address token)
    external
    view
    validTokenList(listID)
    returns (bool)
  {
    return _lists[listID].isIncludedToken[token];
  }

  /**
   * @dev Returns the array of tokens in a list.
   */
  function getTokenList(uint256 listID)
    external
    view
    validTokenList(listID)
    returns (address[] memory tokens)
  {
    tokens = _lists[listID].tokens;
  }

  /**
   * @dev Returns the top `count` tokens and market caps in the list for `listID`
   * after sorting and filtering the tokens according to the list's configuration.
   */
  function getTopTokensAndScores(uint256 listID, uint256 count)
    public
    view
    validTokenList(listID)
    returns (
      address[] memory tokens,
      uint256[] memory scores
    )
  {
    (tokens, scores) = getSortedAndFilteredTokensAndScores(listID);
    require(count <= tokens.length, "ERR_LIST_SIZE");
    assembly {
      mstore(tokens, count)
      mstore(scores, count)
    }
  }

  /**
   * @dev Query the configuration values for a token list.
   *
   * @param listID Identifier for the token list
   * @return scoringStrategy Address of the scoring strategy contract used
   * @return minimumScore Minimum market cap for an included token
   * @return maximumScore Maximum market cap for an included token
   */
  function getTokenListConfig(uint256 listID)
    external
    view
    validTokenList(listID)
    returns (
      address scoringStrategy,
      uint128 minimumScore,
      uint128 maximumScore
    )
  {
    TokenList storage list = _lists[listID];
    scoringStrategy = list.scoringStrategy;
    minimumScore = list.minimumScore;
    maximumScore = list.maximumScore;
  }

  function getTokenScores(uint256 listID, address[] memory tokens)
    public
    view
    validTokenList(listID)
    returns (uint256[] memory scores)
  {
    scores = IScoringStrategy(_lists[listID].scoringStrategy).getTokenScores(tokens);
  }

/* ==========  Token List Utility Functions  ========== */

  /**
   * @dev Adds a new token to a list.
   */
  function _addToken(TokenList storage list, address token) internal {
    require(!list.isIncludedToken[token], "ERR_TOKEN_BOUND");
    list.isIncludedToken[token] = true;
    list.tokens.push(token);
  }
}

interface IIndexedUniswapV2Oracle {

  function updatePrice(address token) external returns (bool);

  function updatePrices(address[] calldata tokens) external returns (bool[] memory);

  function computeAverageEthForTokens(
    address[] calldata tokens,
    uint256[] calldata tokenAmounts,
    uint256 minTimeElapsed,
    uint256 maxTimeElapsed
  ) external view returns (uint256[] memory);

  function computeAverageEthForTokens(
    address token,
    uint256 tokenAmount,
    uint256 minTimeElapsed,
    uint256 maxTimeElapsed
  ) external view returns (uint256);

  function computeAverageTokensForEth(
    address[] calldata tokens,
    uint256[] calldata ethAmounts,
    uint256 minTimeElapsed,
    uint256 maxTimeElapsed
  ) external view returns (uint256[] memory);

  function computeAverageTokensForEth(
    address token,
    uint256 ethAmount,
    uint256 minTimeElapsed,
    uint256 maxTimeElapsed
  ) external view returns (uint256);
}

File 3 of 18 : ScoreLibrary.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;

/* ========== External Libraries ========== */
import "@openzeppelin/contracts/math/SafeMath.sol";


library ScoreLibrary {
  using SafeMath for uint256;

  // Default total weight for a pool.
  uint256 internal constant WEIGHT_MULTIPLIER = 25e18;

  function computeProportionalAmounts(uint256 total, uint256[] memory scores)
    internal
    pure
    returns(uint256[] memory values)
  {
    uint256 sum;
    uint256 len = scores.length;
    values = new uint256[](len);
    for (uint256 i = 0; i < len; i++) {
      sum = sum.add(scores[i]);
    }
    uint256 denormalizedSum = sum * 1e18;
    uint256 denormalizedTotal = total * 1e18;
    for (uint256 i = 0; i < len; i++) {
      values[i] = scores[i].mul(denormalizedTotal).div(denormalizedSum);
    }
  }

  function computeDenormalizedWeights(uint256[] memory values)
    internal
    pure
    returns (uint96[] memory weights)
  {
    uint256 sum;
    uint256 len = values.length;
    weights = new uint96[](len);
    for (uint256 i = 0; i < len; i++) {
      sum = sum.add(values[i]);
    }
    for (uint256 i = 0; i < len; i++) {
      weights[i] = _safeUint96(values[i].mul(WEIGHT_MULTIPLIER).div(sum));
    }
  }

  /**
   * @dev Given a list of tokens and their scores, sort by scores
   * in descending order, and filter out the tokens with scores that
   * are not within the min/max bounds provided.
   */
  function sortAndFilter(
    address[] memory tokens,
    uint256[] memory scores,
    uint256 minimumScore,
    uint256 maximumScore
  ) internal pure {
    uint256 len = tokens.length;
    for (uint256 i = 0; i < len; i++) {
      uint256 cap = scores[i];
      address token = tokens[i];
      if (cap > maximumScore || cap < minimumScore) {
        token = tokens[--len];
        cap = scores[len];
        scores[i] = cap;
        tokens[i] = token;
        i--;
        continue;
      }
      uint256 j = i - 1;
      while (int(j) >= 0 && scores[j] < cap) {
        scores[j + 1] = scores[j];
        tokens[j + 1] = tokens[j];
        j--;
      }
      scores[j + 1] = cap;
      tokens[j + 1] = token;
    }
    if (len != tokens.length) {
      assembly {
        mstore(tokens, len)
        mstore(scores, len)
      }
    }
  }

  /**
   * @dev Given a list of tokens and their scores, sort by scores
   * in descending order, and filter out the tokens with scores that
   * are not within the min/max bounds provided.
   * This function also returns the list of removed tokens.
   */
  function sortAndFilterReturnRemoved(
    address[] memory tokens,
    uint256[] memory scores,
    uint256 minimumScore,
    uint256 maximumScore
  ) internal pure returns (address[] memory removed) {
    uint256 removedIndex = 0;
    uint256 len = tokens.length;
    removed = new address[](len);
    for (uint256 i = 0; i < len; i++) {
      uint256 cap = scores[i];
      address token = tokens[i];
      if (cap > maximumScore || cap < minimumScore) {
        removed[removedIndex++] = token;
        token = tokens[--len];
        cap = scores[len];
        scores[i] = cap;
        tokens[i] = token;
        i--;
        continue;
      }
      uint256 j = i - 1;
      while (int(j) >= 0 && scores[j] < cap) {
        scores[j + 1] = scores[j];
        tokens[j + 1] = tokens[j];
        j--;
      }
      scores[j + 1] = cap;
      tokens[j + 1] = token;
    }
    if (len != tokens.length) {
      assembly {
        mstore(tokens, len)
        mstore(scores, len)
        mstore(removed, removedIndex)
      }
    }
  }

  function _safeUint96(uint256 x) internal pure returns (uint96 y) {
    y = uint96(x);
    require(y == x, "ERR_MAX_UINT96");
  }
}

File 4 of 18 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @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;
    }
}

File 5 of 18 : ICirculatingMarketCapOracle.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;


interface ICirculatingMarketCapOracle {
  function getCirculatingMarketCap(address) external view returns (uint256);

  function getCirculatingMarketCaps(address[] calldata) external view returns (uint256[] memory);

  function updateCirculatingMarketCaps(address[] calldata) external;
}

File 6 of 18 : IScoringStrategy.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;


interface IScoringStrategy {
  function getTokenScores(address[] calldata tokens) external view returns (uint256[] memory scores);
}

File 7 of 18 : OwnableProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/GSN/Context.sol";


/**
 * @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.
 *
 * This is a modified implementation of OpenZeppelin's Ownable.sol.
 * The modifications allow the contract to be inherited by a proxy's logic contract.
 * Any owner-only functions on the base implementation will be unusable.
 *
 * By default, the owner account will be a null address which can be set by the
 * first call to {initializeOwner}. 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. It also makes the function {initializeOwner} available to be used
 * in the initialization function for the inherited contract.
 *
 * Note: This contract should only be inherited by proxy implementation contracts
 * where the implementation will only ever be used as the logic address for proxies.
 * The constructor permanently locks the owner of the implementation contract, but the
 * owner of the proxies can be configured by the first caller.
 */
contract OwnableProxy is Context {
  address private _owner;

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

  constructor() public {
    _owner = address(1);
    emit OwnershipTransferred(address(0), address(1));
  }

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

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

  /**
   * @dev Leaves the contract without owner. It will not be possible to call
   * `onlyOwner` functions anymore. Can only be called by the current owner.
   *
   * NOTE: Renouncing ownership will leave the contract without an owner,
   * thereby removing any functionality that is only available to the owner.
   */
  function renounceOwnership() public virtual onlyOwner {
    // Modified from OZ contract - sets owner to address(1) to prevent
    // _initializeOwnership from being called after ownership is revoked.
    emit OwnershipTransferred(_owner, address(1));
    _owner = address(1);
  }

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

  /**
   * @dev Initializes the contract setting the initializer as the initial owner.
   * Note: Owner address must be zero.
   */
  function _initializeOwnership() internal {
    require(_owner == address(0), "Ownable: owner has already been initialized");
    address msgSender = _msgSender();
    _owner = msgSender;
    emit OwnershipTransferred(address(0), msgSender);
  }

  /**
   * @dev Initializes the contract setting the owner to an invalid address.
   * This ensures that the contract can never be owned, and should only be used
   * in the constructor of a proxy's implementation contract.
   * Note: Owner address must be zero.
   */
  function _lockImplementationOwner() internal {
    require(_owner == address(0), "Ownable: owner has already been initialized");
    emit OwnershipTransferred(address(0), address(1));
    _owner = address(1);
  }
}

File 8 of 18 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with 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.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

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

File 9 of 18 : SigmaControllerV1.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;

/* ========== External Interfaces ========== */
import "@indexed-finance/proxies/contracts/interfaces/IDelegateCallProxyManager.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/* ========== External Libraries ========== */
import "@indexed-finance/proxies/contracts/SaltyLib.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";

/* ========== Internal Interfaces ========== */
import "../interfaces/IIndexPool.sol";
import "../interfaces/IPoolFactory.sol";
import "../interfaces/IPoolInitializer.sol";
import "../interfaces/IUnboundTokenSeller.sol";

/* ========== Internal Inheritance ========== */
import "./ScoredTokenLists.sol";
import "./ControllerConstants.sol";


/**
 * @title SigmaControllerV1
 * @author d1ll0n
 * @dev This contract is used to deploy and manage index pools.
 * It implements the methodology for rebalancing and asset selection, as well as other
 * controls such as pausing public swaps and managing fee configuration.
 *
 * ===== Pool Configuration =====
 * When an index pool is deployed, it is assigned a token list and a target size.
 *
 * The token list is the set of tokens and configuration used for selecting and weighting
 * assets, which is detailed in the documentation for the ScoredTokenLists contract.
 *
 * The size is the target number of underlying assets held by the pool, it is used to determine
 * which assets the pool will hold.
 *
 * The list's scoring strategy is used to assign weights.
 *
 * ===== Asset Selection =====
 * When the pool is deployed and when it is re-indexed, the top assets from the pool's token list
 * are selected using the index size. They are selected after sorting the token list in descending
 * order by the scores of tokens.
 *
 * ===== Rebalancing =====
 * Every week, pools are either re-weighed or re-indexed.
 * They are re-indexed once for every three re-weighs.
 * The contract owner can also force a reindex out of the normal schedule.
 *
 * Re-indexing involves re-selecting the top tokens from the pool's token list using the pool's index
 * size, assigning target weights and setting balance targets for new tokens.
 *
 * Re-weighing involves assigning target weights to only the tokens already included in the pool.
 *
 * ===== Toggling Swaps =====
 * The contract owner can set a circuitBreaker address which is allowed to toggle public swaps on index pools.
 * The contract owner also has the ability to toggle swaps.
 * 
 * ===== Fees =====
 * The contract owner can change the swap fee on index pools, and can change the premium paid on swaps in the
 * unbound token seller contracts.
 */
contract SigmaControllerV1 is ScoredTokenLists, ControllerConstants {
  using SafeMath for uint256;

/* ==========  Constants  ========== */
  // Pool factory contract
  IPoolFactory public immutable poolFactory;

  // Proxy manager & factory
  IDelegateCallProxyManager public immutable proxyManager;

  // Governance address
  address public immutable governance;

/* ==========  Events  ========== */

  /** @dev Emitted when a pool is initialized and made public. */
  event PoolInitialized(
    address pool,
    address unboundTokenSeller,
    uint256 listID,
    uint256 indexSize
  );

  /** @dev Emitted when a pool and its initializer are deployed. */
  event NewPoolInitializer(
    address pool,
    address initializer,
    uint256 listID,
    uint256 indexSize
  );

  /** @dev Emitted when a pool is reweighed. */
  event PoolReweighed(address pool);

  /** @dev Emitted when a pool is reindexed. */
  event PoolReindexed(address pool);

/* ==========  Structs  ========== */

  /**
   * @dev Data structure with metadata about an index pool.
   *
   * Includes the number of times a pool has been either reweighed
   * or re-indexed, as well as the timestamp of the last such action.
   *
   * To reweigh or re-index, the last update must have occurred at
   * least `POOL_REWEIGH_DELAY` seconds ago.
   *
   * If `++index % REWEIGHS_BEFORE_REINDEX + 1` is 0, the pool will
   * re-index, otherwise it will reweigh.
   *
   * The struct fields are assigned their respective integer sizes so
   * that solc can pack the entire struct into a single storage slot.
   * `reweighIndex` is intended to overflow, `listID` will never
   * reach 2**16, `indexSize` is capped at 10 and it is unlikely that
   * this protocol will be in use in the year 292277026596 (unix time
   * for 2**64 - 1).
   *
   * @param initialized Whether the pool has been initialized with the
   * starting balances.
   * @param listID Token list identifier for the pool.
   * @param indexSize Number of tokens the pool should hold.
   * @param reweighIndex Number of times the pool has either re-weighed or re-indexed
   * @param lastReweigh Timestamp of last pool re-weigh or re-index
   */
  struct IndexPoolMeta {
    bool initialized;
    uint16 listID;
    uint8 indexSize;
    uint8 reweighIndex;
    uint64 lastReweigh;
  }

/* ==========  Storage  ========== */

  // Default slippage rate for token seller contracts.
  uint8 public defaultSellerPremium;

  // Metadata about index pools
  mapping(address => IndexPoolMeta) public indexPoolMetadata;

  // Address able to halt swaps
  address public circuitBreaker;

  // Exit fee recipient for the index pools
  address public defaultExitFeeRecipient;

/* ========== Modifiers ========== */

  modifier isInitializedPool(address poolAddress) {
    require(
      indexPoolMetadata[poolAddress].initialized,
      "ERR_POOL_NOT_FOUND"
    );
    _;
  }

  modifier onlyInitializer(address poolAddress) {
    require(
      msg.sender == computeInitializerAddress(poolAddress),
      "ERR_NOT_PRE_DEPLOY_POOL"
    );
    _;
  }

  modifier onlyGovernance() {
    require(msg.sender == governance, "ERR_NOT_GOVERNANCE");
    _;
  }

/* ==========  Constructor  ========== */

  /**
   * @dev Deploy the controller and configure the addresses
   * of the related accounts.
   */
  constructor(
    IIndexedUniswapV2Oracle uniswapOracle_,
    IPoolFactory poolFactory_,
    IDelegateCallProxyManager proxyManager_,
    address governance_
  )
    public
    ScoredTokenLists(uniswapOracle_)
  {
    poolFactory = poolFactory_;
    proxyManager = proxyManager_;
    governance = governance_;
  }

/* ==========  Initializer  ========== */

  /**
   * @dev Initialize the controller with the owner address and default seller premium.
   * This sets up the controller which is deployed as a singleton proxy.
   */
  function initialize(address circuitBreaker_) public {
    super.initialize();
    defaultSellerPremium = 2;
    circuitBreaker = circuitBreaker_;
  }

/* ==========  Configuration  ========== */

  /**
   * @dev Sets the default premium rate for token seller contracts.
   */
  function setDefaultSellerPremium(uint8 _defaultSellerPremium) external onlyOwner {
    require(_defaultSellerPremium > 0 && _defaultSellerPremium < 20, "ERR_PREMIUM");
    defaultSellerPremium = _defaultSellerPremium;
  }

  /**
   * @dev Sets the circuit breaker address allowed to toggle public swaps.
   */
  function setCircuitBreaker(address circuitBreaker_) external onlyOwner {
    circuitBreaker = circuitBreaker_;
  }

  /**
   * @dev Sets the default exit fee recipient for new pools.
   */
  function setDefaultExitFeeRecipient(address defaultExitFeeRecipient_) external onlyGovernance {
    require(defaultExitFeeRecipient_ != address(0), "ERR_NULL_ADDRESS");
    defaultExitFeeRecipient = defaultExitFeeRecipient_;
  }

/* ==========  Pool Deployment  ========== */

  /**
   * @dev Deploys an index pool and a pool initializer.
   * The initializer contract is a pool with specific token
   * balance targets which gives pool tokens in the finished
   * pool to users who provide the underlying tokens needed
   * to initialize it.
   */
  function prepareIndexPool(
    uint256 listID,
    uint256 indexSize,
    uint256 initialWethValue,
    string calldata name,
    string calldata symbol
  )
    external
    onlyOwner
    returns (address poolAddress, address initializerAddress)
  {
    require(indexSize >= MIN_INDEX_SIZE, "ERR_MIN_INDEX_SIZE");
    require(indexSize <= MAX_INDEX_SIZE, "ERR_MAX_INDEX_SIZE");
    require(initialWethValue < uint144(-1), "ERR_MAX_UINT144");

    poolAddress = poolFactory.deployPool(
      POOL_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(listID, indexSize))
    );
    IIndexPool(poolAddress).configure(address(this), name, symbol);

    indexPoolMetadata[poolAddress] = IndexPoolMeta({
      initialized: false,
      listID: uint16(listID),
      indexSize: uint8(indexSize),
      lastReweigh: 0,
      reweighIndex: 0
    });

    initializerAddress = proxyManager.deployProxyManyToOne(
      INITIALIZER_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(poolAddress))
    );

    IPoolInitializer initializer = IPoolInitializer(initializerAddress);

    // Get the initial tokens and balances for the pool.
    (address[] memory tokens, uint256[] memory balances) = getInitialTokensAndBalances(
      listID,
      indexSize,
      uint144(initialWethValue)
    );

    initializer.initialize(address(this), poolAddress, tokens, balances);

    emit NewPoolInitializer(
      poolAddress,
      initializerAddress,
      listID,
      indexSize
    );
  }

  /**
   * @dev Initializes a pool which has been deployed but not initialized
   * and transfers the underlying tokens from the initialization pool to
   * the actual pool.
   *
   * The actual weights assigned to tokens is calculated based on the
   * relative values of the acquired balances, rather than the initial
   * weights computed from the token scores.
   */
  function finishPreparedIndexPool(
    address poolAddress,
    address[] calldata tokens,
    uint256[] calldata balances
  )
    external
    onlyInitializer(poolAddress)
  {
    uint256 len = tokens.length;
    require(balances.length == len, "ERR_ARR_LEN");

    IndexPoolMeta memory meta = indexPoolMetadata[poolAddress];
    require(!meta.initialized, "ERR_INITIALIZED");

    uint256[] memory ethValues = uniswapOracle.computeAverageEthForTokens(
      tokens,
      balances,
      SHORT_TWAP_MIN_TIME_ELAPSED,
      SHORT_TWAP_MAX_TIME_ELAPSED
    );
    uint96[] memory denormalizedWeights = ethValues.computeDenormalizedWeights();

    address sellerAddress = proxyManager.deployProxyManyToOne(
      SELLER_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(poolAddress))
    );

    IIndexPool(poolAddress).initialize(
      tokens,
      balances,
      denormalizedWeights,
      msg.sender,
      sellerAddress,
      defaultExitFeeRecipient
    );

    IUnboundTokenSeller(sellerAddress).initialize(
      address(this),
      poolAddress,
      defaultSellerPremium
    );

    meta.lastReweigh = uint64(now);
    meta.initialized = true;
    indexPoolMetadata[poolAddress] = meta;

    emit PoolInitialized(
      poolAddress,
      sellerAddress,
      meta.listID,
      meta.indexSize
    );
  }

/* ==========  Pool Management  ========== */

  /**
   * @dev Sets the premium rate on `sellerAddress` to the given rate.
   */
  function updateSellerPremium(address tokenSeller, uint8 premiumPercent) external onlyOwner {
    require(premiumPercent > 0 && premiumPercent < 20, "ERR_PREMIUM");
    IUnboundTokenSeller(tokenSeller).setPremiumPercent(premiumPercent);
  }

  /**
   * @dev Sets the controller on an index pool.
   */
  function setController(address poolAddress, address controller) external isInitializedPool(poolAddress) onlyGovernance {
    IIndexPool(poolAddress).setController(controller);
  }

  /**
   * @dev Sets the exit fee recipient for an existing pool.
   */
  function setExitFeeRecipient(address poolAddress, address exitFeeRecipient) external isInitializedPool(poolAddress) onlyGovernance {
    IIndexPool(poolAddress).setExitFeeRecipient(exitFeeRecipient);
  }

  /**
   * @dev Sets the exit fee recipient on multiple existing pools.
   */
  function setExitFeeRecipient(address[] calldata poolAddresses, address exitFeeRecipient) external onlyGovernance {
    for (uint256 i = 0; i < poolAddresses.length; i++) {
      address poolAddress = poolAddresses[i];
      require(indexPoolMetadata[poolAddress].initialized, "ERR_POOL_NOT_FOUND");
      // No not-null requirement - already in pool function.
      IIndexPool(poolAddress).setExitFeeRecipient(exitFeeRecipient);
    }
  }

  /**
   * @dev Sets the swap fee on multiple index pools.
   */
  function setSwapFee(address poolAddress, uint256 swapFee) external onlyGovernance isInitializedPool(poolAddress) {
    IIndexPool(poolAddress).setSwapFee(swapFee);
  }

  /**
   * @dev Sets the swap fee on an index pool.
   */
  function setSwapFee(address[] calldata poolAddresses, uint256 swapFee) external onlyGovernance {
    for (uint256 i = 0; i < poolAddresses.length; i++) {
      address poolAddress = poolAddresses[i];
      require(indexPoolMetadata[poolAddress].initialized, "ERR_POOL_NOT_FOUND");
      // No not-null requirement - already in pool function.
      IIndexPool(poolAddress).setSwapFee(swapFee);
    }
  }

  /**
   * @dev Updates the minimum balance of an uninitialized token, which is
   * useful when the token's price on the pool is too low relative to
   * external prices for people to trade it in.
   */
  function updateMinimumBalance(address pool, address tokenAddress) external isInitializedPool(address(pool)) {
    IIndexPool.Record memory record = IIndexPool(pool).getTokenRecord(tokenAddress);
    require(!record.ready, "ERR_TOKEN_READY");
    uint256 poolValue = _estimatePoolValue(pool);
    uint256 minimumBalance = uniswapOracle.computeAverageTokensForEth(
      tokenAddress,
      poolValue / 100,
      SHORT_TWAP_MIN_TIME_ELAPSED,
      SHORT_TWAP_MAX_TIME_ELAPSED
    );
    IIndexPool(pool).setMinimumBalance(tokenAddress, minimumBalance);
  }

  /**
   * @dev Delegates a comp-like governance token from an index pool to a provided address.
   */
  function delegateCompLikeTokenFromPool(
    address pool,
    address token,
    address delegatee
  )
    external
    onlyOwner
    isInitializedPool(pool)
  {
    IIndexPool(pool).delegateCompLikeToken(token, delegatee);
  }

  /**
   * @dev Enable/disable public swaps on an index pool.
   * Callable by the contract owner and the `circuitBreaker` address.
   */
  function setPublicSwap(address indexPool_, bool publicSwap) external isInitializedPool(indexPool_) {
    require(
      msg.sender == circuitBreaker || msg.sender == owner(),
      "ERR_NOT_AUTHORIZED"
    );
    IIndexPool(indexPool_).setPublicSwap(publicSwap);
  }

/* ==========  Pool Rebalance Actions  ========== */

  /**
   * @dev Re-indexes a pool by setting the underlying assets to the top
   * tokens in its candidates list by score.
   */
  function reindexPool(address poolAddress) external {
    IndexPoolMeta storage meta = indexPoolMetadata[poolAddress];
    require(meta.initialized, "ERR_POOL_NOT_FOUND");
    require(
      now - meta.lastReweigh >= POOL_REWEIGH_DELAY,
      "ERR_POOL_REWEIGH_DELAY"
    );
    require(
      (++meta.reweighIndex % (REWEIGHS_BEFORE_REINDEX + 1)) == 0,
      "ERR_REWEIGH_INDEX"
    );
    _reindexPool(meta, poolAddress);
  }

  function forceReindexPool(address poolAddress) external onlyOwner {
    IndexPoolMeta storage meta = indexPoolMetadata[poolAddress];
    uint8 divisor = REWEIGHS_BEFORE_REINDEX + 1;
    uint8 remainder = ++meta.reweighIndex % divisor;

    meta.reweighIndex += divisor - remainder;
    _reindexPool(meta, poolAddress);
  }

  function _reindexPool(IndexPoolMeta storage meta, address poolAddress) internal {
    uint256 size = meta.indexSize;
    (address[] memory tokens, uint256[] memory scores) = getTopTokensAndScores(meta.listID, size);
    uint256 wethValue = _estimatePoolValue(poolAddress);
    uint256 minValue = wethValue / 100;
    uint256[] memory ethValues = new uint256[](size);
    for (uint256 i = 0; i < size; i++){
      ethValues[i] = minValue;
    }
    uint256[] memory minimumBalances = uniswapOracle.computeAverageTokensForEth(
      tokens,
      ethValues,
      SHORT_TWAP_MIN_TIME_ELAPSED,
      SHORT_TWAP_MAX_TIME_ELAPSED
    );
    uint96[] memory denormalizedWeights = scores.computeDenormalizedWeights();

    meta.lastReweigh = uint64(now);

    IIndexPool(poolAddress).reindexTokens(
      tokens,
      denormalizedWeights,
      minimumBalances
    );
    emit PoolReindexed(poolAddress);
  }

  /**
   * @dev Reweighs the assets in a pool by their scores and sets the
   * desired new weights, which will be adjusted over time.
   */
  function reweighPool(address poolAddress) external {
    IndexPoolMeta memory meta = indexPoolMetadata[poolAddress];
    require(meta.initialized, "ERR_POOL_NOT_FOUND");

    require(
      now - meta.lastReweigh >= POOL_REWEIGH_DELAY,
      "ERR_POOL_REWEIGH_DELAY"
    );

    require(
      (++meta.reweighIndex % (REWEIGHS_BEFORE_REINDEX + 1)) != 0,
      "ERR_REWEIGH_INDEX"
    );

    TokenList storage list = _lists[meta.listID];

    address[] memory tokens = IIndexPool(poolAddress).getCurrentDesiredTokens();
    uint256[] memory scores = IScoringStrategy(list.scoringStrategy).getTokenScores(tokens);
    uint96[] memory denormalizedWeights = scores.computeDenormalizedWeights();

    meta.lastReweigh = uint64(now);
    indexPoolMetadata[poolAddress] = meta;
    IIndexPool(poolAddress).reweighTokens(tokens, denormalizedWeights);
    emit PoolReweighed(poolAddress);
  }

/* ==========  Pool Queries  ========== */

  /**
   * @dev Compute the create2 address for a pool initializer.
   */
  function computeInitializerAddress(address poolAddress)
    public
    view
    returns (address initializerAddress)
  {
    initializerAddress = SaltyLib.computeProxyAddressManyToOne(
      address(proxyManager),
      address(this),
      INITIALIZER_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(poolAddress))
    );
  }

  /**
   * @dev Compute the create2 address for a pool's unbound token seller.
   */
  function computeSellerAddress(address poolAddress)
    public
    view
    returns (address sellerAddress)
  {
    sellerAddress = SaltyLib.computeProxyAddressManyToOne(
      address(proxyManager),
      address(this),
      SELLER_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(poolAddress))
    );
  }

  /**
   * @dev Compute the create2 address for a pool.
   */
  function computePoolAddress(uint256 listID, uint256 indexSize)
    public
    view
    returns (address poolAddress)
  {
    poolAddress = SaltyLib.computeProxyAddressManyToOne(
      address(proxyManager),
      address(poolFactory),
      POOL_IMPLEMENTATION_ID,
      keccak256(abi.encodePacked(
        address(this),
        keccak256(abi.encodePacked(listID, indexSize))
      ))
    );
  }

  /**
   * @dev Queries the top `indexSize` tokens in a list from the market oracle,
   * computes their relative weights and determines the weighted balance of each
   * token to meet a specified total value.
   */
  function getInitialTokensAndBalances(
    uint256 listID,
    uint256 indexSize,
    uint256 wethValue
  )
    public
    view
    returns (
      address[] memory tokens,
      uint256[] memory balances
    )
  {
    uint256[] memory scores;
    (tokens, scores) = getTopTokensAndScores(listID, indexSize);
    uint256[] memory relativeEthValues = wethValue.computeProportionalAmounts(scores);
    balances = uniswapOracle.computeAverageTokensForEth(
      tokens,
      relativeEthValues,
      SHORT_TWAP_MIN_TIME_ELAPSED,
      SHORT_TWAP_MAX_TIME_ELAPSED
    );
    uint256 len = balances.length;
    for (uint256 i = 0; i < len; i++) {
      require(balances[i] >= MIN_BALANCE, "ERR_MIN_BALANCE");
    }
  }

/* ==========  Internal Pool Utility Functions  ========== */

  /**
   * @dev Estimate the total value of a pool by taking the sum of
   * TWAP values of the pool's balance in each token it has bound.
   */
  function _estimatePoolValue(address pool) internal view returns (uint256 totalValue) {
    address[] memory tokens = IIndexPool(pool).getCurrentTokens();
    uint256 len = tokens.length;
    uint256[] memory balances = new uint256[](len);
    for (uint256 i; i < len; i++) balances[i] = IERC20(tokens[i]).balanceOf(address(pool));
    uint256[] memory ethValues = uniswapOracle.computeAverageEthForTokens(
      tokens,
      balances,
      SHORT_TWAP_MIN_TIME_ELAPSED,
      SHORT_TWAP_MAX_TIME_ELAPSED
    );
    // Safe math is not needed because we are taking the sum of an array of uint144s as a uint256.
    for (uint256 i; i < len; i++) totalValue += ethValues[i];
  }
}

File 10 of 18 : IDelegateCallProxyManager.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;


/**
 * @dev Contract that manages deployment and upgrades of delegatecall proxies.
 *
 * An implementation identifier can be created on the proxy manager which is
 * used to specify the logic address for a particular contract type, and to
 * upgrade the implementation as needed.
 *
 * A one-to-one proxy is a single proxy contract with an upgradeable implementation
 * address.
 *
 * A many-to-one proxy is a single upgradeable implementation address that may be
 * used by many proxy contracts.
 */
interface IDelegateCallProxyManager {
/* ==========  Events  ========== */

  event DeploymentApprovalGranted(address deployer);
  event DeploymentApprovalRevoked(address deployer);

  event ManyToOne_ImplementationCreated(
    bytes32 implementationID,
    address implementationAddress
  );

  event ManyToOne_ImplementationUpdated(
    bytes32 implementationID,
    address implementationAddress
  );

  event ManyToOne_ProxyDeployed(
    bytes32 implementationID,
    address proxyAddress
  );

  event OneToOne_ProxyDeployed(
    address proxyAddress,
    address implementationAddress
  );

  event OneToOne_ImplementationUpdated(
    address proxyAddress,
    address implementationAddress
  );

/* ==========  Controls  ========== */

  /**
   * @dev Allows `deployer` to deploy many-to-one proxies.
   */
  function approveDeployer(address deployer) external;

  /**
   * @dev Prevents `deployer` from deploying many-to-one proxies.
   */
  function revokeDeployerApproval(address deployer) external;

/* ==========  Implementation Management  ========== */

  /**
   * @dev Creates a many-to-one proxy relationship.
   *
   * Deploys an implementation holder contract which stores the
   * implementation address for many proxies. The implementation
   * address can be updated on the holder to change the runtime
   * code used by all its proxies.
   *
   * @param implementationID ID for the implementation, used to identify the
   * proxies that use it. Also used as the salt in the create2 call when
   * deploying the implementation holder contract.
   * @param implementation Address with the runtime code the proxies
   * should use.
   */
  function createManyToOneProxyRelationship(
    bytes32 implementationID,
    address implementation
  ) external;

  /**
   * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again.
   */
  function lockImplementationManyToOne(bytes32 implementationID) external;

  /**
   * @dev Lock the current implementation for `proxyAddress` so that it can never be upgraded again.
   */
  function lockImplementationOneToOne(address proxyAddress) external;

  /**
   * @dev Updates the implementation address for a many-to-one
   * proxy relationship.
   *
   * @param implementationID Identifier for the implementation.
   * @param implementation Address with the runtime code the proxies
   * should use.
   */
  function setImplementationAddressManyToOne(
    bytes32 implementationID,
    address implementation
  ) external;

  /**
   * @dev Updates the implementation address for a one-to-one proxy.
   *
   * Note: This could work for many-to-one as well if the caller
   * provides the implementation holder address in place of the
   * proxy address, as they use the same access control and update
   * mechanism.
   *
   * @param proxyAddress Address of the deployed proxy
   * @param implementation Address with the runtime code for
   * the proxy to use.
   */
  function setImplementationAddressOneToOne(
    address proxyAddress,
    address implementation
  ) external;

/* ==========  Proxy Deployment  ========== */

  /**
   * @dev Deploy a proxy contract with a one-to-one relationship
   * with its implementation.
   *
   * The proxy will have its own implementation address which can
   * be updated by the proxy manager.
   *
   * @param suppliedSalt Salt provided by the account requesting deployment.
   * @param implementation Address of the contract with the runtime
   * code that the proxy should use.
   */
  function deployProxyOneToOne(
    bytes32 suppliedSalt,
    address implementation
  ) external returns(address proxyAddress);

  /**
   * @dev Deploy a proxy with a many-to-one relationship with its implemenation.
   *
   * The proxy will call the implementation holder for every transaction to
   * determine the address to use in calls.
   *
   * @param implementationID Identifier for the proxy's implementation.
   * @param suppliedSalt Salt provided by the account requesting deployment.
   */
  function deployProxyManyToOne(
    bytes32 implementationID,
    bytes32 suppliedSalt
  ) external returns(address proxyAddress);

/* ==========  Queries  ========== */

  /**
   * @dev Returns a boolean stating whether `implementationID` is locked.
   */
  function isImplementationLocked(bytes32 implementationID) external view returns (bool);

  /**
   * @dev Returns a boolean stating whether `proxyAddress` is locked.
   */
  function isImplementationLocked(address proxyAddress) external view returns (bool);

  /**
   * @dev Returns a boolean stating whether `deployer` is allowed to deploy many-to-one
   * proxies.
   */
  function isApprovedDeployer(address deployer) external view returns (bool);

  /**
   * @dev Queries the temporary storage value `_implementationHolder`.
   * This is used in the constructor of the many-to-one proxy contract
   * so that the create2 address is static (adding constructor arguments
   * would change the codehash) and the implementation holder can be
   * stored as a constant.
   */
  function getImplementationHolder() external view returns (address);

  /**
   * @dev Returns the address of the implementation holder contract
   * for `implementationID`.
   */
  function getImplementationHolder(bytes32 implementationID) external view returns (address);

  /**
   * @dev Computes the create2 address for a one-to-one proxy requested
   * by `originator` using `suppliedSalt`.
   *
   * @param originator Address of the account requesting deployment.
   * @param suppliedSalt Salt provided by the account requesting deployment.
   */
  function computeProxyAddressOneToOne(
    address originator,
    bytes32 suppliedSalt
  ) external view returns (address);

  /**
   * @dev Computes the create2 address for a many-to-one proxy for the
   * implementation `implementationID` requested by `originator` using
   * `suppliedSalt`.
   *
   * @param originator Address of the account requesting deployment.
   * @param implementationID The identifier for the contract implementation.
   * @param suppliedSalt Salt provided by the account requesting deployment.
  */
  function computeProxyAddressManyToOne(
    address originator,
    bytes32 implementationID,
    bytes32 suppliedSalt
  ) external view returns (address);

  /**
   * @dev Computes the create2 address of the implementation holder
   * for `implementationID`.
   *
   * @param implementationID The identifier for the contract implementation.
  */
  function computeHolderAddressManyToOne(bytes32 implementationID) external view returns (address);
}

File 11 of 18 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

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

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

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

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

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

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

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

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

File 12 of 18 : SaltyLib.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;

/* ---  External Libraries  --- */
import { Create2 } from "@openzeppelin/contracts/utils/Create2.sol";

/* ---  Proxy Contracts  --- */
import { CodeHashes } from "./CodeHashes.sol";


/**
 * @dev Library for computing create2 salts and addresses for proxies
 * deployed by `DelegateCallProxyManager`.
 *
 * Because the proxy factory is meant to be used by multiple contracts,
 * we use a salt derivation pattern that includes the address of the
 * contract that requested the proxy deployment, a salt provided by that
 * contract and the implementation ID used (for many-to-one proxies only).
 */
library SaltyLib {
/* ---  Salt Derivation  --- */

  /**
   * @dev Derives the create2 salt for a many-to-one proxy.
   *
   * Many different contracts in the Indexed framework may use the
   * same implementation contract, and they all use the same init
   * code, so we derive the actual create2 salt from a combination
   * of the implementation ID, the address of the account requesting
   * deployment and the user-supplied salt.
   *
   * @param originator Address of the account requesting deployment.
   * @param implementationID The identifier for the contract implementation.
   * @param suppliedSalt Salt provided by the account requesting deployment.
   */
  function deriveManyToOneSalt(
    address originator,
    bytes32 implementationID,
    bytes32 suppliedSalt
  )
    internal
    pure
    returns (bytes32)
  {
    return keccak256(
      abi.encodePacked(
        originator,
        implementationID,
        suppliedSalt
      )
    );
  }

  /**
   * @dev Derives the create2 salt for a one-to-one proxy.
   *
   * @param originator Address of the account requesting deployment.
   * @param suppliedSalt Salt provided by the account requesting deployment.
   */
  function deriveOneToOneSalt(
    address originator,
    bytes32 suppliedSalt
  )
    internal
    pure
    returns (bytes32)
  {
    return keccak256(abi.encodePacked(originator, suppliedSalt));
  }

/* ---  Address Derivation  --- */

  /**
   * @dev Computes the create2 address for a one-to-one proxy deployed
   * by `deployer` (the factory) when requested by `originator` using
   * `suppliedSalt`.
   *
   * @param deployer Address of the proxy factory.
   * @param originator Address of the account requesting deployment.
   * @param suppliedSalt Salt provided by the account requesting deployment.
   */
  function computeProxyAddressOneToOne(
    address deployer,
    address originator,
    bytes32 suppliedSalt
  )
    internal
    pure
    returns (address)
  {
    bytes32 salt = deriveOneToOneSalt(originator, suppliedSalt);
    return Create2.computeAddress(salt, CodeHashes.ONE_TO_ONE_CODEHASH, deployer);
  }

  /**
   * @dev Computes the create2 address for a many-to-one proxy for the
   * implementation `implementationID` deployed by `deployer` (the factory)
   * when requested by `originator` using `suppliedSalt`.
   *
   * @param deployer Address of the proxy factory.
   * @param originator Address of the account requesting deployment.
   * @param implementationID The identifier for the contract implementation.
   * @param suppliedSalt Salt provided by the account requesting deployment.
  */
  function computeProxyAddressManyToOne(
    address deployer,
    address originator,
    bytes32 implementationID,
    bytes32 suppliedSalt
  )
    internal
    pure
    returns (address)
  {
    bytes32 salt = deriveManyToOneSalt(
      originator,
      implementationID,
      suppliedSalt
    );
    return Create2.computeAddress(salt, CodeHashes.MANY_TO_ONE_CODEHASH, deployer);
  }

  /**
   * @dev Computes the create2 address of the implementation holder
   * for `implementationID`.
   *
   * @param deployer Address of the proxy factory.
   * @param implementationID The identifier for the contract implementation.
  */
  function computeHolderAddressManyToOne(
    address deployer,
    bytes32 implementationID
  )
    internal
    pure
    returns (address)
  {
    return Create2.computeAddress(
      implementationID,
      CodeHashes.IMPLEMENTATION_HOLDER_CODEHASH,
      deployer
    );
  }
}

File 13 of 18 : Create2.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.6.0;

/**
 * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
 * `CREATE2` can be used to compute in advance the address where a smart
 * contract will be deployed, which allows for interesting new mechanisms known
 * as 'counterfactual interactions'.
 *
 * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
 * information.
 */
library Create2 {
    /**
     * @dev Deploys a contract using `CREATE2`. The address where the contract
     * will be deployed can be known in advance via {computeAddress}.
     *
     * The bytecode for a contract can be obtained from Solidity with
     * `type(contractName).creationCode`.
     *
     * Requirements:
     *
     * - `bytecode` must not be empty.
     * - `salt` must have not been used for `bytecode` already.
     * - the factory must have a balance of at least `amount`.
     * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
     */
    function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address) {
        address addr;
        require(address(this).balance >= amount, "Create2: insufficient balance");
        require(bytecode.length != 0, "Create2: bytecode length is zero");
        // solhint-disable-next-line no-inline-assembly
        assembly {
            addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
        }
        require(addr != address(0), "Create2: Failed on deploy");
        return addr;
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
     * `bytecodeHash` or `salt` will result in a new destination address.
     */
    function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
        return computeAddress(salt, bytecodeHash, address(this));
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
     * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
     */
    function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address) {
        bytes32 _data = keccak256(
            abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)
        );
        return address(uint256(_data));
    }
}

File 14 of 18 : CodeHashes.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;


/**
 * @dev Because we use the code hashes of the proxy contracts for proxy address
 * derivation, it is important that other packages have access to the correct
 * values when they import the salt library.
 */
library CodeHashes {
  bytes32 internal constant ONE_TO_ONE_CODEHASH = 0x63d9f7b5931b69188c8f6b806606f25892f1bb17b7f7e966fe3a32c04493aee4;
  bytes32 internal constant MANY_TO_ONE_CODEHASH = 0xa035ad05a1663db5bfd455b99cd7c6ac6bd49269738458eda140e0b78ed53f79;
  bytes32 internal constant IMPLEMENTATION_HOLDER_CODEHASH = 0x11c370493a726a0ffa93d42b399ad046f1b5a543b6e72f1a64f1488dc1c58f2c;
}

File 15 of 18 : IIndexPool.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;


interface IIndexPool {
  /**
   * @dev Token record data structure
   * @param bound is token bound to pool
   * @param ready has token been initialized
   * @param lastDenormUpdate timestamp of last denorm change
   * @param denorm denormalized weight
   * @param desiredDenorm desired denormalized weight (used for incremental changes)
   * @param index index of address in tokens array
   * @param balance token balance
   */
  struct Record {
    bool bound;
    bool ready;
    uint40 lastDenormUpdate;
    uint96 denorm;
    uint96 desiredDenorm;
    uint8 index;
    uint256 balance;
  }

/* ==========  EVENTS  ========== */

  /** @dev Emitted when tokens are swapped. */
  event LOG_SWAP(
    address indexed caller,
    address indexed tokenIn,
    address indexed tokenOut,
    uint256 tokenAmountIn,
    uint256 tokenAmountOut
  );

  /** @dev Emitted when underlying tokens are deposited for pool tokens. */
  event LOG_JOIN(
    address indexed caller,
    address indexed tokenIn,
    uint256 tokenAmountIn
  );

  /** @dev Emitted when pool tokens are burned for underlying. */
  event LOG_EXIT(
    address indexed caller,
    address indexed tokenOut,
    uint256 tokenAmountOut
  );

  /** @dev Emitted when a token's weight updates. */
  event LOG_DENORM_UPDATED(address indexed token, uint256 newDenorm);

  /** @dev Emitted when a token's desired weight is set. */
  event LOG_DESIRED_DENORM_SET(address indexed token, uint256 desiredDenorm);

  /** @dev Emitted when a token is unbound from the pool. */
  event LOG_TOKEN_REMOVED(address token);

  /** @dev Emitted when a token is unbound from the pool. */
  event LOG_TOKEN_ADDED(
    address indexed token,
    uint256 desiredDenorm,
    uint256 minimumBalance
  );

  /** @dev Emitted when a token's minimum balance is updated. */
  event LOG_MINIMUM_BALANCE_UPDATED(address token, uint256 minimumBalance);

  /** @dev Emitted when a token reaches its minimum balance. */
  event LOG_TOKEN_READY(address indexed token);

  /** @dev Emitted when public trades are enabled or disabled. */
  event LOG_PUBLIC_SWAP_TOGGLED(bool isPublic);

  /** @dev Emitted when the swap fee is updated. */
  event LOG_SWAP_FEE_UPDATED(uint256 swapFee);

  /** @dev Emitted when exit fee recipient is updated. */
  event LOG_EXIT_FEE_RECIPIENT_UPDATED(address exitFeeRecipient);

  /** @dev Emitted when controller is updated. */
  event LOG_CONTROLLER_UPDATED(address exitFeeRecipient);

  function configure(
    address controller,
    string calldata name,
    string calldata symbol
  ) external;

  function initialize(
    address[] calldata tokens,
    uint256[] calldata balances,
    uint96[] calldata denorms,
    address tokenProvider,
    address unbindHandler,
    address exitFeeRecipient
  ) external;

  function setSwapFee(uint256 swapFee) external;

  function setController(address controller) external;

  function delegateCompLikeToken(address token, address delegatee) external;

  function setExitFeeRecipient(address) external;

  function setPublicSwap(bool enabled) external;

  function reweighTokens(
    address[] calldata tokens,
    uint96[] calldata desiredDenorms
  ) external;

  function reindexTokens(
    address[] calldata tokens,
    uint96[] calldata desiredDenorms,
    uint256[] calldata minimumBalances
  ) external;

  function setMinimumBalance(address token, uint256 minimumBalance) external;

  function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external;

  function joinswapExternAmountIn(
    address tokenIn,
    uint256 tokenAmountIn,
    uint256 minPoolAmountOut
  ) external returns (uint256/* poolAmountOut */);

  function joinswapPoolAmountOut(
    address tokenIn,
    uint256 poolAmountOut,
    uint256 maxAmountIn
  ) external returns (uint256/* tokenAmountIn */);

  function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external;

  function exitswapPoolAmountIn(
    address tokenOut,
    uint256 poolAmountIn,
    uint256 minAmountOut
  )
    external returns (uint256/* tokenAmountOut */);

  function exitswapExternAmountOut(
    address tokenOut,
    uint256 tokenAmountOut,
    uint256 maxPoolAmountIn
  ) external returns (uint256/* poolAmountIn */);

  function gulp(address token) external;

  function swapExactAmountIn(
    address tokenIn,
    uint256 tokenAmountIn,
    address tokenOut,
    uint256 minAmountOut,
    uint256 maxPrice
  ) external returns (uint256/* tokenAmountOut */, uint256/* spotPriceAfter */);

  function swapExactAmountOut(
    address tokenIn,
    uint256 maxAmountIn,
    address tokenOut,
    uint256 tokenAmountOut,
    uint256 maxPrice
  ) external returns (uint256 /* tokenAmountIn */, uint256 /* spotPriceAfter */);

  function isPublicSwap() external view returns (bool);

  function getSwapFee() external view returns (uint256/* swapFee */);

  function getExitFee() external view returns (uint256/* exitFee */);

  function getController() external view returns (address);

  function getExitFeeRecipient() external view returns (address);

  function isBound(address t) external view returns (bool);

  function getNumTokens() external view returns (uint256);

  function getCurrentTokens() external view returns (address[] memory tokens);

  function getCurrentDesiredTokens() external view returns (address[] memory tokens);

  function getDenormalizedWeight(address token) external view returns (uint256/* denorm */);

  function getTokenRecord(address token) external view returns (Record memory record);

  function getTotalDenormalizedWeight() external view returns (uint256);

  function getBalance(address token) external view returns (uint256);

  function getMinimumBalance(address token) external view returns (uint256);

  function getUsedBalance(address token) external view returns (uint256);

  function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint256);
}

File 16 of 18 : IPoolFactory.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;

import "@indexed-finance/proxies/contracts/interfaces/IDelegateCallProxyManager.sol";


interface IPoolFactory {
/* ========== Events ========== */

  event NewPool(address pool, address controller, bytes32 implementationID);

/* ========== Mutative ========== */

  function approvePoolController(address controller) external;

  function disapprovePoolController(address controller) external;

  function deployPool(bytes32 implementationID, bytes32 controllerSalt) external returns (address);

/* ========== Views ========== */

  function proxyManager() external view returns (IDelegateCallProxyManager);

  function isApprovedController(address) external view returns (bool);

  function getPoolImplementationID(address) external view returns (bytes32);

  function isRecognizedPool(address pool) external view returns (bool);

  function computePoolAddress(
    bytes32 implementationID,
    address controller,
    bytes32 controllerSalt
  ) external view returns (address);
}

File 17 of 18 : IPoolInitializer.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;


interface IPoolInitializer {
/* ========== Events ========== */

  event TokensContributed(
    address from,
    address token,
    uint256 amount,
    uint256 credit
  );

/* ========== Mutative ========== */

  function initialize(
    address controller,
    address poolAddress,
    address[] calldata tokens,
    uint256[] calldata amounts
  ) external;

  function finish() external;

  function claimTokens() external;

  function claimTokens(address account) external;

  function claimTokens(address[] calldata accounts) external;

  function contributeTokens(
    address token,
    uint256 amountIn,
    uint256 minimumCredit
  ) external returns (uint256);

  function contributeTokens(
    address[] calldata tokens,
    uint256[] calldata amountsIn,
    uint256 minimumCredit
  ) external returns (uint256);

  function updatePrices() external;

/* ========== Views ========== */

  function isFinished() external view returns (bool);

  function getTotalCredit() external view returns (uint256);

  function getCreditOf(address account) external view returns (uint256);

  function getDesiredTokens() external view returns (address[] memory);

  function getDesiredAmount(address token) external view returns (uint256);

  function getDesiredAmounts(address[] calldata tokens) external view returns (uint256[] memory);

  function getCreditForTokens(address token, uint256 amountIn) external view returns (uint144);
}

File 18 of 18 : IUnboundTokenSeller.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;


interface IUnboundTokenSeller {
/* ========== Events ========== */

  event PremiumPercentSet(uint8 premium);

  event NewTokensToSell(address indexed token, uint256 amountReceived);

  event SwappedTokens(
    address indexed tokenSold,
    address indexed tokenBought,
    uint256 soldAmount,
    uint256 boughtAmount
  );

/* ========== Mutative ========== */

  function initialize(address controller_, address pool, uint8 premiumPercent) external;

  function handleUnbindToken(address token, uint256 amount) external;

  function setPremiumPercent(uint8 premiumPercent) external;

  function executeSwapTokensForExactTokens(
    address tokenIn,
    address tokenOut,
    uint256 amountOut,
    address[] calldata path
  ) external returns (uint256);

  function executeSwapExactTokensForTokens(
    address tokenIn,
    address tokenOut,
    uint256 amountIn,
    address[] calldata path
  ) external returns (uint256);

  function swapExactTokensForTokens(
    address tokenIn,
    address tokenOut,
    uint256 amountIn,
    uint256 minAmountOut
  ) external returns (uint256);

  function swapTokensForExactTokens(
    address tokenIn,
    address tokenOut,
    uint256 amountOut,
    uint256 maxAmountIn
  ) external returns (uint256);

/* ========== Views ========== */

  function getPremiumPercent() external view returns (uint8);

  function calcInGivenOut(
    address tokenIn,
    address tokenOut,
    uint256 amountOut
  ) external view returns (uint256);

  function calcOutGivenIn(
    address tokenIn,
    address tokenOut,
    uint256 amountIn
  ) external view returns (uint256);
}

Settings
{
  "metadata": {
    "useLiteralContent": false
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract IIndexedUniswapV2Oracle","name":"uniswapOracle_","type":"address"},{"internalType":"contract IPoolFactory","name":"poolFactory_","type":"address"},{"internalType":"contract IDelegateCallProxyManager","name":"proxyManager_","type":"address"},{"internalType":"address","name":"governance_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"initializer","type":"address"},{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"indexSize","type":"uint256"}],"name":"NewPoolInitializer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"address","name":"unboundTokenSeller","type":"address"},{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"indexSize","type":"uint256"}],"name":"PoolInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolReindexed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolReweighed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"}],"name":"TokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"metadataHash","type":"bytes32"},{"indexed":false,"internalType":"address","name":"scoringStrategy","type":"address"},{"indexed":false,"internalType":"uint128","name":"minimumScore","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"maximumScore","type":"uint128"}],"name":"TokenListAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"}],"name":"TokenListSorted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"listID","type":"uint256"}],"name":"TokenRemoved","type":"event"},{"inputs":[],"name":"INITIALIZER_IMPLEMENTATION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_INDEX_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LIST_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_BALANCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_INDEX_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_IMPLEMENTATION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_REWEIGH_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWEIGHS_BEFORE_REINDEX","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SELLER_IMPLEMENTATION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHORT_TWAP_MAX_TIME_ELAPSED","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SHORT_TWAP_MIN_TIME_ELAPSED","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"addToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"addTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"circuitBreaker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"circulatingMarketCapOracle","outputs":[{"internalType":"contract ICirculatingMarketCapOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"computeInitializerAddress","outputs":[{"internalType":"address","name":"initializerAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"uint256","name":"indexSize","type":"uint256"}],"name":"computePoolAddress","outputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"computeSellerAddress","outputs":[{"internalType":"address","name":"sellerAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"metadataHash","type":"bytes32"},{"internalType":"address","name":"scoringStrategy","type":"address"},{"internalType":"uint128","name":"minimumScore","type":"uint128"},{"internalType":"uint128","name":"maximumScore","type":"uint128"}],"name":"createTokenList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultExitFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultSellerPremium","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegateCompLikeTokenFromPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"name":"finishPreparedIndexPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"forceReindexPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"uint256","name":"indexSize","type":"uint256"},{"internalType":"uint256","name":"wethValue","type":"uint256"}],"name":"getInitialTokensAndBalances","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"}],"name":"getSortedAndFilteredTokensAndScores","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"scores","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"}],"name":"getTokenList","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"}],"name":"getTokenListConfig","outputs":[{"internalType":"address","name":"scoringStrategy","type":"address"},{"internalType":"uint128","name":"minimumScore","type":"uint128"},{"internalType":"uint128","name":"maximumScore","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getTokenScores","outputs":[{"internalType":"uint256[]","name":"scores","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"getTopTokensAndScores","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"scores","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"indexPoolMetadata","outputs":[{"internalType":"bool","name":"initialized","type":"bool"},{"internalType":"uint16","name":"listID","type":"uint16"},{"internalType":"uint8","name":"indexSize","type":"uint8"},{"internalType":"uint8","name":"reweighIndex","type":"uint8"},{"internalType":"uint64","name":"lastReweigh","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"circuitBreaker_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"isTokenInlist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFactory","outputs":[{"internalType":"contract IPoolFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"uint256","name":"indexSize","type":"uint256"},{"internalType":"uint256","name":"initialWethValue","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"prepareIndexPool","outputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"initializerAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyManager","outputs":[{"internalType":"contract IDelegateCallProxyManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"reindexPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"removeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"reweighPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"circuitBreaker_","type":"address"}],"name":"setCircuitBreaker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"controller","type":"address"}],"name":"setController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"defaultExitFeeRecipient_","type":"address"}],"name":"setDefaultExitFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_defaultSellerPremium","type":"uint8"}],"name":"setDefaultSellerPremium","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"setExitFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"poolAddresses","type":"address[]"},{"internalType":"address","name":"exitFeeRecipient","type":"address"}],"name":"setExitFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"indexPool_","type":"address"},{"internalType":"bool","name":"publicSwap","type":"bool"}],"name":"setPublicSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"poolAddresses","type":"address[]"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"setSwapFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"}],"name":"sortAndFilterTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenListCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapOracle","outputs":[{"internalType":"contract IIndexedUniswapV2Oracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"updateMinimumBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenSeller","type":"address"},{"internalType":"uint8","name":"premiumPercent","type":"uint8"}],"name":"updateSellerPremium","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"listID","type":"uint256"}],"name":"updateTokenPrices","outputs":[{"internalType":"bool[]","name":"pricesUpdated","type":"bool[]"}],"stateMutability":"nonpayable","type":"function"}]

6101006040523480156200001257600080fd5b5060405162005848380380620058488339810160408190526200003591620000a5565b600080546001600160a01b031916600190811782556040518692907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36001600160601b0319606091821b811660805293811b841660a05291821b831660c052901b1660e0525062000125565b60008060008060808587031215620000bb578384fd5b8451620000c8816200010c565b6020860151909450620000db816200010c565b6040860151909350620000ee816200010c565b606086015190925062000101816200010c565b939692955090935050565b6001600160a01b03811681146200012257600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c615678620001d0600039806107bc5280610c6652806110e352806114fe528061220a528061276152806131f252508061148952806116d95280611eea5280612734528061280b528061332e5250806112175280611c80528061282c5250806109d75280610b8052806113bb528061162e5280611ace52806120d75280612b73528061351752806136b052506156786000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c8063830b6b0b116101e9578063b3ec862e1161010f578063df8e238a116100ad578063f2fde38b1161007c578063f2fde38b14610770578063f34e861814610783578063f52a4f2614610796578063fa7c0b5e1461079e57610399565b8063df8e238a1461072f578063e9819daf14610742578063ec0915c714610755578063f2d754711461075d57610399565b8063c6acb34f116100e9578063c6acb34f146106e1578063d600751d146106f4578063dcdf7e16146106fc578063de16eb991461070f57610399565b8063b3ec862e146106be578063c4d66de8146106c6578063c5ea91e1146106d957610399565b806396b4ca7011610187578063a34fefdd11610156578063a34fefdd1461069e578063a43ad7e7146106a6578063a8eb80ab146106ae578063acbfc96d146106b657610399565b806396b4ca701461064c578063991991c7146106545780639dd19a52146106675780639dfab0921461067a57610399565b806388b9813a116101c357806388b9813a146105fe57806388d6c096146106115780638a15f964146106245780638da5cb5b1461064457610399565b8063830b6b0b146105db578063861a9ec9146105e3578063867378c5146105f657610399565b806341b63bd8116102ce5780636a7a93ed1161026c578063774cf0cb1161023b578063774cf0cb1461058c5780637b7d6c68146105ad5780638129fc1c146105c057806382beee89146105c857610399565b80636a7a93ed1461053d5780636b5b880814610550578063715018a61461056357806374a587831461056b57610399565b806353304eb9116102a857806353304eb9146104fa57806357016b0a1461050f578063582edc9b146105225780635aa6e6751461053557610399565b806341b63bd8146104bf5780634219dc40146104df57806350b1e342146104e757610399565b80631eccc1851161033b57806333fe56761161031557806333fe56761461047c578063351ad28f1461048f578063372accd2146104a25780633d89da25146104b757610399565b80631eccc18514610434578063250436fd14610447578063297c34301461045c57610399565b8063120c6c5b11610377578063120c6c5b146103d957806313b75360146103f757806316efd941146104195780631a33a2501461042157610399565b80630255b1de1461039e578063034b904e146103b35780630fae3828146103c6575b600080fd5b6103b16103ac366004614498565b6107b1565b005b6103b16103c13660046142c9565b6108dc565b6103b16103d4366004614291565b610ae2565b6103e1610b7e565b6040516103ee9190614bad565b60405180910390f35b61040a61040536600461479a565b610ba2565b6040516103ee93929190614ce6565b6103e1610c12565b6103b161042f3660046142c9565b610c21565b6103b16104423660046143ca565b610d06565b61044f610db9565b6040516103ee9190614fe3565b61046f61046a366004614837565b610ddd565b6040516103ee9190614f90565b6103b161048a3660046147ca565b610eaa565b6103b161049d366004614291565b6110d8565b6104aa611168565b6040516103ee91906155ba565b6104aa611171565b6104d26104cd36600461479a565b611176565b6040516103ee9190614e20565b6103e1611215565b6103b16104f5366004614291565b611239565b6105026112fe565b6040516103ee91906155a9565b6103b161051d3660046147ca565b611304565b6103e1610530366004614291565b611482565b6103e16114fc565b6103b161054b36600461434b565b611520565b6103b161055e3660046147ee565b6119a0565b6103b1611b5b565b61057e610579366004614927565b611bde565b6040516103ee929190614bc1565b61059f61059a3660046148fc565b61209d565b6040516103ee929190614e33565b6103b16105bb3660046142c9565b6121c5565b6103b1612273565b6103b16105d6366004614291565b61227d565b61044f6122d4565b61059f6105f13660046148db565b6122db565b61044f612349565b6103b161060c36600461479a565b612350565b6103b161061f3660046146a9565b612559565b6106376106323660046147ca565b6126c2565b6040516103ee9190614fa3565b6103e1612723565b6103e1612732565b6103b16106623660046143f7565b612756565b6103e16106753660046148db565b612804565b61068d610688366004614291565b6128ae565b6040516103ee959493929190614fae565b6105026128f5565b61044f6128fc565b6103e1612902565b61044f612911565b61044f612916565b6103b16106d4366004614291565b61291b565b61044f612953565b6103b16106ef366004614301565b612977565b6103e1612a4c565b6103b161070a366004614422565b612a5b565b61072261071d36600461479a565b612b1c565b6040516103ee9190614f56565b6103b161073d3660046149b0565b612c00565b6103b1610750366004614291565b612c7d565b61044f612fdb565b61059f61076b36600461479a565b612fe0565b6103b161077e366004614291565b613131565b6103b161079136600461444f565b6131e7565b61044f613303565b6103e16107ac366004614291565b613327565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108025760405162461bcd60e51b81526004016107f9906153b5565b60405180910390fd5b60005b828110156108d657600084848381811061081b57fe5b90506020020160208101906108309190614291565b6001600160a01b03811660009081526005602052604090205490915060ff1661086b5760405162461bcd60e51b81526004016107f9906152a0565b6040516334e1990760e01b81526001600160a01b038216906334e1990790610897908690600401614fe3565b600060405180830381600087803b1580156108b157600080fd5b505af11580156108c5573d6000803e3d6000fd5b505060019093019250610805915050565b50505050565b6001600160a01b038216600090815260056020526040902054829060ff166109165760405162461bcd60e51b81526004016107f9906152a0565b61091e6140ee565b6040516364c7d66160e01b81526001600160a01b038516906364c7d6619061094a908690600401614bad565b60e06040518083038186803b15801561096257600080fd5b505afa158015610976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099a91906146f9565b90508060200151156109be5760405162461bcd60e51b81526004016107f9906154a2565b60006109c985613380565b905060006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634f2acedf86606485046104b06202a3006040518563ffffffff1660e01b8152600401610a279493929190614d29565b60206040518083038186803b158015610a3f57600080fd5b505afa158015610a53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7791906147b2565b60405163a49c44d760e01b81529091506001600160a01b0387169063a49c44d790610aa89088908590600401614d10565b600060405180830381600087803b158015610ac257600080fd5b505af1158015610ad6573d6000803e3d6000fd5b50505050505050505050565b610aea6135e7565b6000546001600160a01b03908116911614610b175760405162461bcd60e51b81526004016107f990615335565b6001600160a01b03811660009081526005602052604090208054600160201b80820460ff908116600101808216830264ff00000000199485161793841660039091166004818103958590048416959095019092169092029190911783556108d683856135eb565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000836002548111158015610bba5750600081115b610bd65760405162461bcd60e51b81526004016107f99061542b565b505050600091825250600360205260409020600181015490546001600160a01b03909116916001600160801b0380831692600160801b90041690565b6006546001600160a01b031681565b6001600160a01b038216600090815260056020526040902054829060ff16610c5b5760405162461bcd60e51b81526004016107f9906152a0565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610ca35760405162461bcd60e51b81526004016107f9906153b5565b604051631f3f2f9360e31b81526001600160a01b0384169063f9f97c9890610ccf908590600401614bad565b600060405180830381600087803b158015610ce957600080fd5b505af1158015610cfd573d6000803e3d6000fd5b50505050505050565b6001600160a01b038216600090815260056020526040902054829060ff16610d405760405162461bcd60e51b81526004016107f9906152a0565b6006546001600160a01b0316331480610d715750610d5c612723565b6001600160a01b0316336001600160a01b0316145b610d8d5760405162461bcd60e51b81526004016107f990615217565b6040516324dacaa960e11b81526001600160a01b038416906349b5955290610ccf908590600401614fa3565b7f42fdd905bf1f3fac3b475cdca7cc127db3a757ae179f57c9da3b4787f5f5820681565b6060826002548111158015610df25750600081115b610e0e5760405162461bcd60e51b81526004016107f99061542b565b60008481526003602052604090819020600101549051631a86165360e01b81526001600160a01b0390911690631a86165390610e4e908690600401614e20565b60006040518083038186803b158015610e6657600080fd5b505afa158015610e7a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ea2919081019061460a565b949350505050565b610eb26135e7565b6000546001600160a01b03908116911614610edf5760405162461bcd60e51b81526004016107f990615335565b816002548111158015610ef25750600081115b610f0e5760405162461bcd60e51b81526004016107f99061542b565b6000838152600360205260408120600281015490919080610f415760405162461bcd60e51b81526004016107f990615450565b6001600160a01b038516600090815260038401602052604090205460ff16610f7b5760405162461bcd60e51b81526004016107f990615141565b6001600160a01b03851660009081526003840160205260409020805460ff191690555b808210156110cf57846001600160a01b0316836002018381548110610fbf57fe5b6000918252602090912001546001600160a01b031614156110c4576000198101828114611052576000846002018281548110610ff757fe5b6000918252602090912001546002860180546001600160a01b03909216925082918690811061102257fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505b8360020180548061105f57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556040517fbe9bb4bdca0a094babd75e3a98b1d2e2390633430d0a2f6e2b9970e2ee03fb2e906110b39088908a90614d10565b60405180910390a1505050506110d3565b600190910190610f9e565b5050505b505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146111205760405162461bcd60e51b81526004016107f9906153b5565b6001600160a01b0381166111465760405162461bcd60e51b81526004016107f990615478565b600780546001600160a01b0319166001600160a01b0392909216919091179055565b60045460ff1681565b600381565b606081600254811115801561118b5750600081115b6111a75760405162461bcd60e51b81526004016107f99061542b565b6000838152600360209081526040918290206002018054835181840281018401909452808452909183018282801561120857602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116111ea575b5050505050915050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b0381166000908152600560205260409020805460ff166112725760405162461bcd60e51b81526004016107f9906152a0565b805462093a80600160281b9091046001600160401b0316420310156112a95760405162461bcd60e51b81526004016107f990615243565b805464ff00000000198116600160ff600160201b93849004811691909101908116909202178255600316156112f05760405162461bcd60e51b81526004016107f9906151ec565b6112fa81836135eb565b5050565b6104b081565b61130c6135e7565b6000546001600160a01b039081169116146113395760405162461bcd60e51b81526004016107f990615335565b81600254811115801561134c5750600081115b6113685760405162461bcd60e51b81526004016107f99061542b565b6000838152600360205260409020600281015460191161139a5760405162461bcd60e51b81526004016107f990615273565b6113a4818461381e565b6040516396e85ced60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906396e85ced906113f0908690600401614bad565b602060405180830381600087803b15801561140a57600080fd5b505af115801561141e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611442919061468d565b507ff4c563a3ea86ff1f4275e8c207df0375a51963f2b831b7bf4da8be938d92876c8385604051611474929190614d10565b60405180910390a150505050565b60006114f67f0000000000000000000000000000000000000000000000000000000000000000307f9f8b000e870cb32f9827cf46e6a69e2637d6c7131de0898cec5106d029b20f8d856040516020016114db9190614b11565b604051602081830303815290604052805190602001206138a8565b92915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b8461152a81613327565b6001600160a01b0316336001600160a01b03161461155a5760405162461bcd60e51b81526004016107f99061510a565b8382811461157a5760405162461bcd60e51b81526004016107f9906153e1565b61158261412a565b506001600160a01b038716600090815260056020908152604091829020825160a081018452905460ff8082161580158452610100830461ffff169484019490945263010000008204811694830194909452600160201b81049093166060820152600160281b9092046001600160401b031660808301526116145760405162461bcd60e51b81526004016107f9906151c3565b604051633e48351560e11b81526060906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637c906a2a90611672908b908b908b908b906104b0906202a30090600401614dd5565b60006040518083038186803b15801561168a57600080fd5b505afa15801561169e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116c6919081019061460a565b905060606116d3826138ed565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a5e5bc57f9f8b000e870cb32f9827cf46e6a69e2637d6c7131de0898cec5106d029b20f8d8d6040516020016117389190614b11565b604051602081830303815290604052805190602001206040518363ffffffff1660e01b815260040161176b929190614b9f565b602060405180830381600087803b15801561178557600080fd5b505af1158015611799573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117bd91906142ad565b600754604051630ac4431d60e21b81529192506001600160a01b03808e1692632b110c74926117ff928f928f928f928f928b9233928c92911690600401614d6c565b600060405180830381600087803b15801561181957600080fd5b505af115801561182d573d6000803e3d6000fd5b50505050806001600160a01b03166389232a00308d600460009054906101000a900460ff166040518463ffffffff1660e01b815260040161187093929190614c7c565b600060405180830381600087803b15801561188a57600080fd5b505af115801561189e573d6000803e3d6000fd5b505050426001600160401b0390811660808701908152600187526001600160a01b038e1660009081526005602090815260409182902089518154928b0151848c015160608d0151965160ff199095169215159290921762ffff00191661010061ffff8316021763ff0000001916630100000060ff808516919091029190911764ff000000001916600160201b9190971602959095176cffffffffffffffff00000000001916600160281b939096169290920294909417909355517f9ff2050ac7faae9dc192e1cc9abe73b18a9b849f9b43f509914d80fa104d5903935061198b928f928692909190614c24565b60405180910390a15050505050505050505050565b6119a86135e7565b6000546001600160a01b039081169116146119d55760405162461bcd60e51b81526004016107f990615335565b8260025481111580156119e85750600081115b611a045760405162461bcd60e51b81526004016107f99061542b565b6000848152600360205260409020600281015460199084011115611a3a5760405162461bcd60e51b81526004016107f990615273565b60005b83811015611ab6576000858583818110611a5357fe5b9050602002016020810190611a689190614291565b9050611a74838261381e565b7ff4c563a3ea86ff1f4275e8c207df0375a51963f2b831b7bf4da8be938d92876c8188604051611aa5929190614d10565b60405180910390a150600101611a3d565b506040516303f294b760e51b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637e5296e090611b059087908790600401614d58565b600060405180830381600087803b158015611b1f57600080fd5b505af1158015611b33573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110cf919081019061457e565b611b636135e7565b6000546001600160a01b03908116911614611b905760405162461bcd60e51b81526004016107f990615335565b600080546040516001926001600160a01b03909216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001179055565b600080611be96135e7565b6000546001600160a01b03908116911614611c165760405162461bcd60e51b81526004016107f990615335565b6002881015611c375760405162461bcd60e51b81526004016107f99061551c565b600a881115611c585760405162461bcd60e51b81526004016107f990615197565b6001600160901b038710611c7e5760405162461bcd60e51b81526004016107f990615548565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663187775f97f42fdd905bf1f3fac3b475cdca7cc127db3a757ae179f57c9da3b4787f5f582068b8b604051602001611ce1929190614b9f565b604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401611d14929190614b9f565b602060405180830381600087803b158015611d2e57600080fd5b505af1158015611d42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6691906142ad565b6040516319f0f84960e01b81529092506001600160a01b038316906319f0f84990611d9d9030908a908a908a908a90600401614ca2565b600060405180830381600087803b158015611db757600080fd5b505af1158015611dcb573d6000803e3d6000fd5b505050506040518060a001604052806000151581526020018a61ffff1681526020018960ff168152602001600060ff16815260200160006001600160401b031681525060056000846001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548161ffff021916908361ffff16021790555060408201518160000160036101000a81548160ff021916908360ff16021790555060608201518160000160046101000a81548160ff021916908360ff16021790555060808201518160000160056101000a8154816001600160401b0302191690836001600160401b031602179055509050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a5e5bc57fe3d7c1179cc3f4ae9aab4e39c8923b411d4674dcb3d44aa456301be51bb24aef84604051602001611f499190614b11565b604051602081830303815290604052805190602001206040518363ffffffff1660e01b8152600401611f7c929190614b9f565b602060405180830381600087803b158015611f9657600080fd5b505af1158015611faa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fce91906142ad565b905080606080611fe88c8c6001600160901b038d1661209d565b604051633b4f19a560e21b815291935091506001600160a01b0384169063ed3c66949061201f903090899087908790600401614bdb565b600060405180830381600087803b15801561203957600080fd5b505af115801561204d573d6000803e3d6000fd5b505050507f7ad23833dba658b2bdc6f260fb60a3240b3868086ad60b4e42276f5eeba73e6a85858e8e6040516120869493929190614c53565b60405180910390a150505097509795505050505050565b60608060606120ac86866122db565b909350905060606120bd85836139f4565b604051630228300360e51b81529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063450600609061211790879085906104b0906202a30090600401614e61565b60006040518083038186803b15801561212f57600080fd5b505afa158015612143573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261216b919081019061460a565b805190935060005b818110156121b957620f424085828151811061218b57fe5b602002602001015110156121b15760405162461bcd60e51b81526004016107f99061516e565b600101612173565b50505050935093915050565b6001600160a01b038216600090815260056020526040902054829060ff166121ff5760405162461bcd60e51b81526004016107f9906152a0565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146122475760405162461bcd60e51b81526004016107f9906153b5565b6040516392eefe9b60e01b81526001600160a01b038416906392eefe9b90610ccf908590600401614bad565b61227b613abc565b565b6122856135e7565b6000546001600160a01b039081169116146122b25760405162461bcd60e51b81526004016107f990615335565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b62093a8081565b6060808360025481111580156122f15750600081115b61230d5760405162461bcd60e51b81526004016107f99061542b565b61231685612fe0565b8151919450925084111561233c5760405162461bcd60e51b81526004016107f9906154f5565b5082825291825292909150565b620f424081565b8060025481111580156123635750600081115b61237f5760405162461bcd60e51b81526004016107f99061542b565b60008281526003602090815260409182902060028101805484518185028101850190955280855291936060939092908301828280156123e757602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116123c9575b5050506001850154604051631a86165360e01b81529394506060936001600160a01b039091169250631a8616539150612424908590600401614e20565b60006040518083038186803b15801561243c57600080fd5b505afa158015612450573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612478919081019061460a565b83549091506060906124a190849084906001600160801b0380821691600160801b900416613b3b565b600087815260036020908152604090912085519293506124c992600290910191860190614158565b5060005b8151811015610cfd5760008282815181106124e457fe5b6020908102919091018101516001600160a01b038116600090815260038901909252604091829020805460ff1916905590519091507fbe9bb4bdca0a094babd75e3a98b1d2e2390633430d0a2f6e2b9970e2ee03fb2e906125489083908b90614d10565b60405180910390a1506001016124cd565b6125616135e7565b6000546001600160a01b0390811691161461258e5760405162461bcd60e51b81526004016107f990615335565b6000826001600160801b0316116125b75760405162461bcd60e51b81526004016107f9906154cb565b816001600160801b0316816001600160801b0316116125e85760405162461bcd60e51b81526004016107f990615406565b6001600160a01b03831661260e5760405162461bcd60e51b81526004016107f990615478565b600280546001908101918290556000828152600360205260409081902091820180546001600160a01b0388166001600160a01b031990911617905581546001600160801b03858116600160801b028188166fffffffffffffffffffffffffffffffff199093169290921716178255517fd5e8e673f6e24dc7176b58a5620dcee488e08e985c6fd9db96b1b6d214004117906126b29084908990899089908990615571565b60405180910390a1505050505050565b60008260025481111580156126d75750600081115b6126f35760405162461bcd60e51b81526004016107f99061542b565b505060009182526003602081815260408085206001600160a01b0394909416855292909101905290205460ff1690565b6000546001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000081565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461279e5760405162461bcd60e51b81526004016107f9906153b5565b6001600160a01b038216600090815260056020526040902054829060ff166127d85760405162461bcd60e51b81526004016107f9906152a0565b6040516334e1990760e01b81526001600160a01b038416906334e1990790610ccf908590600401614fe3565b60006128a77f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f42fdd905bf1f3fac3b475cdca7cc127db3a757ae179f57c9da3b4787f5f58206308787604051602001612880929190614b9f565b604051602081830303815290604052805190602001206040516020016114db929190614b29565b9392505050565b60056020526000908152604090205460ff80821691610100810461ffff169163010000008204811691600160201b810490911690600160281b90046001600160401b031685565b6202a30081565b60025481565b6007546001600160a01b031681565b600a81565b600281565b612923612273565b6004805460ff19166002179055600680546001600160a01b039092166001600160a01b0319909216919091179055565b7f9f8b000e870cb32f9827cf46e6a69e2637d6c7131de0898cec5106d029b20f8d81565b61297f6135e7565b6000546001600160a01b039081169116146129ac5760405162461bcd60e51b81526004016107f990615335565b6001600160a01b038316600090815260056020526040902054839060ff166129e65760405162461bcd60e51b81526004016107f9906152a0565b60405163f8b5db0960e01b81526001600160a01b0385169063f8b5db0990612a149086908690600401614bc1565b600060405180830381600087803b158015612a2e57600080fd5b505af1158015612a42573d6000803e3d6000fd5b5050505050505050565b6001546001600160a01b031681565b612a636135e7565b6000546001600160a01b03908116911614612a905760405162461bcd60e51b81526004016107f990615335565b60008160ff16118015612aa6575060148160ff16105b612ac25760405162461bcd60e51b81526004016107f9906150bc565b604051630633177160e41b81526001600160a01b03831690636331771090612aee9084906004016155ba565b600060405180830381600087803b158015612b0857600080fd5b505af11580156110cf573d6000803e3d6000fd5b6060816002548111158015612b315750600081115b612b4d5760405162461bcd60e51b81526004016107f99061542b565b6000838152600360205260409081902090516303f294b760e51b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691637e5296e091612baa9160020190600401614f06565b600060405180830381600087803b158015612bc457600080fd5b505af1158015612bd8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526128a7919081019061457e565b612c086135e7565b6000546001600160a01b03908116911614612c355760405162461bcd60e51b81526004016107f990615335565b60008160ff16118015612c4b575060148160ff16105b612c675760405162461bcd60e51b81526004016107f9906150bc565b6004805460ff191660ff92909216919091179055565b612c8561412a565b506001600160a01b038116600090815260056020908152604091829020825160a081018452905460ff8082161515808452610100830461ffff169484019490945263010000008204811694830194909452600160201b81049093166060820152600160281b9092046001600160401b03166080830152612d175760405162461bcd60e51b81526004016107f9906152a0565b62093a8081608001516001600160401b031642031015612d495760405162461bcd60e51b81526004016107f990615243565b60608101805160010160ff8116909152600316612d785760405162461bcd60e51b81526004016107f9906151ec565b600060036000836020015161ffff16815260200190815260200160002090506060836001600160a01b031663039209af6040518163ffffffff1660e01b815260040160006040518083038186803b158015612dd257600080fd5b505afa158015612de6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e0e91908101906144e1565b6001830154604051631a86165360e01b81529192506060916001600160a01b0390911690631a86165390612e46908590600401614e20565b60006040518083038186803b158015612e5e57600080fd5b505afa158015612e72573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e9a919081019061460a565b90506060612ea7826138ed565b426001600160401b03908116608088019081526001600160a01b0389166000818152600560209081526040918290208b518154928d0151848e015160608f0151975160ff199095169215159290921762ffff00191661010061ffff909216919091021763ff0000001916630100000060ff928316021764ff000000001916600160201b9190961602949094176cffffffffffffffff00000000001916600160281b9190951602939093179091559051635d5e8ce760e01b815291925090635d5e8ce790612f7a9086908590600401614ea8565b600060405180830381600087803b158015612f9457600080fd5b505af1158015612fa8573d6000803e3d6000fd5b505050507fd77c8f1facbb8968e28252bdd2dcbda2999951b599d2fb9858379b45d126eb78866040516126b29190614bad565b601981565b606080826002548111158015612ff65750600081115b6130125760405162461bcd60e51b81526004016107f99061542b565b60008481526003602090815260409182902060028101805484518185028101850190955280855291939290919083018282801561307857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161305a575b5050506001840154604051631a86165360e01b81529397506001600160a01b031692631a86165392506130b091508790600401614e20565b60006040518083038186803b1580156130c857600080fd5b505afa1580156130dc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613104919081019061460a565b815490935061312a90859085906001600160801b0380821691600160801b900416613d98565b5050915091565b6131396135e7565b6000546001600160a01b039081169116146131665760405162461bcd60e51b81526004016107f990615335565b6001600160a01b03811661318c5760405162461bcd60e51b81526004016107f99061503f565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461322f5760405162461bcd60e51b81526004016107f9906153b5565b60005b828110156108d657600084848381811061324857fe5b905060200201602081019061325d9190614291565b6001600160a01b03811660009081526005602052604090205490915060ff166132985760405162461bcd60e51b81526004016107f9906152a0565b604051631f3f2f9360e31b81526001600160a01b0382169063f9f97c98906132c4908690600401614bad565b600060405180830381600087803b1580156132de57600080fd5b505af11580156132f2573d6000803e3d6000fd5b505060019093019250613232915050565b7fe3d7c1179cc3f4ae9aab4e39c8923b411d4674dcb3d44aa456301be51bb24aef81565b60006114f67f0000000000000000000000000000000000000000000000000000000000000000307fe3d7c1179cc3f4ae9aab4e39c8923b411d4674dcb3d44aa456301be51bb24aef856040516020016114db9190614b11565b60006060826001600160a01b031663cc77828d6040518163ffffffff1660e01b815260040160006040518083038186803b1580156133bd57600080fd5b505afa1580156133d1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526133f991908101906144e1565b80519091506060816001600160401b038111801561341657600080fd5b50604051908082528060200260200182016040528015613440578160200160208202803683370190505b50905060005b828110156134fc5783818151811061345a57fe5b60200260200101516001600160a01b03166370a08231876040518263ffffffff1660e01b815260040161348d9190614bad565b60206040518083038186803b1580156134a557600080fd5b505afa1580156134b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134dd91906147b2565b8282815181106134e957fe5b6020908102919091010152600101613446565b50604051633e48351560e11b81526060906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637c906a2a9061355790879086906104b0906202a30090600401614e61565b60006040518083038186803b15801561356f57600080fd5b505afa158015613583573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526135ab919081019061460a565b905060005b838110156135dd578181815181106135c457fe5b60200260200101518601955080806001019150506135b0565b5050505050919050565b3390565b81546301000000810460ff1690606090819061361090610100900461ffff16846122db565b91509150600061361f85613380565b9050606481046060856001600160401b038111801561363d57600080fd5b50604051908082528060200260200182016040528015613667578160200160208202803683370190505b50905060005b86811015613695578282828151811061368257fe5b602090810291909101015260010161366d565b50604051630228300360e51b81526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906345060060906136f090899086906104b0906202a30090600401614e61565b60006040518083038186803b15801561370857600080fd5b505afa15801561371c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613744919081019061460a565b90506060613751866138ed565b8a546cffffffffffffffff00000000001916600160281b426001600160401b031602178b55604051630c3f468160e41b81529091506001600160a01b038a169063c3f46810906137a9908a9085908790600401614ecd565b600060405180830381600087803b1580156137c357600080fd5b505af11580156137d7573d6000803e3d6000fd5b505050507f3d5c3f9eb52a8b038ea739539d59ca565b416ec61363cde7ef167348260885598960405161380a9190614bad565b60405180910390a150505050505050505050565b6001600160a01b038116600090815260038301602052604090205460ff16156138595760405162461bcd60e51b81526004016107f9906150e1565b6001600160a01b0316600081815260038301602090815260408220805460ff191660019081179091556002909401805494850181558252902090910180546001600160a01b0319169091179055565b6000806138b6858585613f73565b90506138e3817fa035ad05a1663db5bfd455b99cd7c6ac6bd49269738458eda140e0b78ed53f7988613fa9565b9695505050505050565b8051606090600090806001600160401b038111801561390b57600080fd5b50604051908082528060200260200182016040528015613935578160200160208202803683370190505b50925060005b818110156139735761396985828151811061395257fe5b602002602001015184613fe890919063ffffffff16565b925060010161393b565b5060005b818110156139ec576139c06139bb846139b568015af1d78b58c4000089868151811061399f57fe5b602002602001015161400d90919063ffffffff16565b90614047565b614089565b8482815181106139cc57fe5b6001600160601b0390921660209283029190910190910152600101613977565b505050919050565b8051606090600090806001600160401b0381118015613a1257600080fd5b50604051908082528060200260200182016040528015613a3c578160200160208202803683370190505b50925060005b81811015613a6357613a5985828151811061395257fe5b9250600101613a42565b50670de0b6b3a764000080830290860260005b83811015613ab157613a92836139b5848a858151811061399f57fe5b868281518110613a9e57fe5b6020908102919091010152600101613a76565b505050505092915050565b6000546001600160a01b031615613ae55760405162461bcd60e51b81526004016107f99061536a565b6000613aef6135e7565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350565b8351606090600090806001600160401b0381118015613b5957600080fd5b50604051908082528060200260200182016040528015613b83578160200160208202803683370190505b50925060005b81811015613d7b576000878281518110613b9f57fe5b602002602001015190506000898381518110613bb757fe5b6020026020010151905086821180613bce57508782105b15613c825780868680600101975081518110613be657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505089846001900394508481518110613c1957fe5b60200260200101519050888481518110613c2f57fe5b6020026020010151915081898481518110613c4657fe5b602002602001018181525050808a8481518110613c5f57fe5b6001600160a01b0390921660209283029190910190910152505060001901613d73565b60001983015b60008112158015613cab5750828a8281518110613ca157fe5b6020026020010151105b15613d2357898181518110613cbc57fe5b60200260200101518a8260010181518110613cd357fe5b6020026020010181815250508a8181518110613ceb57fe5b60200260200101518b8260010181518110613d0257fe5b6001600160a01b039092166020928302919091019091015260001901613c88565b828a8260010181518110613d3357fe5b602002602001018181525050818b8260010181518110613d4f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505050505b600101613b89565b5086518114613d8e578087528086528183525b5050949350505050565b835160005b81811015613f5c576000858281518110613db357fe5b602002602001015190506000878381518110613dcb57fe5b6020026020010151905084821180613de257508582105b15613e635787846001900394508481518110613dfa57fe5b60200260200101519050868481518110613e1057fe5b6020026020010151915081878481518110613e2757fe5b60200260200101818152505080888481518110613e4057fe5b6001600160a01b0390921660209283029190910190910152505060001901613f54565b60001983015b60008112158015613e8c575082888281518110613e8257fe5b6020026020010151105b15613f0457878181518110613e9d57fe5b6020026020010151888260010181518110613eb457fe5b602002602001018181525050888181518110613ecc57fe5b6020026020010151898260010181518110613ee357fe5b6001600160a01b039092166020928302919091019091015260001901613e69565b82888260010181518110613f1457fe5b60200260200101818152505081898260010181518110613f3057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250505050505b600101613d9d565b5084518114613f6c578085528084525b5050505050565b6000838383604051602001613f8a93929190614b46565b6040516020818303038152906040528051906020012090509392505050565b60008060ff60f81b838686604051602001613fc79493929190614b6b565b60408051808303601f19018152919052805160209091012095945050505050565b6000828201838110156128a75760405162461bcd60e51b81526004016107f990615085565b60008261401c575060006114f6565b8282028284828161402957fe5b04146128a75760405162461bcd60e51b81526004016107f9906152f4565b60006128a783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506140b7565b806001600160601b03811681146140b25760405162461bcd60e51b81526004016107f9906152cc565b919050565b600081836140d85760405162461bcd60e51b81526004016107f99190614fec565b5060008385816140e457fe5b0495945050505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b8280548282559060005260206000209081019282156141ad579160200282015b828111156141ad57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614178565b506141b99291506141bd565b5090565b5b808211156141b95780546001600160a01b03191681556001016141be565b60008083601f8401126141ed578182fd5b5081356001600160401b03811115614203578182fd5b602083019150836020808302850101111561421d57600080fd5b9250929050565b60008083601f840112614235578182fd5b5081356001600160401b0381111561424b578182fd5b60208301915083602082850101111561421d57600080fd5b80356001600160801b03811681146114f657600080fd5b80516001600160601b03811681146114f657600080fd5b6000602082840312156142a2578081fd5b81356128a78161560d565b6000602082840312156142be578081fd5b81516128a78161560d565b600080604083850312156142db578081fd5b82356142e68161560d565b915060208301356142f68161560d565b809150509250929050565b600080600060608486031215614315578081fd5b83356143208161560d565b925060208401356143308161560d565b915060408401356143408161560d565b809150509250925092565b600080600080600060608688031215614362578283fd5b853561436d8161560d565b945060208601356001600160401b0380821115614388578485fd5b61439489838a016141dc565b909650945060408801359150808211156143ac578283fd5b506143b9888289016141dc565b969995985093965092949392505050565b600080604083850312156143dc578182fd5b82356143e78161560d565b915060208301356142f681615625565b60008060408385031215614409578182fd5b82356144148161560d565b946020939093013593505050565b60008060408385031215614434578182fd5b823561443f8161560d565b915060208301356142f681615633565b600080600060408486031215614463578081fd5b83356001600160401b03811115614478578182fd5b614484868287016141dc565b90945092505060208401356143408161560d565b6000806000604084860312156144ac578081fd5b83356001600160401b038111156144c1578182fd5b6144cd868287016141dc565b909790965060209590950135949350505050565b600060208083850312156144f3578182fd5b82516001600160401b03811115614508578283fd5b8301601f81018513614518578283fd5b805161452b614526826155ee565b6155c8565b8181528381019083850185840285018601891015614547578687fd5b8694505b8385101561457257805161455e8161560d565b83526001949094019391850191850161454b565b50979650505050505050565b60006020808385031215614590578182fd5b82516001600160401b038111156145a5578283fd5b8301601f810185136145b5578283fd5b80516145c3614526826155ee565b81815283810190838501858402850186018910156145df578687fd5b8694505b838510156145725780516145f681615625565b8352600194909401939185019185016145e3565b6000602080838503121561461c578182fd5b82516001600160401b03811115614631578283fd5b8301601f81018513614641578283fd5b805161464f614526826155ee565b818152838101908385018584028501860189101561466b578687fd5b8694505b8385101561457257805183526001949094019391850191850161466f565b60006020828403121561469e578081fd5b81516128a781615625565b600080600080608085870312156146be578182fd5b8435935060208501356146d08161560d565b92506146df8660408701614263565b91506146ee8660608701614263565b905092959194509250565b600060e0828403121561470a578081fd5b61471460e06155c8565b825161471f81615625565b8152602083015161472f81615625565b6020820152604083015164ffffffffff8116811461474b578283fd5b604082015261475d846060850161427a565b606082015261476f846080850161427a565b608082015260a083015161478281615633565b60a082015260c0928301519281019290925250919050565b6000602082840312156147ab578081fd5b5035919050565b6000602082840312156147c3578081fd5b5051919050565b600080604083850312156147dc578182fd5b8235915060208301356142f68161560d565b600080600060408486031215614802578081fd5b8335925060208401356001600160401b0381111561481e578182fd5b61482a868287016141dc565b9497909650939450505050565b60008060408385031215614849578182fd5b823591506020808401356001600160401b03811115614866578283fd5b8401601f81018613614876578283fd5b8035614884614526826155ee565b81815283810190838501858402850186018a10156148a0578687fd5b8694505b838510156148cb5780356148b78161560d565b8352600194909401939185019185016148a4565b5080955050505050509250929050565b600080604083850312156148ed578182fd5b50508035926020909101359150565b600080600060608486031215614910578081fd5b505081359360208301359350604090920135919050565b600080600080600080600060a0888a031215614941578485fd5b87359650602088013595506040880135945060608801356001600160401b038082111561496c578384fd5b6149788b838c01614224565b909650945060808a0135915080821115614990578384fd5b5061499d8a828b01614224565b989b979a50959850939692959293505050565b6000602082840312156149c1578081fd5b81356128a781615633565b60008284526020808501945082825b85811015614a095781356149ee8161560d565b6001600160a01b0316875295820195908201906001016149db565b509495945050505050565b6000815180845260208085019450808401835b83811015614a095781516001600160a01b031687529582019590820190600101614a27565b81835260006001600160fb1b03831115614a64578081fd5b6020830280836020870137939093016020019283525090919050565b6000815180845260208085019450808401835b83811015614a0957815187529582019590820190600101614a93565b6000815180845260208085019450808401835b83811015614a095781516001600160601b031687529582019590820190600101614ac2565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60609190911b6001600160601b031916815260140190565b60609290921b6001600160601b0319168252601482015260340190565b60609390931b6001600160601b03191683526014830191909152603482015260540190565b6001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b03858116825284166020820152608060408201819052600090614c0790830185614a14565b8281036060840152614c198185614a80565b979650505050505050565b6001600160a01b03948516815292909316602083015261ffff16604082015260ff909116606082015260800190565b6001600160a01b0394851681529290931660208301526040820152606081019190915260800190565b6001600160a01b03938416815291909216602082015260ff909116604082015260600190565b6001600160a01b0386168152606060208201819052600090614cc79083018688614ae7565b8281036040840152614cda818587614ae7565b98975050505050505050565b6001600160a01b039390931683526001600160801b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03949094168452602084019290925263ffffffff908116604084015216606082015260800190565b600060208252610ea26020830184866149cc565b600060c08252614d8060c083018a8c6149cc565b8281036020840152614d9381898b614a4c565b90508281036040840152614da78188614aaf565b6001600160a01b03968716606085015294861660808401525050921660a09092019190915295945050505050565b600060808252614de960808301888a6149cc565b8281036020840152614dfc818789614a4c565b91505063ffffffff8085166040840152808416606084015250979650505050505050565b6000602082526128a76020830184614a14565b600060408252614e466040830185614a14565b8281036020840152614e588185614a80565b95945050505050565b600060808252614e746080830187614a14565b8281036020840152614e868187614a80565b91505063ffffffff808516604084015280841660608401525095945050505050565b600060408252614ebb6040830185614a14565b8281036020840152614e588185614aaf565b600060608252614ee06060830186614a14565b8281036020840152614ef28186614aaf565b905082810360408401526138e38185614a80565b6020808252825482820181905260008481528281209092916040850190845b81811015614f4a5783546001600160a01b031683526001938401939285019201614f25565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614f4a578351151583529284019291840191600101614f72565b6000602082526128a76020830184614a80565b901515815260200190565b941515855261ffff93909316602085015260ff91821660408501521660608301526001600160401b0316608082015260a00190565b90815260200190565b6000602080835283518082850152825b8181101561501857858101830151858201604001528201614ffc565b818111156150295783604083870101525b50601f01601f1916929092016040019392505050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252600b908201526a4552525f5052454d49554d60a81b604082015260600190565b6020808252600f908201526e11549497d513d2d15397d093d55391608a1b604082015260600190565b60208082526017908201527f4552525f4e4f545f5052455f4445504c4f595f504f4f4c000000000000000000604082015260600190565b60208082526013908201527211549497d513d2d15397d393d517d093d55391606a1b604082015260600190565b6020808252600f908201526e4552525f4d494e5f42414c414e434560881b604082015260600190565b6020808252601290820152714552525f4d41585f494e4445585f53495a4560701b604082015260600190565b6020808252600f908201526e11549497d253925512505312569151608a1b604082015260600190565b60208082526011908201527008aa4a4bea48aae8a928e90be929c888ab607b1b604082015260600190565b60208082526012908201527111549497d393d517d055551213d49256915160721b604082015260600190565b6020808252601690820152754552525f504f4f4c5f524557454947485f44454c415960501b604082015260600190565b6020808252601390820152724552525f4d41585f4c4953545f544f4b454e5360681b604082015260600190565b60208082526012908201527111549497d413d3d317d393d517d193d5539160721b604082015260600190565b6020808252600e908201526d22a9292fa6a0ac2faaa4a72a1c9b60911b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252602b908201527f4f776e61626c653a206f776e65722068617320616c7265616479206265656e2060408201526a1a5b9a5d1a585b1a5e995960aa1b606082015260800190565b6020808252601290820152714552525f4e4f545f474f5645524e414e434560701b604082015260600190565b6020808252600b908201526a22a9292fa0a9292fa622a760a91b604082015260600190565b6020808252600b908201526a04552525f4d41585f4341560ac1b604082015260600190565b6020808252600b908201526a11549497d31254d517d25160aa1b604082015260600190565b6020808252600e908201526d11549497d15354151657d31254d560921b604082015260600190565b60208082526010908201526f4552525f4e554c4c5f4144445245535360801b604082015260600190565b6020808252600f908201526e4552525f544f4b454e5f524541445960881b604082015260600190565b60208082526010908201526f04552525f4e554c4c5f4d494e5f4341560841b604082015260600190565b6020808252600d908201526c4552525f4c4953545f53495a4560981b604082015260600190565b6020808252601290820152714552525f4d494e5f494e4445585f53495a4560701b604082015260600190565b6020808252600f908201526e11549497d3505617d55253950c4d0d608a1b604082015260600190565b94855260208501939093526001600160a01b039190911660408401526001600160801b03908116606084015216608082015260a00190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b6040518181016001600160401b03811182821017156155e657600080fd5b604052919050565b60006001600160401b03821115615603578081fd5b5060209081020190565b6001600160a01b038116811461562257600080fd5b50565b801515811461562257600080fd5b60ff8116811461562257600080fdfea2646970667358221220d813aa869f556a334393860eb8f373cf6c7ba822c879c7db351770795f9679fe64736f6c634300060c003300000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b00000000000000000000000083a3451a569e941e2ddb79942f404c126a1b56bf000000000000000000000000592f70ce43a310d15ff59be1460f38ab6df3fe65000000000000000000000000dedefb37b5a5d8e2b357dbaf5983b0fd78fe120e

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

00000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b00000000000000000000000083a3451a569e941e2ddb79942f404c126a1b56bf000000000000000000000000592f70ce43a310d15ff59be1460f38ab6df3fe65000000000000000000000000dedefb37b5a5d8e2b357dbaf5983b0fd78fe120e

-----Decoded View---------------
Arg [0] : uniswapOracle_ (address): 0x95129751769f99cc39824a0793ef4933dd8bb74b
Arg [1] : poolFactory_ (address): 0x83a3451a569e941e2ddb79942f404c126a1b56bf
Arg [2] : proxyManager_ (address): 0x592f70ce43a310d15ff59be1460f38ab6df3fe65
Arg [3] : governance_ (address): 0xdedefb37b5a5d8e2b357dbaf5983b0fd78fe120e

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b
Arg [1] : 00000000000000000000000083a3451a569e941e2ddb79942f404c126a1b56bf
Arg [2] : 000000000000000000000000592f70ce43a310d15ff59be1460f38ab6df3fe65
Arg [3] : 000000000000000000000000dedefb37b5a5d8e2b357dbaf5983b0fd78fe120e


Deployed ByteCode Sourcemap

2698:17977:10:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12760:402;;;;;;:::i;:::-;;:::i;:::-;;13370:555;;;;;;:::i;:::-;;:::i;15284:322::-;;;;;;:::i;:::-;;:::i;1562:54:9:-;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9714:371;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;5278:29:10:-;;;:::i;11739:203::-;;;;;;:::i;:::-;;:::i;14401:266::-;;;;;;:::i;:::-;;:::i;818:82:8:-;;;:::i;:::-;;;;;;;:::i;10089:243:9:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5843:664::-;;;;;;:::i;:::-;;:::i;7333:228:10:-;;;;;;:::i;:::-;;:::i;5113:33::-;;;:::i;:::-;;;;;;;:::i;1072:49:8:-;;;:::i;8631:168:9:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2868:41:10:-;;;:::i;14854:426::-;;;;;;:::i;:::-;;:::i;1175:63:8:-;;;:::i;:::-;;;;;;;:::i;4724:335:9:-;;;;;;:::i;:::-;;:::i;18081:309:10:-;;;;;;:::i;:::-;;:::i;3027:35::-;;;:::i;9731:1317::-;;;;;;:::i;:::-;;:::i;5215:474:9:-;;;;;;:::i;:::-;;:::i;2227:280:7:-;;;:::i;7884:1472:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;19072:713::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;11484:179::-;;;;;;:::i;:::-;;:::i;3646:70:9:-;;;:::i;7142:114:10:-;;;;;;:::i;:::-;;:::i;946:52:8:-;;;:::i;8980:396:9:-;;;;;;:::i;:::-;;:::i;342:41:8:-;;;:::i;7034:645:9:-;;;;;;:::i;:::-;;:::i;3935:638::-;;;;;;:::i;:::-;;:::i;8387:179::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1644:71:7:-;;;:::i;2943:55:10:-;;;:::i;12531:167::-;;;;;;:::i;:::-;;:::i;18456:396::-;;;;;;:::i;:::-;;:::i;5183:58::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;1242:59:8:-;;;:::i;2961:29:9:-;;;:::i;5356:38:10:-;;;:::i;228:43:8:-;;;:::i;138:42::-;;;:::i;6552:149:10:-;;;;;;:::i;:::-;;:::i;648:93:8:-;;;:::i;14032:227:10:-;;;;;;:::i;:::-;;:::i;2857:61:9:-;;;:::i;11181:239:10:-;;;;;;:::i;:::-;;:::i;6661:203:9:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;6830:221:10:-;;;;;;:::i;:::-;;:::i;16657:884::-;;;;;;:::i;:::-;;:::i;1488:44:9:-;;;:::i;7798:439::-;;;;;;:::i;:::-;;:::i;2646:226:7:-;;;;;;:::i;:::-;;:::i;12024:438:10:-;;;;;;:::i;:::-;;:::i;466:95:8:-;;;:::i;17663:329:10:-;;;;;;:::i;:::-;;:::i;12760:402::-;5813:10;-1:-1:-1;;;;;5827:10:10;5813:24;;5805:55;;;;-1:-1:-1;;;5805:55:10;;;;;;;:::i;:::-;;;;;;;;;12866:9:::1;12861:297;12881:24:::0;;::::1;12861:297;;;12920:19;12942:13;;12956:1;12942:16;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;12974:30:10;::::1;;::::0;;;:17:::1;:30;::::0;;;;:42;12920:38;;-1:-1:-1;12974:42:10::1;;12966:73;;;;-1:-1:-1::0;;;12966:73:10::1;;;;;;;:::i;:::-;13108:43;::::0;-1:-1:-1;;;13108:43:10;;-1:-1:-1;;;;;13108:34:10;::::1;::::0;::::1;::::0;:43:::1;::::0;13143:7;;13108:43:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;12907:3:10::1;::::0;;::::1;::::0;-1:-1:-1;12861:297:10::1;::::0;-1:-1:-1;;12861:297:10::1;;;12760:402:::0;;;:::o;13370:555::-;-1:-1:-1;;;;;5507:30:10;;;;;;:17;:30;;;;;:42;13471:4;;5507:42;;5492:91;;;;-1:-1:-1;;;5492:91:10;;;;;;;:::i;:::-;13484:31:::1;;:::i;:::-;13518:45;::::0;-1:-1:-1;;;13518:45:10;;-1:-1:-1;;;;;13518:31:10;::::1;::::0;::::1;::::0;:45:::1;::::0;13550:12;;13518:45:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13484:79;;13578:6;:12;;;13577:13;13569:41;;;;-1:-1:-1::0;;;13569:41:10::1;;;;;;;:::i;:::-;13616:17;13636:24;13655:4;13636:18;:24::i;:::-;13616:44:::0;-1:-1:-1;13666:22:10::1;-1:-1:-1::0;;;;;13691:13:10::1;:40;;13739:12:::0;13771:3:::1;13616:44:::0;13759:15:::1;1228:10:8;1295:6;13691:159:10;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13856:64;::::0;-1:-1:-1;;;13856:64:10;;13666:184;;-1:-1:-1;;;;;;13856:34:10;::::1;::::0;::::1;::::0;:64:::1;::::0;13891:12;;13666:184;;13856:64:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;5589:1;;;13370:555:::0;;;:::o;15284:322::-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;-1:-1:-1;;;;;15385:30:10;::::1;15356:26;15385:30:::0;;;:17:::1;:30;::::0;;;;15488:19;;-1:-1:-1;;;15488:19:10;;::::1;:29;:19:::0;;::::1;15463:1;15488:19;::::0;;::::1;::::0;::::1;-1:-1:-1::0;;15488:19:10;;::::1;;15524:40:::0;;::::1;15488:29:::0;;;;15437:27;15545:19;;::::1;15524:40:::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;15570:31:::1;15385:30:::0;;15570:12:::1;:31::i;1562:54:9:-:0;;;:::o;9714:371::-;9827:23;9858:20;9886;9799:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;-1:-1:-1;;;9921:22:9::1;9946:14:::0;;;-1:-1:-1;9946:6:9::1;:14;::::0;;;;9984:20:::1;::::0;::::1;::::0;10025:17;;-1:-1:-1;;;;;9984:20:9;;::::1;::::0;-1:-1:-1;;;;;10025:17:9;;::::1;::::0;-1:-1:-1;;;10063:17:9;::::1;;::::0;9714:371::o;5278:29:10:-;;;-1:-1:-1;;;;;5278:29:10;;:::o;11739:203::-;-1:-1:-1;;;;;5507:30:10;;;;;;:17;:30;;;;;:42;11842:11;;5507:42;;5492:91;;;;-1:-1:-1;;;5492:91:10;;;;;;;:::i;:::-;5813:10:::1;-1:-1:-1::0;;;;;5827:10:10::1;5813:24;;5805:55;;;;-1:-1:-1::0;;;5805:55:10::1;;;;;;;:::i;:::-;11876:61:::2;::::0;-1:-1:-1;;;11876:61:10;;-1:-1:-1;;;;;11876:43:10;::::2;::::0;::::2;::::0;:61:::2;::::0;11920:16;;11876:61:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;11739:203:::0;;;:::o;14401:266::-;-1:-1:-1;;;;;5507:30:10;;;;;;:17;:30;;;;;:42;14488:10;;5507:42;;5492:91;;;;-1:-1:-1;;;5492:91:10;;;;;;;:::i;:::-;14535:14:::1;::::0;-1:-1:-1;;;;;14535:14:10::1;14521:10;:28;::::0;:53:::1;;;14567:7;:5;:7::i;:::-;-1:-1:-1::0;;;;;14553:21:10::1;:10;-1:-1:-1::0;;;;;14553:21:10::1;;14521:53;14506:102;;;;-1:-1:-1::0;;;14506:102:10::1;;;;;;;:::i;:::-;14614:48;::::0;-1:-1:-1;;;14614:48:10;;-1:-1:-1;;;;;14614:36:10;::::1;::::0;::::1;::::0;:48:::1;::::0;14651:10;;14614:48:::1;;;:::i;818:82:8:-:0;867:33;818:82;:::o;10089:243:9:-;10214:23;10193:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;10273:14:::1;::::0;;;:6:::1;:14;::::0;;;;;;:30:::1;;::::0;10256:71;;-1:-1:-1;;;10256:71:9;;-1:-1:-1;;;;;10273:30:9;;::::1;::::0;10256:63:::1;::::0;:71:::1;::::0;10320:6;;10256:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;10256:71:9::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;10247:80:::0;10089:243;-1:-1:-1;;;;10089:243:9:o;5843:664::-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;5929:6:9::1;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1::0;;;3129:62:9::1;;;;;;;:::i;:::-;5943:22:::2;5968:14:::0;;;:6:::2;:14;::::0;;;;6021:11:::2;::::0;::::2;:18:::0;5968:14;;5943:22;6053:7;6045:34:::2;;;;-1:-1:-1::0;;;6045:34:9::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;6093:27:9;::::2;;::::0;;;:20:::2;::::0;::::2;:27;::::0;;;;;::::2;;6085:59;;;;-1:-1:-1::0;;;6085:59:9::2;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;6150:27:9;::::2;6180:5;6150:27:::0;;;:20:::2;::::0;::::2;:27;::::0;;;;:35;;-1:-1:-1;;6150:35:9::2;::::0;;6191:312:::2;6202:3;6198:1;:7;6191:312;;;6242:5;-1:-1:-1::0;;;;;6224:23:9::2;:4;:11;;6236:1;6224:14;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;-1:-1:-1;;;;;6224:14:9::2;:23;6220:277;;;-1:-1:-1::0;;6274:7:9;;6295:9;;::::2;6291:113;;6318:17;6338:4;:11;;6350:4;6338:17;;;;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;6367:11:::2;::::0;::::2;:14:::0;;-1:-1:-1;;;;;6338:17:9;;::::2;::::0;-1:-1:-1;6338:17:9;;6379:1;;6367:14;::::2;;;;;;;;;;;;;:26;;;;;-1:-1:-1::0;;;;;6367:26:9::2;;;;;-1:-1:-1::0;;;;;6367:26:9::2;;;;;;6291:113;;6413:4;:11;;:17;;;;;;;;::::0;;;::::2;::::0;;;;-1:-1:-1;;6413:17:9;;;;;-1:-1:-1;;;;;;6413:17:9::2;::::0;;;;;6445:27:::2;::::0;::::2;::::0;::::2;::::0;6458:5;;6465:6;;6445:27:::2;:::i;:::-;;;;;;;;6482:7;;;;;;6220:277;6207:3;::::0;;::::2;::::0;6191:312:::2;;;3197:1;;;;1895::7::1;5843:664:9::0;;:::o;7333:228:10:-;5813:10;-1:-1:-1;;;;;5827:10:10;5813:24;;5805:55;;;;-1:-1:-1;;;5805:55:10;;;;;;;:::i;:::-;-1:-1:-1;;;;;7441:38:10;::::1;7433:67;;;;-1:-1:-1::0;;;7433:67:10::1;;;;;;;:::i;:::-;7506:23;:50:::0;;-1:-1:-1;;;;;;7506:50:10::1;-1:-1:-1::0;;;;;7506:50:10;;;::::1;::::0;;;::::1;::::0;;7333:228::o;5113:33::-;;;;;;:::o;1072:49:8:-;1120:1;1072:49;:::o;8631:168:9:-;8731:23;8710:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;8773:14:::1;::::0;;;:6:::1;:14;::::0;;;;;;;;:21:::1;;8764:30:::0;;;;;;::::1;::::0;;;;;;;;;;8773:21;;8764:30;::::1;8773:21:::0;8764:30;;::::1;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;8764:30:9::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;;8631:168:::0;;;;:::o;2868:41:10:-;;;:::o;14854:426::-;-1:-1:-1;;;;;14940:30:10;;14911:26;14940:30;;;:17;:30;;;;;14984:16;;;;14976:47;;;;-1:-1:-1;;;14976:47:10;;;;;;;:::i;:::-;15050:16;;991:7:8;-1:-1:-1;;;15050:16:10;;;-1:-1:-1;;;;;15050:16:10;15044:3;:22;:44;;15029:97;;;;-1:-1:-1;;;15029:97:10;;;;;;;:::i;:::-;15148:19;;-1:-1:-1;;15148:19:10;;15197:1;15148:51;-1:-1:-1;;;15148:19:10;;;;;;;;;;;;;;;;;;;:51;;15147:58;15132:106;;;;-1:-1:-1;;;15132:106:10;;;;;;;:::i;:::-;15244:31;15257:4;15263:11;15244:12;:31::i;:::-;14854:426;;:::o;1175:63:8:-;1228:10;1175:63;:::o;4724:335:9:-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;4807:6:9::1;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1::0;;;3129:62:9::1;;;;;;;:::i;:::-;4821:22:::2;4846:14:::0;;;:6:::2;:14;::::0;;;;4881:11:::2;::::0;::::2;:18:::0;1530:2:::2;-1:-1:-1::0;4866:86:9::2;;;;-1:-1:-1::0;;;4866:86:9::2;;;;;;;:::i;:::-;4958:22;4968:4;4974:5;4958:9;:22::i;:::-;4986:32;::::0;-1:-1:-1;;;4986:32:9;;-1:-1:-1;;;;;4986:13:9::2;:25;::::0;::::2;::::0;:32:::2;::::0;5012:5;;4986:32:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;5029:25;5040:5;5047:6;5029:25;;;;;;;:::i;:::-;;;;;;;;3197:1;1895::7::1;4724:335:9::0;;:::o;18081:309:10:-;18165:21;18212:173;18265:12;18294:4;699:42:8;18366:11:10;18349:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;18339:40;;;;;;18212:37;:173::i;:::-;18196:189;18081:309;-1:-1:-1;;18081:309:10:o;3027:35::-;;;:::o;9731:1317::-;9890:11;5680:38;5706:11;5680:25;:38::i;:::-;-1:-1:-1;;;;;5666:52:10;:10;-1:-1:-1;;;;;5666:52:10;;5651:106;;;;-1:-1:-1;;;5651:106:10;;;;;;;:::i;:::-;9925:6;9952:22;;::::1;9944:46;;;;-1:-1:-1::0;;;9944:46:10::1;;;;;;;:::i;:::-;9997:25;;:::i;:::-;-1:-1:-1::0;;;;;;10025:30:10;::::1;;::::0;;;:17:::1;:30;::::0;;;;;;;;9997:58;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;::::0;::::1;::::0;;::::1;::::0;::::1;;;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;-1:-1:-1;;;9997:58:10;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;;;9997:58:10;;::::1;-1:-1:-1::0;;;;;9997:58:10::1;::::0;;;;10061:45:::1;;;;-1:-1:-1::0;;;10061:45:10::1;;;;;;;:::i;:::-;10142:146;::::0;-1:-1:-1;;;10142:146:10;;10113:26:::1;::::0;-1:-1:-1;;;;;10142:13:10::1;:40;::::0;::::1;::::0;:146:::1;::::0;10190:6;;;;10204:8;;;;1228:10:8::1;::::0;1295:6:::1;::::0;10142:146:10::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;10142:146:10::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;10113:175;;10294:35;10332:38;:9;:36;:38::i;:::-;10294:76;;10377:21;10401:12;-1:-1:-1::0;;;;;10401:33:10::1;;699:42:8;10501:11:10;10484:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;10474:40;;;;;;10401:119;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10665:23;::::0;10527:167:::1;::::0;-1:-1:-1;;;10527:167:10;;10377:143;;-1:-1:-1;;;;;;10527:34:10;;::::1;::::0;::::1;::::0;:167:::1;::::0;10569:6;;;;10583:8;;;;10599:19;;10626:10:::1;::::0;10377:143;;10665:23;::::1;::::0;10527:167:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;10721:13;-1:-1:-1::0;;;;;10701:45:10::1;;10762:4;10775:11;10794:20;;;;;;;;;;;10701:119;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;;10853:3:10::1;-1:-1:-1::0;;;;;10827:30:10;;::::1;:16;::::0;::::1;:30:::0;;;10882:4:::1;10863:23:::0;;-1:-1:-1;;;;;10892:30:10;::::1;-1:-1:-1::0;10892:30:10;;;:17:::1;:30;::::0;;;;;;;;:37;;;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;;;-1:-1:-1;;10892:37:10;;::::1;::::0;::::1;;::::0;;;::::1;-1:-1:-1::0;;10892:37:10::1;;;::::0;::::1;;;-1:-1:-1::0;;10892:37:10::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;10892:37:10::1;-1:-1:-1::0;;;10892:37:10;;;::::1;;::::0;;;::::1;-1:-1:-1::0;;10892:37:10::1;-1:-1:-1::0;;;10892:37:10;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;10941:102;::::1;::::0;-1:-1:-1;10941:102:10::1;::::0;10892:30;;10983:13;;10892:37;;;10941:102:::1;:::i;:::-;;;;;;;;5763:1;;;;;9731:1317:::0;;;;;;:::o;5215:474:9:-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;5323:6:9::1;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1::0;;;3129:62:9::1;;;;;;;:::i;:::-;5339:22:::2;5364:14:::0;;;:6:::2;:14;::::0;;;;5399:11:::2;::::0;::::2;:18:::0;1530:2:::2;5399:34:::0;;::::2;:53;;5384:103;;;;-1:-1:-1::0;;;5384:103:9::2;;;;;;;:::i;:::-;5498:9;5493:152;5513:17:::0;;::::2;5493:152;;;5545:13;5561:6;;5568:1;5561:9;;;;;;;;;;;;;;;;;;;;:::i;:::-;5545:25;;5578:22;5588:4;5594:5;5578:9;:22::i;:::-;5613:25;5624:5;5631:6;5613:25;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;5532:3:9::2;;5493:152;;;-1:-1:-1::0;5650:34:9::2;::::0;-1:-1:-1;;;5650:34:9;;-1:-1:-1;;;;;5650:13:9::2;:26;::::0;::::2;::::0;:34:::2;::::0;5677:6;;;;5650:34:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;-1:-1:-1::0;;5650:34:9::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;2227:280:7:-:0;1840:12;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;2458:6:::1;::::0;;2437:40:::1;::::0;2474:1:::1;::::0;-1:-1:-1;;;;;2458:6:7;;::::1;::::0;2437:40:::1;::::0;::::1;2483:6;:19:::0;;-1:-1:-1;;;;;;2483:19:7::1;2500:1;2483:19;::::0;;2227:280::o;7884:1472:10:-;8081:19;8102:26;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;179:1:8::1;8146:9:10;:27;;8138:58;;;;-1:-1:-1::0;;;8138:58:10::1;;;;;;;:::i;:::-;269:2:8;8210:9:10;:27;;8202:58;;;;-1:-1:-1::0;;;8202:58:10::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8274:30:10;::::1;8266:58;;;;-1:-1:-1::0;;;8266:58:10::1;;;;;;;:::i;:::-;8345:11;-1:-1:-1::0;;;;;8345:22:10::1;;867:33:8;8432:6:10;8440:9;8415:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;8405:46;;;;;;8345:112;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8463:62;::::0;-1:-1:-1;;;8463:62:10;;8331:126;;-1:-1:-1;;;;;;8463:33:10;::::1;::::0;::::1;::::0;:62:::1;::::0;8505:4:::1;::::0;8512;;;;8518:6;;;;8463:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;8565:157;;;;;;;;8600:5;8565:157;;;;;;8628:6;8565:157;;;;;;8660:9;8565:157;;;;;;8714:1;8565:157;;;;;;8691:1;-1:-1:-1::0;;;;;8565:157:10::1;;;::::0;8532:17:::1;:30;8550:11;-1:-1:-1::0;;;;;8532:30:10::1;-1:-1:-1::0;;;;;8532:30:10::1;;;;;;;;;;;;:190;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;8532:190:10::1;;;;;-1:-1:-1::0;;;;;8532:190:10::1;;;;;;;;;8750:12;-1:-1:-1::0;;;;;8750:33:10::1;;522:39:8;8855:11:10;8838:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;8828:40;;;;;;8750:124;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8729:145:::0;-1:-1:-1;8729:145:10;9013:23:::1;::::0;9067:97:::1;9102:6:::0;9116:9;-1:-1:-1;;;;;9067:97:10;::::1;:27;:97::i;:::-;9171:68;::::0;-1:-1:-1;;;9171:68:10;;9012:152;;-1:-1:-1;9012:152:10;-1:-1:-1;;;;;;9171:22:10;::::1;::::0;::::1;::::0;:68:::1;::::0;9202:4:::1;::::0;9209:11;;9012:152;;;;9171:68:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;9251:100;9277:11;9296:18;9322:6;9336:9;9251:100;;;;;;;;;:::i;:::-;;;;;;;;1895:1:7;;;7884:1472:10::0;;;;;;;;;;:::o;19072:713::-;19219:23;19250:25;19290:23;19338:40;19360:6;19368:9;19338:21;:40::i;:::-;19319:59;;-1:-1:-1;19319:59:10;-1:-1:-1;19384:34:10;19421:44;:9;19319:59;19421:36;:44::i;:::-;19482:155;;-1:-1:-1;;;19482:155:10;;19384:81;;-1:-1:-1;;;;;;19482:13:10;:40;;;;:155;;19530:6;;19384:81;;1228:10:8;;1295:6;;19482:155:10;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;19482:155:10;;;;;;;;;;;;:::i;:::-;19657:15;;19471:166;;-1:-1:-1;19643:11:10;19678:103;19702:3;19698:1;:7;19678:103;;;380:3:8;19728:8:10;19737:1;19728:11;;;;;;;;;;;;;;:26;;19720:54;;;;-1:-1:-1;;;19720:54:10;;;;;;;:::i;:::-;19707:3;;19678:103;;;;19072:713;;;;;;;;;:::o;11484:179::-;-1:-1:-1;;;;;5507:30:10;;;;;;:17;:30;;;;;:42;11575:11;;5507:42;;5492:91;;;;-1:-1:-1;;;5492:91:10;;;;;;;:::i;:::-;5813:10:::1;-1:-1:-1::0;;;;;5827:10:10::1;5813:24;;5805:55;;;;-1:-1:-1::0;;;5805:55:10::1;;;;;;;:::i;:::-;11609:49:::2;::::0;-1:-1:-1;;;11609:49:10;;-1:-1:-1;;;;;11609:37:10;::::2;::::0;::::2;::::0;:49:::2;::::0;11647:10;;11609:49:::2;;;:::i;3646:70:9:-:0;3689:22;:20;:22::i;:::-;3646:70::o;7142:114:10:-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;7219:14:10::1;:32:::0;;-1:-1:-1;;;;;;7219:32:10::1;-1:-1:-1::0;;;;;7219:32:10;;;::::1;::::0;;;::::1;::::0;;7142:114::o;946:52:8:-;991:7;946:52;:::o;8980:396:9:-;9109:23;9140;9081:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;9197:43:::1;9233:6;9197:35;:43::i;:::-;9263:13:::0;;9178:62;;-1:-1:-1;9178:62:9;-1:-1:-1;9254:22:9;::::1;;9246:48;;;;-1:-1:-1::0;;;9246:48:9::1;;;;;;;:::i;:::-;-1:-1:-1::0;9317:21:9;;;9345;;;9324:6;9352;;-1:-1:-1;8980:396:9:o;342:41:8:-;380:3;342:41;:::o;7034:645:9:-;7111:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;7127:22:::1;7152:14:::0;;;:6:::1;:14;::::0;;;;;;;;7198:11:::1;::::0;::::1;7172:37:::0;;;;;;::::1;::::0;;;;;;;;;;7152:14;;7172:23:::1;::::0;:37;;;;::::1;7198:11:::0;7172:37;;::::1;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;7172:37:9::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;-1:-1:-1::0;;;7262:20:9::1;::::0;::::1;::::0;7245:61:::1;::::0;-1:-1:-1;;;7245:61:9;;7172:37;;-1:-1:-1;7215:27:9::1;::::0;-1:-1:-1;;;;;7262:20:9;;::::1;::::0;-1:-1:-1;7245:53:9::1;::::0;-1:-1:-1;7245:61:9::1;::::0;7172:37;;7245:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;7245:61:9::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;7404:17:::0;;7215:91;;-1:-1:-1;7312:30:9::1;::::0;7345:107:::1;::::0;:6;;7215:91;;-1:-1:-1;;;;;7404:17:9;;::::1;::::0;-1:-1:-1;;;7429:17:9;::::1;;7345:33;:107::i;:::-;7458:14;::::0;;;:6:::1;:14;::::0;;;;;;;:30;;7312:140;;-1:-1:-1;7458:30:9::1;::::0;:21:::1;::::0;;::::1;::::0;:30;::::1;::::0;::::1;:::i;:::-;;7499:9;7494:181;7518:13;:20;7514:1;:24;7494:181;;;7553:13;7569;7583:1;7569:16;;;;;;;;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;7593:27:9;::::1;7623:5;7593:27:::0;;;:20:::1;::::0;::::1;:27:::0;;;;;;;;:35;;-1:-1:-1;;7593:35:9::1;::::0;;7641:27;;7569:16;;-1:-1:-1;7641:27:9::1;::::0;::::1;::::0;7569:16;;7661:6;;7641:27:::1;:::i;:::-;;;;;;;;-1:-1:-1::0;7540:3:9::1;;7494:181;;3935:638:::0;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;4129:1:9::1;4114:12;-1:-1:-1::0;;;;;4114:16:9::1;;4106:45;;;;-1:-1:-1::0;;;4106:45:9::1;;;;;;;:::i;:::-;4180:12;-1:-1:-1::0;;;;;4165:27:9::1;:12;-1:-1:-1::0;;;;;4165:27:9::1;;4157:51;;;;-1:-1:-1::0;;;4157:51:9::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;4222:29:9;::::1;4214:58;;;;-1:-1:-1::0;;;4214:58:9::1;;;;;;;:::i;:::-;4297:14;4295:16:::0;;::::1;::::0;;::::1;::::0;;;;4278:14:::1;4342::::0;;;:6:::1;:14;::::0;;;;;;4362:20;;::::1;:38:::0;;-1:-1:-1;;;;;4362:38:9;::::1;-1:-1:-1::0;;;;;;4362:38:9;;::::1;;::::0;;4406:32;;-1:-1:-1;;;;;4444:32:9;;::::1;-1:-1:-1::0;;;4444:32:9::1;4406::::0;;::::1;-1:-1:-1::0;;4406:32:9;;::::1;::::0;;;::::1;4444;;::::0;;4487:81;::::1;::::0;::::1;::::0;4295:16;;4510:12;;4385:15;;4426:12;;4464;;4487:81:::1;:::i;:::-;;;;;;;;1895:1:7;;3935:638:9::0;;;;:::o;8387:179::-;8503:4;8482:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;-1:-1:-1;;8524:14:9::1;::::0;;;:6:::1;:14;::::0;;;;;;;-1:-1:-1;;;;;8524:37:9;;;::::1;::::0;;:30;;;::::1;:37:::0;;;;;::::1;;::::0;8387:179::o;1644:71:7:-;1682:7;1704:6;-1:-1:-1;;;;;1704:6:7;1644:71;:::o;2943:55:10:-;;;:::o;12531:167::-;5813:10;-1:-1:-1;;;;;5827:10:10;5813:24;;5805:55;;;;-1:-1:-1;;;5805:55:10;;;;;;;:::i;:::-;-1:-1:-1;;;;;5507:30:10;::::1;;::::0;;;:17:::1;:30;::::0;;;;:42;12631:11;;5507:42:::1;;5492:91;;;;-1:-1:-1::0;;;5492:91:10::1;;;;;;;:::i;:::-;12650:43:::2;::::0;-1:-1:-1;;;12650:43:10;;-1:-1:-1;;;;;12650:34:10;::::2;::::0;::::2;::::0;:43:::2;::::0;12685:7;;12650:43:::2;;;:::i;18456:396::-:0;18552:19;18595:252;18648:12;18677:11;867:33:8;18771:4:10;18813:6;18821:9;18796:35;;;;;;;;;:::i;:::-;;;;;;;;;;;;;18786:46;;;;;;18737:103;;;;;;;;;:::i;18595:252::-;18581:266;18456:396;-1:-1:-1;;;18456:396:10:o;5183:58::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5183:58:10;;;;;;-1:-1:-1;;;5183:58:10;;-1:-1:-1;;;;;5183:58:10;;:::o;1242:59:8:-;1295:6;1242:59;:::o;2961:29:9:-;;;;:::o;5356:38:10:-;;;-1:-1:-1;;;;;5356:38:10;;:::o;228:43:8:-;269:2;228:43;:::o;138:42::-;179:1;138:42;:::o;6552:149:10:-;6610:18;:16;:18::i;:::-;6634:20;:24;;-1:-1:-1;;6634:24:10;6657:1;6634:24;;;6664:14;:32;;-1:-1:-1;;;;;6664:32:10;;;-1:-1:-1;;;;;;6664:32:10;;;;;;;;;6552:149::o;648:93:8:-;699:42;648:93;:::o;14032:227:10:-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;-1:-1:-1;;;;;5507:30:10;::::1;;::::0;;;:17:::1;:30;::::0;;;;:42;14184:4;;5507:42:::1;;5492:91;;;;-1:-1:-1::0;;;5492:91:10::1;;;;;;;:::i;:::-;14198:56:::2;::::0;-1:-1:-1;;;14198:56:10;;-1:-1:-1;;;;;14198:38:10;::::2;::::0;::::2;::::0;:56:::2;::::0;14237:5;;14244:9;;14198:56:::2;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;1895:1:7::1;14032:227:10::0;;;:::o;2857:61:9:-;;;-1:-1:-1;;;;;2857:61:9;;:::o;11181:239:10:-;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;11303:1:10::1;11286:14;:18;;;:41;;;;;11325:2;11308:14;:19;;;11286:41;11278:65;;;;-1:-1:-1::0;;;11278:65:10::1;;;;;;;:::i;:::-;11349:66;::::0;-1:-1:-1;;;11349:66:10;;-1:-1:-1;;;;;11349:50:10;::::1;::::0;::::1;::::0;:66:::1;::::0;11400:14;;11349:66:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;6661:203:9::0;6757:27;6736:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;6837:14:::1;::::0;;;:6:::1;:14;::::0;;;;;;6810:49;;-1:-1:-1;;;6810:49:9;;-1:-1:-1;;;;;6810:13:9::1;:26;::::0;::::1;::::0;:49:::1;::::0;6837:21:::1;;::::0;6810:49:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;6810:49:9::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;6830:221:10:-:0;1840:12:7;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;6949:1:10::1;6925:21;:25;;;:55;;;;;6978:2;6954:21;:26;;;6925:55;6917:79;;;;-1:-1:-1::0;;;6917:79:10::1;;;;;;;:::i;:::-;7002:20;:44:::0;;-1:-1:-1;;7002:44:10::1;;::::0;;;::::1;::::0;;;::::1;::::0;;6830:221::o;16657:884::-;16714:25;;:::i;:::-;-1:-1:-1;;;;;;16742:30:10;;;;;;:17;:30;;;;;;;;;16714:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;16714:58:10;;;;;;;;;-1:-1:-1;;;16714:58:10;;;-1:-1:-1;;;;;16714:58:10;;;;;16778:47;;;;-1:-1:-1;;;16778:47:10;;;;;;;:::i;:::-;991:7:8;16853:4:10;:16;;;-1:-1:-1;;;;;16847:22:10;:3;:22;:44;;16832:97;;;;-1:-1:-1;;;16832:97:10;;;;;;;:::i;:::-;16954:17;;;16952:19;;17001:1;16952:19;:51;:19;;;;;:51;;16936:106;;;;-1:-1:-1;;;16936:106:10;;;;;;;:::i;:::-;17049:22;17074:6;:19;17081:4;:11;;;17074:19;;;;;;;;;;;;;17049:44;;17100:23;17137:11;-1:-1:-1;;;;;17126:47:10;;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17126:49:10;;;;;;;;;;;;:::i;:::-;17224:20;;;;17207:61;;-1:-1:-1;;;17207:61:10;;17100:75;;-1:-1:-1;17181:23:10;;-1:-1:-1;;;;;17224:20:10;;;;17207:53;;:61;;17100:75;;17207:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;17207:61:10;;;;;;;;;;;;:::i;:::-;17181:87;;17274:35;17312;:6;:33;:35::i;:::-;17380:3;-1:-1:-1;;;;;17354:30:10;;;:16;;;:30;;;-1:-1:-1;;;;;17390:30:10;;;;;;:17;:30;;;;;;;;;:37;;;;;;;;;;;;;;;;;;-1:-1:-1;;17390:37:10;;;;;;;;;;-1:-1:-1;;17390:37:10;;;;;;;;;;;-1:-1:-1;;17390:37:10;;;;;;;;-1:-1:-1;;17390:37:10;-1:-1:-1;;;17390:37:10;;;;;;;;;-1:-1:-1;;17390:37:10;-1:-1:-1;;;17390:37:10;;;;;;;;;;;;17433:66;;-1:-1:-1;;;17433:66:10;;17274:73;;-1:-1:-1;17390:30:10;17433:37;;:66;;17471:6;;17274:73;;17390:37;17433:66;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17510:26;17524:11;17510:26;;;;;;:::i;1488:44:9:-;1530:2;1488:44;:::o;7798:439::-;7926:23;7957;7898:6;3147:14;;3137:6;:24;;:38;;;;;3174:1;3165:6;:10;3137:38;3129:62;;;;-1:-1:-1;;;3129:62:9;;;;;;;:::i;:::-;7995:22:::1;8020:14:::0;;;:6:::1;:14;::::0;;;;;;;;8049:11:::1;::::0;::::1;8040:20:::0;;;;;;::::1;::::0;;;;;;;;;;8020:14;;8040:20;8049:11;;8040:20;;::::1;8049:11:::0;8040:20;;::::1;;;;;;;;;;;;;;;;::::0;;-1:-1:-1;;;;;8040:20:9::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;-1:-1:-1::0;;;8092:20:9::1;::::0;::::1;::::0;8075:61:::1;::::0;-1:-1:-1;;;8075:61:9;;8040:20;;-1:-1:-1;;;;;;8092:20:9::1;::::0;8075:53:::1;::::0;-1:-1:-1;8075:61:9::1;::::0;-1:-1:-1;8040:20:9;;8075:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;8075:61:9::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;8184:17:::0;;8066:70;;-1:-1:-1;8142:90:9::1;::::0;:6;;8066:70;;-1:-1:-1;;;;;8184:17:9;;::::1;::::0;-1:-1:-1;;;8209:17:9;::::1;;8142:20;:90::i;:::-;3197:1;7798:439:::0;;;;:::o;2646:226:7:-;1840:12;:10;:12::i;:::-;1830:6;;-1:-1:-1;;;;;1830:6:7;;;:22;;;1822:67;;;;-1:-1:-1;;;1822:67:7;;;;;;;:::i;:::-;-1:-1:-1;;;;;2730:22:7;::::1;2722:73;;;;-1:-1:-1::0;;;2722:73:7::1;;;;;;;:::i;:::-;2827:6;::::0;;2806:38:::1;::::0;-1:-1:-1;;;;;2806:38:7;;::::1;::::0;2827:6;::::1;::::0;2806:38:::1;::::0;::::1;2850:6;:17:::0;;-1:-1:-1;;;;;;2850:17:7::1;-1:-1:-1::0;;;;;2850:17:7;;;::::1;::::0;;;::::1;::::0;;2646:226::o;12024:438:10:-;5813:10;-1:-1:-1;;;;;5827:10:10;5813:24;;5805:55;;;;-1:-1:-1;;;5805:55:10;;;;;;;:::i;:::-;12148:9:::1;12143:315;12163:24:::0;;::::1;12143:315;;;12202:19;12224:13;;12238:1;12224:16;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;12256:30:10;::::1;;::::0;;;:17:::1;:30;::::0;;;;:42;12202:38;;-1:-1:-1;12256:42:10::1;;12248:73;;;;-1:-1:-1::0;;;12248:73:10::1;;;;;;;:::i;:::-;12390:61;::::0;-1:-1:-1;;;12390:61:10;;-1:-1:-1;;;;;12390:43:10;::::1;::::0;::::1;::::0;:61:::1;::::0;12434:16;;12390:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;12189:3:10::1;::::0;;::::1;::::0;-1:-1:-1;12143:315:10::1;::::0;-1:-1:-1;;12143:315:10::1;466:95:8::0;522:39;466:95;:::o;17663:329:10:-;17752:26;17809:178;17862:12;17891:4;522:39:8;17968:11:10;17951:29;;;;;;;;:::i;19997:676::-;20062:18;20088:23;20125:4;-1:-1:-1;;;;;20114:33:10;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20114:35:10;;;;;;;;;;;;:::i;:::-;20169:13;;20088:61;;-1:-1:-1;20188:25:10;20169:13;-1:-1:-1;;;;;20216:18:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20216:18:10;;20188:46;;20245:9;20240:86;20260:3;20256:1;:7;20240:86;;;20291:6;20298:1;20291:9;;;;;;;;;;;;;;-1:-1:-1;;;;;20284:27:10;;20320:4;20284:42;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20270:8;20279:1;20270:11;;;;;;;;;;;;;;;;;:56;20265:3;;20240:86;;;-1:-1:-1;20361:146:10;;-1:-1:-1;;;20361:146:10;;20332:26;;-1:-1:-1;;;;;20361:13:10;:40;;;;:146;;20409:6;;20423:8;;1228:10:8;;1295:6;;20361:146:10;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;20361:146:10;;;;;;;;;;;;:::i;:::-;20332:175;;20617:9;20612:56;20632:3;20628:1;:7;20612:56;;;20656:9;20666:1;20656:12;;;;;;;;;;;;;;20642:26;;;;20637:3;;;;;;;20612:56;;;;19997:676;;;;;;;:::o;590:104:3:-;677:10;590:104;:::o;15610:902:10:-;15711:14;;;;;;;;15732:23;;;;15784:40;;15711:14;15806:11;;;;15711:14;15784:21;:40::i;:::-;15731:93;;;;15830:17;15850:31;15869:11;15850:18;:31::i;:::-;15830:51;-1:-1:-1;15918:3:10;15906:15;;15927:26;15970:4;-1:-1:-1;;;;;15956:19:10;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15956:19:10;;15927:48;;15986:9;15981:72;16005:4;16001:1;:8;15981:72;;;16038:8;16023:9;16033:1;16023:12;;;;;;;;;;;;;;;;;:23;16011:3;;15981:72;;;-1:-1:-1;16093:147:10;;-1:-1:-1;;;16093:147:10;;16058:32;;-1:-1:-1;;;;;16093:13:10;:40;;;;:147;;16141:6;;16155:9;;1228:10:8;;1295:6;;16093:147:10;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;16093:147:10;;;;;;;;;;;;:::i;:::-;16058:182;;16246:35;16284;:6;:33;:35::i;:::-;16326:30;;-1:-1:-1;;16326:30:10;-1:-1:-1;;;16352:3:10;-1:-1:-1;;;;;16326:30:10;;;;;16363:107;;-1:-1:-1;;;16363:107:10;;16246:73;;-1:-1:-1;;;;;;16363:37:10;;;;;:107;;16408:6;;16246:73;;16449:15;;16363:107;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16481:26;16495:11;16481:26;;;;;;:::i;:::-;;;;;;;;15610:902;;;;;;;;;;:::o;10446:203:9:-;-1:-1:-1;;;;;10528:27:9;;;;;;:20;;;:27;;;;;;;;10527:28;10519:56;;;;-1:-1:-1;;;10519:56:9;;;;;;;:::i;:::-;-1:-1:-1;;;;;10581:27:9;;;;;:20;;;:27;;;;;;;:34;;-1:-1:-1;;10581:34:9;10611:4;10581:34;;;;;;10621:11;;;;:23;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;10621:23:9;;;;;;10446:203::o;3276:387:1:-;3455:7;3472:12;3487:87;3514:10;3532:16;3556:12;3487:19;:87::i;:::-;3472:102;-1:-1:-1;3587:71:1;3472:102;463:66:0;3649:8:1;3587:22;:71::i;:::-;3580:78;3276:387;-1:-1:-1;;;;;;3276:387:1:o;826:410:17:-;986:13;;922:23;;955:11;;986:13;-1:-1:-1;;;;;1015:17:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1015:17:17;;1005:27;;1043:9;1038:73;1062:3;1058:1;:7;1038:73;;;1086:18;1094:6;1101:1;1094:9;;;;;;;;;;;;;;1086:3;:7;;:18;;;;:::i;:::-;1080:24;-1:-1:-1;1067:3:17;;1038:73;;;;1121:9;1116:116;1140:3;1136:1;:7;1116:116;;;1171:54;1183:41;1220:3;1183:32;302:5;1183:6;1190:1;1183:9;;;;;;;;;;;;;;:13;;:32;;;;:::i;:::-;:36;;:41::i;:::-;1171:11;:54::i;:::-;1158:7;1166:1;1158:10;;;;;;;;-1:-1:-1;;;;;1158:67:17;;;:10;;;;;;;;;;;:67;1145:3;;1116:116;;;;826:410;;;;;:::o;312:510::-;486:13;;422:23;;455:11;;486:13;-1:-1:-1;;;;;514:18:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;514:18:17;;505:27;;543:9;538:73;562:3;558:1;:7;538:73;;;586:18;594:6;601:1;594:9;;;;;;;586:18;580:24;-1:-1:-1;567:3:17;;538:73;;;-1:-1:-1;648:4:17;642:10;;;;686:12;;616:23;704:114;728:3;724:1;:7;704:114;;;758:53;795:15;758:32;772:17;758:6;765:1;758:9;;;;;;;:53;746:6;753:1;746:9;;;;;;;;;;;;;;;;;:65;733:3;;704:114;;;;312:510;;;;;;;;:::o;3008:244:7:-;3081:1;3063:6;-1:-1:-1;;;;;3063:6:7;:20;3055:76;;;;-1:-1:-1;;;3055:76:7;;;;;;;:::i;:::-;3137:17;3157:12;:10;:12::i;:::-;3175:6;:18;;-1:-1:-1;;;;;;3175:18:7;-1:-1:-1;;;;;3175:18:7;;;;;;;3204:43;;3175:18;;-1:-1:-1;3175:18:7;3204:43;;3175:6;;3204:43;3008:244;:::o;2536:1031:17:-;2785:13;;2709:24;;2741:20;;2785:13;-1:-1:-1;;;;;2814:18:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2814:18:17;;2804:28;;2843:9;2838:568;2862:3;2858:1;:7;2838:568;;;2880:11;2894:6;2901:1;2894:9;;;;;;;;;;;;;;2880:23;;2911:13;2927:6;2934:1;2927:9;;;;;;;;;;;;;;2911:25;;2954:12;2948:3;:18;:40;;;;2976:12;2970:3;:18;2948:40;2944:237;;;3026:5;3000:7;3008:14;;;;;;3000:23;;;;;;;;;;;;;:31;-1:-1:-1;;;;;3000:31:17;;;-1:-1:-1;;;;;3000:31:17;;;;;3049:6;3056:5;;;;;;;3049:13;;;;;;;;;;;;;;3041:21;;3078:6;3085:3;3078:11;;;;;;;;;;;;;;3072:17;;3111:3;3099:6;3106:1;3099:9;;;;;;;;;;;;;:15;;;;;3136:5;3124:6;3131:1;3124:9;;;;;;;;-1:-1:-1;;;;;3124:17:17;;;:9;;;;;;;;;;;:17;-1:-1:-1;;;;3151:3:17;3164:8;;2944:237;-1:-1:-1;;3200:5:17;;3213:131;3230:1;3224;3220:11;;:30;;;;;3247:3;3235:6;3242:1;3235:9;;;;;;;;;;;;;;:15;3220:30;3213:131;;;3278:6;3285:1;3278:9;;;;;;;;;;;;;;3262:6;3269:1;3273;3269:5;3262:13;;;;;;;;;;;;;:25;;;;;3313:6;3320:1;3313:9;;;;;;;;;;;;;;3297:6;3304:1;3308;3304:5;3297:13;;;;;;;;-1:-1:-1;;;;;3297:25:17;;;:13;;;;;;;;;;;:25;-1:-1:-1;;3332:3:17;3213:131;;;3367:3;3351:6;3358:1;3362;3358:5;3351:13;;;;;;;;;;;;;:19;;;;;3394:5;3378:6;3385:1;3389;3385:5;3378:13;;;;;;;;;;;;;:21;-1:-1:-1;;;;;3378:21:17;;;-1:-1:-1;;;;;3378:21:17;;;;;2838:568;;;;2867:3;;2838:568;;;;3422:6;:13;3415:3;:20;3411:152;;3479:3;3471:6;3464:19;3507:3;3499:6;3492:19;3536:12;3527:7;3520:29;3454:103;2536:1031;;;;;;;;:::o;1436:840::-;1607:13;;1593:11;1626:527;1650:3;1646:1;:7;1626:527;;;1668:11;1682:6;1689:1;1682:9;;;;;;;;;;;;;;1668:23;;1699:13;1715:6;1722:1;1715:9;;;;;;;;;;;;;;1699:25;;1742:12;1736:3;:18;:40;;;;1764:12;1758:3;:18;1736:40;1732:196;;;1796:6;1803:5;;;;;;;1796:13;;;;;;;;;;;;;;1788:21;;1825:6;1832:3;1825:11;;;;;;;;;;;;;;1819:17;;1858:3;1846:6;1853:1;1846:9;;;;;;;;;;;;;:15;;;;;1883:5;1871:6;1878:1;1871:9;;;;;;;;-1:-1:-1;;;;;1871:17:17;;;:9;;;;;;;;;;;:17;-1:-1:-1;;;;1898:3:17;1911:8;;1732:196;-1:-1:-1;;1947:5:17;;1960:131;1977:1;1971;1967:11;;:30;;;;;1994:3;1982:6;1989:1;1982:9;;;;;;;;;;;;;;:15;1967:30;1960:131;;;2025:6;2032:1;2025:9;;;;;;;;;;;;;;2009:6;2016:1;2020;2016:5;2009:13;;;;;;;;;;;;;:25;;;;;2060:6;2067:1;2060:9;;;;;;;;;;;;;;2044:6;2051:1;2055;2051:5;2044:13;;;;;;;;-1:-1:-1;;;;;2044:25:17;;;:13;;;;;;;;;;;:25;-1:-1:-1;;2079:3:17;1960:131;;;2114:3;2098:6;2105:1;2109;2105:5;2098:13;;;;;;;;;;;;;:19;;;;;2141:5;2125:6;2132:1;2136;2132:5;2125:13;;;;;;;;;;;;;:21;-1:-1:-1;;;;;2125:21:17;;;-1:-1:-1;;;;;2125:21:17;;;;;1626:527;;;;1655:3;;1626:527;;;;2169:6;:13;2162:3;:20;2158:114;;2226:3;2218:6;2211:19;2254:3;2246:6;2239:19;2201:65;1436:840;;;;;:::o;1332:292:1:-;1480:7;1547:10;1567:16;1593:12;1521:92;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1504:115;;;;;;1497:122;;1332:292;;;;;:::o;2160:276:6:-;2261:7;2280:13;2343:4;2336:12;;2350:8;2360:4;2366:12;2319:60;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;2319:60:6;;;;;;2296:93;;2319:60;2296:93;;;;;2160:276;-1:-1:-1;;;;;2160:276:6:o;874:176:4:-;932:7;963:5;;;986:6;;;;978:46;;;;-1:-1:-1;;;978:46:4;;;;;;;:::i;2180:459::-;2238:7;2479:6;2475:45;;-1:-1:-1;2508:1:4;2501:8;;2475:45;2542:5;;;2546:1;2542;:5;:1;2565:5;;;;;:10;2557:56;;;;-1:-1:-1;;;2557:56:4;;;;;;;:::i;3101:130::-;3159:7;3185:39;3189:1;3192;3185:39;;;;;;;;;;;;;;;;;:3;:39::i;3571:128:17:-;3653:1;-1:-1:-1;;;;;3669:6:17;;;;3661:33;;;;-1:-1:-1;;;3661:33:17;;;;;;;:::i;:::-;3571:128;;;:::o;3713:272:4:-;3799:7;3833:12;3826:5;3818:28;;;;-1:-1:-1;;;3818:28:4;;;;;;;;:::i;:::-;;3856:9;3872:1;3868;:5;;;;;;;3713:272;-1:-1:-1;;;;;3713:272:4:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;301:352;;;431:3;424:4;416:6;412:17;408:27;398:2;;-1:-1;;439:12;398:2;-1:-1;469:20;;-1:-1;;;;;498:30;;495:2;;;-1:-1;;531:12;495:2;575:4;567:6;563:17;551:29;;626:3;575:4;;610:6;606:17;567:6;592:32;;589:41;586:2;;;643:1;;633:12;586:2;391:262;;;;;:::o;4422:337::-;;;4537:3;4530:4;4522:6;4518:17;4514:27;4504:2;;-1:-1;;4545:12;4504:2;-1:-1;4575:20;;-1:-1;;;;;4604:30;;4601:2;;;-1:-1;;4637:12;4601:2;4681:4;4673:6;4669:17;4657:29;;4732:3;4681:4;4712:17;4673:6;4698:32;;4695:41;4692:2;;;4749:1;;4739:12;6100:130;6167:20;;-1:-1;;;;;73366:46;;78196:35;;78186:2;;78245:1;;78235:12;6924:132;7001:13;;-1:-1;;;;;74166:38;;78685:34;;78675:2;;78733:1;;78723:12;7063:241;;7167:2;7155:9;7146:7;7142:23;7138:32;7135:2;;;-1:-1;;7173:12;7135:2;85:6;72:20;97:33;124:5;97:33;:::i;7311:263::-;;7426:2;7414:9;7405:7;7401:23;7397:32;7394:2;;;-1:-1;;7432:12;7394:2;226:6;220:13;238:33;265:5;238:33;:::i;7581:366::-;;;7702:2;7690:9;7681:7;7677:23;7673:32;7670:2;;;-1:-1;;7708:12;7670:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;7760:63;-1:-1;7860:2;7899:22;;72:20;97:33;72:20;97:33;:::i;:::-;7868:63;;;;7664:283;;;;;:::o;7954:491::-;;;;8092:2;8080:9;8071:7;8067:23;8063:32;8060:2;;;-1:-1;;8098:12;8060:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8150:63;-1:-1;8250:2;8289:22;;72:20;97:33;72:20;97:33;:::i;:::-;8258:63;-1:-1;8358:2;8397:22;;72:20;97:33;72:20;97:33;:::i;:::-;8366:63;;;;8054:391;;;;;:::o;8452:803::-;;;;;;8660:2;8648:9;8639:7;8635:23;8631:32;8628:2;;;-1:-1;;8666:12;8628:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;8718:63;-1:-1;8846:2;8831:18;;8818:32;-1:-1;;;;;8859:30;;;8856:2;;;-1:-1;;8892:12;8856:2;8930:80;9002:7;8993:6;8982:9;8978:22;8930:80;:::i;:::-;8912:98;;-1:-1;8912:98;-1:-1;9075:2;9060:18;;9047:32;;-1:-1;9088:30;;;9085:2;;;-1:-1;;9121:12;9085:2;;9159:80;9231:7;9222:6;9211:9;9207:22;9159:80;:::i;:::-;8622:633;;;;-1:-1;8622:633;;-1:-1;9141:98;;;8622:633;-1:-1;;;8622:633::o;9262:360::-;;;9380:2;9368:9;9359:7;9355:23;9351:32;9348:2;;;-1:-1;;9386:12;9348:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;9438:63;-1:-1;9538:2;9574:22;;4068:20;4093:30;4068:20;4093:30;:::i;9629:366::-;;;9750:2;9738:9;9729:7;9725:23;9721:32;9718:2;;;-1:-1;;9756:12;9718:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;9808:63;9908:2;9947:22;;;;6304:20;;-1:-1;;;9712:283::o;10002:362::-;;;10121:2;10109:9;10100:7;10096:23;10092:32;10089:2;;;-1:-1;;10127:12;10089:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;10179:63;-1:-1;10279:2;10316:22;;6719:20;6744:31;6719:20;6744:31;:::i;10371:522::-;;;;10527:2;10515:9;10506:7;10502:23;10498:32;10495:2;;;-1:-1;;10533:12;10495:2;10591:17;10578:31;-1:-1;;;;;10621:6;10618:30;10615:2;;;-1:-1;;10651:12;10615:2;10689:80;10761:7;10752:6;10741:9;10737:22;10689:80;:::i;:::-;10671:98;;-1:-1;10671:98;-1:-1;;10806:2;10845:22;;72:20;97:33;72:20;97:33;:::i;10900:522::-;;;;11056:2;11044:9;11035:7;11031:23;11027:32;11024:2;;;-1:-1;;11062:12;11024:2;11120:17;11107:31;-1:-1;;;;;11150:6;11147:30;11144:2;;;-1:-1;;11180:12;11144:2;11218:80;11290:7;11281:6;11270:9;11266:22;11218:80;:::i;:::-;11200:98;;;;-1:-1;11335:2;11374:22;;;;6304:20;;11018:404;-1:-1;;;;11018:404::o;11429:392::-;;11569:2;;11557:9;11548:7;11544:23;11540:32;11537:2;;;-1:-1;;11575:12;11537:2;11626:17;11620:24;-1:-1;;;;;11656:6;11653:30;11650:2;;;-1:-1;;11686:12;11650:2;11773:22;;1533:4;1521:17;;1517:27;-1:-1;1507:2;;-1:-1;;1548:12;1507:2;1588:6;1582:13;1610:80;1625:64;1682:6;1625:64;:::i;:::-;1610:80;:::i;:::-;1718:21;;;1775:14;;;;1750:17;;;1864;;;1855:27;;;;1852:36;-1:-1;1849:2;;;-1:-1;;1891:12;1849:2;-1:-1;1917:10;;1911:217;1936:6;1933:1;1930:13;1911:217;;;226:6;220:13;238:33;265:5;238:33;:::i;:::-;2004:61;;1958:1;1951:9;;;;;2079:14;;;;2107;;1911:217;;;-1:-1;11706:99;11531:290;-1:-1;;;;;;;11531:290::o;11828:386::-;;11965:2;;11953:9;11944:7;11940:23;11936:32;11933:2;;;-1:-1;;11971:12;11933:2;12022:17;12016:24;-1:-1;;;;;12052:6;12049:30;12046:2;;;-1:-1;;12082:12;12046:2;12166:22;;2275:4;2263:17;;2259:27;-1:-1;2249:2;;-1:-1;;2290:12;2249:2;2330:6;2324:13;2352:77;2367:61;2421:6;2367:61;:::i;2352:77::-;2457:21;;;2514:14;;;;2489:17;;;2603;;;2594:27;;;;2591:36;-1:-1;2588:2;;;-1:-1;;2630:12;2588:2;-1:-1;2656:10;;2650:214;2675:6;2672:1;2669:13;2650:214;;;4216:6;4210:13;4228:30;4252:5;4228:30;:::i;:::-;2743:58;;2697:1;2690:9;;;;;2815:14;;;;2843;;2650:214;;12221:392;;12361:2;;12349:9;12340:7;12336:23;12332:32;12329:2;;;-1:-1;;12367:12;12329:2;12418:17;12412:24;-1:-1;;;;;12448:6;12445:30;12442:2;;;-1:-1;;12478:12;12442:2;12565:22;;3395:4;3383:17;;3379:27;-1:-1;3369:2;;-1:-1;;3410:12;3369:2;3450:6;3444:13;3472:80;3487:64;3544:6;3487:64;:::i;3472:80::-;3580:21;;;3637:14;;;;3612:17;;;3726;;;3717:27;;;;3714:36;-1:-1;3711:2;;;-1:-1;;3753:12;3711:2;-1:-1;3779:10;;3773:217;3798:6;3795:1;3792:13;3773:217;;;6452:13;;3866:61;;3820:1;3813:9;;;;;3941:14;;;;3969;;3773:217;;12620:257;;12732:2;12720:9;12711:7;12707:23;12703:32;12700:2;;;-1:-1;;12738:12;12700:2;4216:6;4210:13;4228:30;4252:5;4228:30;:::i;12884:617::-;;;;;13039:3;13027:9;13018:7;13014:23;13010:33;13007:2;;;-1:-1;;13046:12;13007:2;4350:6;4337:20;13098:63;;13198:2;13241:9;13237:22;72:20;97:33;124:5;97:33;:::i;:::-;13206:63;-1:-1;13324:53;13369:7;13306:2;13345:22;;13324:53;:::i;:::-;13314:63;;13432:53;13477:7;13414:2;13457:9;13453:22;13432:53;:::i;:::-;13422:63;;13001:500;;;;;;;:::o;13508:312::-;;13647:3;13635:9;13626:7;13622:23;13618:33;13615:2;;;-1:-1;;13654:12;13615:2;4958:20;13647:3;4958:20;:::i;:::-;4216:6;4210:13;4228:30;4252:5;4228:30;:::i;:::-;5036:83;;5181:2;5243:22;;4210:13;4228:30;4210:13;4228:30;:::i;:::-;5181:2;5196:16;;5189:83;5345:2;5409:22;;6592:13;73889:12;73878:24;;78443:34;;78433:2;;-1:-1;;78481:12;78433:2;5345;5360:16;;5353:85;5534:59;5589:3;5501:2;5565:22;;5534:59;:::i;:::-;5501:2;5520:5;5516:16;5509:85;5698:59;5753:3;5664;5733:9;5729:22;5698:59;:::i;:::-;5664:3;5684:5;5680:16;5673:85;5820:3;5888:9;5884:22;6863:13;6881:31;6906:5;6881:31;:::i;:::-;5820:3;5836:16;;5829:84;5977:3;6043:22;;;6452:13;5993:16;;;5986:86;;;;-1:-1;5840:5;13609:211;-1:-1;13609:211::o;13827:241::-;;13931:2;13919:9;13910:7;13906:23;13902:32;13899:2;;;-1:-1;;13937:12;13899:2;-1:-1;6304:20;;13893:175;-1:-1;13893:175::o;14075:263::-;;14190:2;14178:9;14169:7;14165:23;14161:32;14158:2;;;-1:-1;;14196:12;14158:2;-1:-1;6452:13;;14152:186;-1:-1;14152:186::o;14345:366::-;;;14466:2;14454:9;14445:7;14441:23;14437:32;14434:2;;;-1:-1;;14472:12;14434:2;6317:6;6304:20;14524:63;;14624:2;14667:9;14663:22;72:20;97:33;124:5;97:33;:::i;14718:522::-;;;;14874:2;14862:9;14853:7;14849:23;14845:32;14842:2;;;-1:-1;;14880:12;14842:2;6317:6;6304:20;14932:63;;15060:2;15049:9;15045:18;15032:32;-1:-1;;;;;15076:6;15073:30;15070:2;;;-1:-1;;15106:12;15070:2;15144:80;15216:7;15207:6;15196:9;15192:22;15144:80;:::i;:::-;14836:404;;15126:98;;-1:-1;15126:98;;-1:-1;;;;14836:404::o;15247:502::-;;;15393:2;15381:9;15372:7;15368:23;15364:32;15361:2;;;-1:-1;;15399:12;15361:2;6317:6;6304:20;15451:63;;15579:2;;15568:9;15564:18;15551:32;-1:-1;;;;;15595:6;15592:30;15589:2;;;-1:-1;;15625:12;15589:2;15701:22;;789:4;777:17;;773:27;-1:-1;763:2;;-1:-1;;804:12;763:2;851:6;838:20;873:80;888:64;945:6;888:64;:::i;873:80::-;981:21;;;1038:14;;;;1013:17;;;1127;;;1118:27;;;;1115:36;-1:-1;1112:2;;;-1:-1;;1154:12;1112:2;-1:-1;1180:10;;1174:206;1199:6;1196:1;1193:13;1174:206;;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;1267:50;;1221:1;1214:9;;;;;1331:14;;;;1359;;1174:206;;;1178:14;15645:88;;;;;;;;15355:394;;;;;:::o;15756:366::-;;;15877:2;15865:9;15856:7;15852:23;15848:32;15845:2;;;-1:-1;;15883:12;15845:2;-1:-1;;6304:20;;;16035:2;16074:22;;;6304:20;;-1:-1;15839:283::o;16129:491::-;;;;16267:2;16255:9;16246:7;16242:23;16238:32;16235:2;;;-1:-1;;16273:12;16235:2;-1:-1;;6304:20;;;16425:2;16464:22;;6304:20;;-1:-1;16533:2;16572:22;;;6304:20;;16229:391;-1:-1;16229:391::o;16627:995::-;;;;;;;;16839:3;16827:9;16818:7;16814:23;16810:33;16807:2;;;-1:-1;;16846:12;16807:2;6317:6;6304:20;16898:63;;16998:2;17041:9;17037:22;6304:20;17006:63;;17106:2;17149:9;17145:22;6304:20;17114:63;;17242:2;17231:9;17227:18;17214:32;-1:-1;;;;;17266:18;17258:6;17255:30;17252:2;;;-1:-1;;17288:12;17252:2;17326:65;17383:7;17374:6;17363:9;17359:22;17326:65;:::i;:::-;17308:83;;-1:-1;17308:83;-1:-1;17456:3;17441:19;;17428:33;;-1:-1;17470:30;;;17467:2;;;-1:-1;;17503:12;17467:2;;17541:65;17598:7;17589:6;17578:9;17574:22;17541:65;:::i;:::-;16801:821;;;;-1:-1;16801:821;;-1:-1;16801:821;;;;17523:83;;-1:-1;;;16801:821::o;17629:237::-;;17731:2;17719:9;17710:7;17706:23;17702:32;17699:2;;;-1:-1;;17737:12;17699:2;6732:6;6719:20;6744:31;6769:5;6744:31;:::i;19154:665::-;;71830:6;71825:3;71818:19;71867:4;;71862:3;71858:14;19301:93;;19479:21;-1:-1;19506:291;19531:6;19528:1;19525:13;19506:291;;;85:6;72:20;97:33;124:5;97:33;:::i;:::-;-1:-1;;;;;72818:54;18795:37;;18027:14;;;;72716:12;;;;509:18;19546:9;19506:291;;;-1:-1;19803:10;;19288:531;-1:-1;;;;;19288:531::o;19858:690::-;;20051:5;70268:12;71830:6;71825:3;71818:19;71867:4;;71862:3;71858:14;20063:93;;71867:4;20227:5;69472:14;-1:-1;20266:260;20291:6;20288:1;20285:13;20266:260;;;20352:13;;-1:-1;;;;;72818:54;18795:37;;18027:14;;;;71105;;;;509:18;20306:9;20266:260;;22034:467;71818:19;;;22034:467;-1:-1;;;;;22282:78;;22279:2;;;-1:-1;;22363:12;22279:2;71867:4;22398:6;22394:17;76352:6;76347:3;71867:4;71862:3;71858:14;76329:30;76390:16;;;;71867:4;76390:16;76383:27;;;-1:-1;76390:16;;22166:335;-1:-1;22166:335::o;22540:690::-;;22733:5;70268:12;71830:6;71825:3;71818:19;71867:4;;71862:3;71858:14;22745:93;;71867:4;22909:5;69472:14;-1:-1;22948:260;22973:6;22970:1;22967:13;22948:260;;;23034:13;;24395:37;;18379:14;;;;71105;;;;22995:1;22988:9;22948:260;;23267:682;;23457:5;70268:12;71830:6;71825:3;71818:19;71867:4;;71862:3;71858:14;23469:92;;71867:4;23631:5;69472:14;-1:-1;23670:257;23695:6;23692:1;23689:13;23670:257;;;23756:13;;-1:-1;;;;;74166:38;37117:36;;18557:14;;;;71105;;;;23717:1;23710:9;23670:257;;25404:300;;71830:6;71825:3;71818:19;76352:6;76347:3;71867:4;71862:3;71858:14;76329:30;-1:-1;71867:4;76399:6;71862:3;76390:16;;76383:27;71867:4;77538:7;;77542:2;25690:6;77522:14;77518:28;71862:3;25659:39;;25652:46;;25506:198;;;;;:::o;37165:253::-;77633:2;77629:14;;;;-1:-1;;;;;;77629:14;19053:58;;37390:2;37381:12;;37281:137::o;37425:392::-;77633:2;77629:14;;;;-1:-1;;;;;;77629:14;19053:58;;37678:2;37669:12;;24395:37;37780:12;;;37569:248::o;37824:531::-;77633:2;77629:14;;;;-1:-1;;;;;;77629:14;19053:58;;38105:2;38096:12;;24395:37;;;;38207:12;;;24395:37;38318:12;;;37996:359::o;38362:665::-;-1:-1;;;;;;73135:78;;;;24256:56;;77633:2;77629:14;;;;-1:-1;;;;;;77629:14;38667:1;38658:11;;19053:58;38768:12;;;24395:37;38879:12;;;24395:37;38990:12;;;38560:467::o;39034:392::-;24395:37;;;39287:2;39278:12;;24395:37;39389:12;;;39178:248::o;39433:222::-;-1:-1;;;;;72818:54;;;;18795:37;;39560:2;39545:18;;39531:124::o;39662:333::-;-1:-1;;;;;72818:54;;;18795:37;;72818:54;;39981:2;39966:18;;18795:37;39817:2;39802:18;;39788:207::o;40002:852::-;-1:-1;;;;;72818:54;;;18795:37;;72818:54;;40478:2;40463:18;;18795:37;40313:3;40515:2;40500:18;;40493:48;;;40002:852;;40555:108;;40298:19;;40649:6;40555:108;:::i;:::-;40711:9;40705:4;40701:20;40696:2;40685:9;40681:18;40674:48;40736:108;40839:4;40830:6;40736:108;:::i;:::-;40728:116;40284:570;-1:-1;;;;;;;40284:570::o;40861:550::-;-1:-1;;;;;72818:54;;;18795:37;;72818:54;;;;41234:2;41219:18;;18795:37;73496:6;73485:18;41316:2;41301:18;;36000:49;74088:4;74077:16;;;41397:2;41382:18;;36884:48;41069:3;41054:19;;41040:371::o;41418:556::-;-1:-1;;;;;72818:54;;;18795:37;;72818:54;;;;41794:2;41779:18;;18795:37;41877:2;41862:18;;24395:37;41960:2;41945:18;;24395:37;;;;41629:3;41614:19;;41600:374::o;41981:436::-;-1:-1;;;;;72818:54;;;18795:37;;72818:54;;;;42324:2;42309:18;;18795:37;74088:4;74077:16;;;42403:2;42388:18;;37011:35;42160:2;42145:18;;42131:286::o;42424:660::-;-1:-1;;;;;72818:54;;18795:37;;42667:2;42785;42770:18;;42763:48;;;42424:660;;42825:88;;42652:18;;42899:6;42891;42825:88;:::i;:::-;42961:9;42955:4;42951:20;42946:2;42935:9;42931:18;42924:48;42986:88;43069:4;43060:6;43052;42986:88;:::i;:::-;42978:96;42638:446;-1:-1;;;;;;;;42638:446::o;43091:444::-;-1:-1;;;;;72818:54;;;;18795:37;;-1:-1;;;;;73366:46;;;43438:2;43423:18;;35764:37;73366:46;43521:2;43506:18;;35764:37;43274:2;43259:18;;43245:290::o;43542:333::-;-1:-1;;;;;72818:54;;;;18795:37;;43861:2;43846:18;;24395:37;43697:2;43682:18;;43668:207::o;43882:552::-;-1:-1;;;;;72818:54;;;;18795:37;;44256:2;44241:18;;24395:37;;;;73794:10;73783:22;;;44338:2;44323:18;;36520:49;73783:22;44420:2;44405:18;;36520:49;44091:3;44076:19;;44062:372::o;44441:390::-;;44628:2;44649:17;44642:47;44703:118;44628:2;44617:9;44613:18;44807:6;44799;44703:118;:::i;44838:1276::-;;45281:3;45303:17;45296:47;45357:118;45281:3;45270:9;45266:19;45461:6;45453;45357:118;:::i;:::-;45523:9;45517:4;45513:20;45508:2;45497:9;45493:18;45486:48;45548:118;45661:4;45652:6;45644;45548:118;:::i;:::-;45540:126;;45714:9;45708:4;45704:20;45699:2;45688:9;45684:18;45677:48;45739:106;45840:4;45831:6;45739:106;:::i;:::-;-1:-1;;;;;72818:54;;;45932:2;45917:18;;18664:58;72818:54;;;46015:3;46000:19;;18795:37;-1:-1;;72818:54;;72829:42;46084:19;;;18795:37;;;;72818:54;45731:114;-1:-1;;;;;45252:862::o;46121:888::-;;46450:3;46472:17;46465:47;46526:118;46450:3;46439:9;46435:19;46630:6;46622;46526:118;:::i;:::-;46692:9;46686:4;46682:20;46677:2;46666:9;46662:18;46655:48;46717:118;46830:4;46821:6;46813;46717:118;:::i;:::-;46709:126;;;73794:10;;36562:5;73783:22;46913:2;46902:9;46898:18;36520:49;73794:10;36562:5;73783:22;46995:2;46984:9;46980:18;36520:49;;46421:588;;;;;;;;;:::o;47016:370::-;;47193:2;47214:17;47207:47;47268:108;47193:2;47182:9;47178:18;47362:6;47268:108;:::i;47393:629::-;;47648:2;47669:17;47662:47;47723:108;47648:2;47637:9;47633:18;47817:6;47723:108;:::i;:::-;47879:9;47873:4;47869:20;47864:2;47853:9;47849:18;47842:48;47904:108;48007:4;47998:6;47904:108;:::i;:::-;47896:116;47619:403;-1:-1;;;;;47619:403::o;48029:848::-;;48338:3;48360:17;48353:47;48414:108;48338:3;48327:9;48323:19;48508:6;48414:108;:::i;:::-;48570:9;48564:4;48560:20;48555:2;48544:9;48540:18;48533:48;48595:108;48698:4;48689:6;48595:108;:::i;:::-;48587:116;;;73794:10;;73787:5;73783:22;48781:2;48770:9;48766:18;36520:49;73794:10;73787:5;73783:22;48863:2;48852:9;48848:18;36520:49;;48309:568;;;;;;;:::o;48884:625::-;;49137:2;49158:17;49151:47;49212:108;49137:2;49126:9;49122:18;49306:6;49212:108;:::i;:::-;49368:9;49362:4;49358:20;49353:2;49342:9;49338:18;49331:48;49393:106;49494:4;49485:6;49393:106;:::i;49516:884::-;;49847:2;49868:17;49861:47;49922:108;49847:2;49836:9;49832:18;50016:6;49922:108;:::i;:::-;50078:9;50072:4;50068:20;50063:2;50052:9;50048:18;50041:48;50103:106;50204:4;50195:6;50103:106;:::i;:::-;50095:114;;50257:9;50251:4;50247:20;50242:2;50231:9;50227:18;50220:48;50282:108;50385:4;50376:6;50282:108;:::i;50407:364::-;50581:2;50595:47;;;70415:12;;50566:18;;;71818:19;;;50407:364;69625:14;;;69654:18;;;50407:364;;50581:2;71858:14;;;;50407:364;20986:288;21011:6;21008:1;21005:13;20986:288;;;77430:11;;-1:-1;;;;;72818:54;18795:37;;509:18;71332:14;;;;18027;;;;21026:9;20986:288;;;-1:-1;50648:113;;50552:219;-1:-1;;;;;;50552:219::o;50778:358::-;50949:2;50963:47;;;70268:12;;50934:18;;;71818:19;;;50778:358;;50949:2;69472:14;;;;71858;;;;50778:358;21722:251;21747:6;21744:1;21741:13;21722:251;;;21808:13;;73048;73041:21;24012:34;;71105:14;;;;18197;;;;21769:1;21762:9;21722:251;;51143:370;;51320:2;51341:17;51334:47;51395:108;51320:2;51309:9;51305:18;51489:6;51395:108;:::i;51520:210::-;73048:13;;73041:21;24012:34;;51641:2;51626:18;;51612:118::o;51737:632::-;73048:13;;73041:21;24012:34;;73496:6;73485:18;;;;52115:2;52100:18;;35882:36;74088:4;74077:16;;;52194:2;52179:18;;37011:35;74077:16;52273:2;52258:18;;37011:35;-1:-1;;;;;73975:30;52354:3;52339:19;;36767:36;51958:3;51943:19;;51929:440::o;52376:222::-;24395:37;;;52503:2;52488:18;;52474:124::o;54105:310::-;;54252:2;;54273:17;54266:47;25857:5;70268:12;71830:6;54252:2;54241:9;54237:18;71818:19;-1:-1;76497:101;76511:6;76508:1;76505:13;76497:101;;;76578:11;;;;;76572:18;76559:11;;;71858:14;76559:11;76552:39;76526:10;;76497:101;;;76613:6;76610:1;76607:13;76604:2;;;-1:-1;71858:14;76669:6;54241:9;76660:16;;76653:27;76604:2;-1:-1;77538:7;77522:14;-1:-1;;77518:28;26015:39;;;;71858:14;26015:39;;54223:192;-1:-1;;;54223:192::o;54422:416::-;54622:2;54636:47;;;26291:2;54607:18;;;71818:19;26327:34;71858:14;;;26307:55;-1:-1;;;26382:12;;;26375:30;26424:12;;;54593:245::o;54845:416::-;55045:2;55059:47;;;26675:2;55030:18;;;71818:19;26711:29;71858:14;;;26691:50;26760:12;;;55016:245::o;55268:416::-;55468:2;55482:47;;;27011:2;55453:18;;;71818:19;-1:-1;;;71858:14;;;27027:34;27080:12;;;55439:245::o;55691:416::-;55891:2;55905:47;;;27331:2;55876:18;;;71818:19;-1:-1;;;71858:14;;;27347:38;27404:12;;;55862:245::o;56114:416::-;56314:2;56328:47;;;27655:2;56299:18;;;71818:19;27691:25;71858:14;;;27671:46;27736:12;;;56285:245::o;56537:416::-;56737:2;56751:47;;;27987:2;56722:18;;;71818:19;-1:-1;;;71858:14;;;28003:42;28064:12;;;56708:245::o;56960:416::-;57160:2;57174:47;;;28315:2;57145:18;;;71818:19;-1:-1;;;71858:14;;;28331:38;28388:12;;;57131:245::o;57383:416::-;57583:2;57597:47;;;28639:2;57568:18;;;71818:19;-1:-1;;;71858:14;;;28655:41;28715:12;;;57554:245::o;57806:416::-;58006:2;58020:47;;;28966:2;57991:18;;;71818:19;-1:-1;;;71858:14;;;28982:38;29039:12;;;57977:245::o;58229:416::-;58429:2;58443:47;;;29290:2;58414:18;;;71818:19;-1:-1;;;71858:14;;;29306:40;29365:12;;;58400:245::o;58652:416::-;58852:2;58866:47;;;29616:2;58837:18;;;71818:19;-1:-1;;;71858:14;;;29632:41;29692:12;;;58823:245::o;59075:416::-;59275:2;59289:47;;;29943:2;59260:18;;;71818:19;-1:-1;;;71858:14;;;29959:45;30023:12;;;59246:245::o;59498:416::-;59698:2;59712:47;;;30274:2;59683:18;;;71818:19;-1:-1;;;71858:14;;;30290:42;30351:12;;;59669:245::o;59921:416::-;60121:2;60135:47;;;30602:2;60106:18;;;71818:19;-1:-1;;;71858:14;;;30618:41;30678:12;;;60092:245::o;60344:416::-;60544:2;60558:47;;;30929:2;60529:18;;;71818:19;-1:-1;;;71858:14;;;30945:37;31001:12;;;60515:245::o;60767:416::-;60967:2;60981:47;;;31252:2;60952:18;;;71818:19;31288:34;71858:14;;;31268:55;-1:-1;;;31343:12;;;31336:25;31380:12;;;60938:245::o;61190:416::-;61390:2;61404:47;;;61375:18;;;71818:19;31667:34;71858:14;;;31647:55;31721:12;;;61361:245::o;61613:416::-;61813:2;61827:47;;;31972:2;61798:18;;;71818:19;32008:34;71858:14;;;31988:55;-1:-1;;;32063:12;;;32056:35;32110:12;;;61784:245::o;62036:416::-;62236:2;62250:47;;;32361:2;62221:18;;;71818:19;-1:-1;;;71858:14;;;32377:41;32437:12;;;62207:245::o;62459:416::-;62659:2;62673:47;;;32688:2;62644:18;;;71818:19;-1:-1;;;71858:14;;;32704:34;32757:12;;;62630:245::o;62882:416::-;63082:2;63096:47;;;33008:2;63067:18;;;71818:19;-1:-1;;;71858:14;;;33024:34;33077:12;;;63053:245::o;63305:416::-;63505:2;63519:47;;;33328:2;63490:18;;;71818:19;-1:-1;;;71858:14;;;33344:34;33397:12;;;63476:245::o;63728:416::-;63928:2;63942:47;;;33648:2;63913:18;;;71818:19;-1:-1;;;71858:14;;;33664:37;33720:12;;;63899:245::o;64151:416::-;64351:2;64365:47;;;33971:2;64336:18;;;71818:19;-1:-1;;;71858:14;;;33987:39;34045:12;;;64322:245::o;64574:416::-;64774:2;64788:47;;;34296:2;64759:18;;;71818:19;-1:-1;;;71858:14;;;34312:38;34369:12;;;64745:245::o;64997:416::-;65197:2;65211:47;;;34620:2;65182:18;;;71818:19;-1:-1;;;71858:14;;;34636:39;34694:12;;;65168:245::o;65420:416::-;65620:2;65634:47;;;34945:2;65605:18;;;71818:19;-1:-1;;;71858:14;;;34961:36;35016:12;;;65591:245::o;65843:416::-;66043:2;66057:47;;;35267:2;66028:18;;;71818:19;-1:-1;;;71858:14;;;35283:41;35343:12;;;66014:245::o;66266:416::-;66466:2;66480:47;;;35594:2;66451:18;;;71818:19;-1:-1;;;71858:14;;;35610:38;35667:12;;;66437:245::o;66918:668::-;24395:37;;;67322:2;67307:18;;24395:37;;;;-1:-1;;;;;72818:54;;;;67405:2;67390:18;;18795:37;-1:-1;;;;;73366:46;;;67488:2;67473:18;;35764:37;73366:46;67571:3;67556:19;;35764:37;67157:3;67142:19;;67128:458::o;67593:218::-;73794:10;73783:22;;;;36650:36;;67718:2;67703:18;;67689:122::o;67818:214::-;74088:4;74077:16;;;;37011:35;;67941:2;67926:18;;67912:120::o;68039:256::-;68101:2;68095:9;68127:17;;;-1:-1;;;;;68187:34;;68223:22;;;68184:62;68181:2;;;68259:1;;68249:12;68181:2;68101;68268:22;68079:216;;-1:-1;68079:216::o;68302:304::-;;-1:-1;;;;;68453:6;68450:30;68447:2;;;-1:-1;;68483:12;68447:2;-1:-1;68528:4;68516:17;;;68581:15;;68384:222::o;77771:117::-;-1:-1;;;;;72818:54;;77830:35;;77820:2;;77879:1;;77869:12;77820:2;77814:74;:::o;77895:111::-;77976:5;73048:13;73041:21;77954:5;77951:32;77941:2;;77997:1;;77987:12;78507:113;74088:4;78590:5;74077:16;78567:5;78564:33;78554:2;;78611:1;;78601:12

Swarm Source

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