Contract 0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e9

Txn Hash
Block
From
To
Value [Txn Fee]
0x9aa4d545fe02b5b59916d0a3b1ece31a674a1fc47ff5a63f30c9cf8ac7563dd455535032021-06-13 3:17:132 mins ago0x603405b995d0822ebc1d1959b211fec28681c740 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588615
0x5ade17e05705220c26e47be76db2ebfd22a6c8f01be9b19d327259e04692add955529592021-06-13 2:50:0129 mins ago0x0bba9bad330a51e2addb1c526a070cb39127bf00 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00046485
0xd31334677712702c7f100bda80ec88313bc87010ca0d86f30574661f6af68b3055529052021-06-13 2:47:1932 mins ago0x5588a2962daae351c26f549303f75dcd246f70b8 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000580691
0xd26c0bfbfa0b7dbf1c96500e5dcaedc03db1e9b611139dac5627a78d60587eda55528802021-06-13 2:46:0433 mins ago0x5588a2962daae351c26f549303f75dcd246f70b8 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000579914
0xaed1436eb8fdbc0e63f467405b0f6a1ef6d8cc2f5bd264f4c74f457e90490e8e55528552021-06-13 2:44:4934 mins ago0x5588a2962daae351c26f549303f75dcd246f70b8 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000645971
0xe6a47b36f530dfc0b60e99ad09a50ec6a88f0e82b29b1ff8b7b78da7800f358b55526702021-06-13 2:35:3443 mins ago0x4d62c8c10184faf8f14fd02d6917c0177e3302c2 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00046485
0x9f9584bd8d3c248797aa531029be3367390c224d12d265f57e1cbadb7400265355526452021-06-13 2:34:1945 mins ago0x0af2f134e61b41eb917703ff32dd5f0f04f06a2c IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588579
0xaf32985085a5b789b7dff7aa4366710bfe2a006e782fc2805e7749c3850bbb8d55526422021-06-13 2:34:1045 mins ago0x6f2f8bb312fc90dedd21d731986b63670629c63b IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000602964
0xe6bda0414dcb4725d867798097f7cacf3c2435af3a6df01ddf25e7bc6937c92755525632021-06-13 2:30:1349 mins ago0x0ec3d1e674f29b8c7cdb74d2a077519fe2912176 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000542729
0xb195fdb6ef9fd1cad950328b52efd1538eeddd50a64b90a67c508e4f3bea07e755525012021-06-13 2:27:0752 mins ago0x3fbc1eb8d28e5b16f2a31a0837a47442d7a9f728 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000542729
0x3b051ea037ab7e06fa27adf5bd6bbe1063ef597b854fa7639e4a083d5f4d3c7055524862021-06-13 2:26:2252 mins ago0x1cef945e4aa6418cf82d5af8fd143c88e9dddd15 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00052485
0x7cc09155c67d9320c6ee72381106a08b53d4372e18324cc7310f420b2e5354ef55523932021-06-13 2:21:4357 mins ago0x9095835556225680836cfbb6cf88ef369a861b25 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000618615
0x86a2cac54cd5287def94844de829f503af6c2e0c2ad0019bc3b5b583f5249f5255520202021-06-13 2:03:041 hr 16 mins ago0x12f7ee069ba97231ab09336f679626c016286df9 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000573591
0x5ab3510dd40ad4ac3a83f7dab2c927b02e78fad865d43c806c59533fd0efbbe055519742021-06-13 2:00:461 hr 18 mins ago0x12f7ee069ba97231ab09336f679626c016286df9 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000758871
0x0f90ce591b4f47c2b7a51d4a897b78401aaee99fd2291b5c2014ed30ebd1ff3155519002021-06-13 1:57:041 hr 22 mins ago0x708e691af61694a3ba6aea6174e448c3d1735acb IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000632729
0x2b0e1f4e91af66049e265b46c0dff1bb87c7289275d5e7d2047f73882cf7fce355518402021-06-13 1:54:041 hr 25 mins ago0xa1f93dad821db17beaf4bc881102864f7241ed4c IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588579
0x066c4c89446ab8d2d0db4742f477c78cf5ca53de57a76237c59376a0080b946555517792021-06-13 1:51:011 hr 28 mins ago0x9923c5a0dd1d8beb1611b44ce161e1a393a67f21 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00078152976
0xe7ad485f8f0f1d2ebe6b8a2c1161ba058226025d380da2b39c19e1b7c7aef6c555516952021-06-13 1:46:491 hr 32 mins ago0x2c14abea23c5cb87bdfb4ec9d561a633d4329cea IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588579
0xee7321a50e6df1768c5d0cc63cb54f0a27f41dfad479088286bdad4a0f2191af55513792021-06-13 1:31:011 hr 48 mins ago0xeb465e1cbb8feef57053f98890cefbbec7044cb1 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588579
0x6cad295583c275a054a1e5ba77bde31c8b7f32f4d8eeec002547f4f5af3b704d55513572021-06-13 1:29:551 hr 49 mins ago0xeb465e1cbb8feef57053f98890cefbbec7044cb1 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000603591
0xfca666012ea339e55ff27ea1df453d7a067f08add944dfedb03951514734f2e455513502021-06-13 1:29:341 hr 49 mins ago0x550786441d5dc21963c3fc005dc2e358db1c1105 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00052485
0x5566730568930c2f37bbcb7f16f625fd53f41a10ffa0bcb6d1b8826b4a6f4b5755510142021-06-13 1:12:462 hrs 6 mins ago0x058aae506d5155e81ca942fcddb0b7fe2f57ecfa IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00046485
0x72872ba48551497093e3d089578a6962c8238a4bc3dff050aeb31dfe28f63ecb55509592021-06-13 1:10:012 hrs 9 mins ago0x6500ef256139e207f156dd63b12d4b866340d2eb IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000588579
0x048662d51f1faa62882996c4346ae4fb8ec56c5e8f9399fe22bec2a959dcce4755508152021-06-13 1:02:492 hrs 16 mins ago0x34941902a7a325f7b941ae070cb9a82bce85093d IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.00050985
0x2fba31addf4efbf27bd5ec3c294b168211676ee5db2e324a912573fb0018a42b55507932021-06-13 1:01:432 hrs 17 mins ago0x859023468f7f166814cf8d6727639e69f40a77f3 IN  0x6d9ed5d07d7761d05f05832ab695d233e8fdc3e90 HT0.000602964
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiRewardTokenPool

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 9999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at hecoinfo.com on 2021-05-14
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/EnumerableSet.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


pragma solidity >=0.6.2 <0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

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

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

// File: @openzeppelin/contracts/math/SafeMath.sol


pragma solidity >=0.6.0 <0.8.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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @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) {
        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, reverting 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) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * 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);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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: @openzeppelin/contracts/token/ERC20/IERC20.sol


pragma solidity >=0.6.0 <0.8.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: @openzeppelin/contracts/token/ERC20/SafeERC20.sol


pragma solidity >=0.6.0 <0.8.0;




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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


pragma solidity >=0.6.0 <0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with 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: @openzeppelin/contracts/access/Ownable.sol


pragma solidity >=0.6.0 <0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

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

// File: contracts/boardroom/MultiRewardTokenPool.sol

pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;




contract MultiRewardTokenPool is Ownable {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;
    using EnumerableSet for EnumerableSet.AddressSet;

    event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
    event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, uint256 indexed lockedId, uint256 penlaty);
    event PoolAdded(uint256 pid, address indexed stakedToken, uint256 allocPoint);
    event PoolSetted(uint256 pid, address indexed stakedToken, uint256 allocPoint);
    event RewardTokenAdded(address indexed rewardToken, uint256 decimals, uint256 rid);
    
    struct LockedInfo {
        uint256 amount;
        uint256 stakedTime;
        uint256 expireTime;
        uint256 unlockTime;
        bool isWithdrawed;
    }
    
    // Info of each user.
    struct UserInfo {
        uint256 totalAmount;     // How many staked tokens the user has provided.
        // Reward debt corresponding rid
        mapping (uint256 => uint256) rewardDebt; 
        LockedInfo[] lockedInfo;
    }
    
    // Info of each pools.
    struct PoolInfo {
        IERC20 stakedToken;           
        uint256 allocPoint;
        // lastReardBlock corresponding rid
        mapping (uint256 => uint256) lastRewardBlock;
        // accRewardPerShare corresponding rid
        mapping (uint256 => uint256) accRewardPerShare;
        uint256 totalAmount;
        uint256 totalStakedAddress;
    }

    struct RewardTokenInfo {
        IERC20 rewardToken;
        string symbol;
        uint256 decimals;
        uint256 magicNumber;
        uint256 startBlock;
        uint256 endBlock;
        uint256 rewardPerBlock;
        uint256 tokenRemaining;
        uint256 tokenRewarded;
        uint256 rid;
    }
    
    RewardTokenInfo[] public rewardTokenInfo;
    PoolInfo[] public poolInfo;
    // Info of each user that stakes tokens corresponding pid
    mapping (uint256 => mapping (address => UserInfo)) public userInfo;
    // Is staked address corresponding pid
    mapping (uint256 => mapping (address => bool)) isStakedAddress;
    
    uint256 public totalAllocPoint;
    uint256 public rewardCycle = 7 days;
    uint256 public lockedTime = 30 days;
    uint256 public phase1Time = 10 days;
    uint256 public phase2Time = 20 days;
    uint256 public PENLATY_RATIO1 = 30;
    uint256 public PENLATY_RATIO2 = 20;
    uint256 public PENLATY_RATIO3 = 10;
    // Speed of block, default every block / 3s on Heco chain
    uint256 public blockSpeed = 3;
    // pid corresponding pool staked token address
    mapping(address => uint256) public pidOfPool;
    // rid corresponding reward token address
    mapping(address => uint256) public ridOfReward;
    mapping(uint256 => address) public setterOfRid;
    mapping(address => bool) public isExistedRewardToken;
    EnumerableSet.AddressSet private _setter;
    address public BLACK_HOLE;

    modifier onlySetter() {
        require(isSetter(msg.sender), "MultiRewardTokenPool: Not the setter");
        _;
    }
    
    constructor(address _blackHole) public {
        BLACK_HOLE = _blackHole;
        EnumerableSet.add(_setter, msg.sender);
    }

    function getSetterLength() public view returns (uint256) {
        return EnumerableSet.length(_setter);
    }

    function isSetter(address _set) public view returns (bool) {
        return EnumerableSet.contains(_setter, _set);
    }

    function getSetter(uint256 _index) public view returns (address){
        require(_index <= getSetterLength() - 1, "MultiRewardTokenPool: index out of bounds");
        return EnumerableSet.at(_setter, _index);
    }
    
    function getRewardTokenInfo() external view returns(RewardTokenInfo[] memory) {
        return rewardTokenInfo;
    }
    
    // Return reward multiplier over the given _from to _to block.
    function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
        return _to.sub(_from);
    }
    
    function getUserLockedInfo(uint256 _pid, address _user) public view returns(LockedInfo[] memory) {
        UserInfo memory user = userInfo[_pid][_user];
        return user.lockedInfo;
    }
    
    function getCurrentBlock() public view returns(uint256) {
        return block.number;
    }
    
    function getUserLockedAmount(uint256 _pid, address _user) public view returns(uint256) {
        UserInfo memory user = userInfo[_pid][_user];
        LockedInfo[] memory lockedInfo = user.lockedInfo;
        uint256 lockedAmount = 0;
        for(uint i = 0; i < lockedInfo.length; i++) {
            if (lockedInfo[i].expireTime > block.timestamp && !lockedInfo[i].isWithdrawed) {
                lockedAmount = lockedAmount.add(lockedInfo[i].amount);
            }
        }
        return lockedAmount;
    }
    
    function pendingRewards(uint256 _rid, uint256 _pid, address _user) public view returns(uint256) {
        PoolInfo storage pool = poolInfo[_pid];
        UserInfo storage user = userInfo[_pid][_user];
        RewardTokenInfo storage token = rewardTokenInfo[_rid];
        uint256 accRewardPerShare = pool.accRewardPerShare[_rid];
        uint256 lastRewardBlock = pool.lastRewardBlock[_rid];
        uint256 stakedTokenSupply = pool.stakedToken.balanceOf(address(this));
        if (block.number > lastRewardBlock && stakedTokenSupply != 0) {
            uint256 multiplier = getMultiplier(lastRewardBlock, block.number);
            uint256 tokenReward = multiplier.mul(token.rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
            if (tokenReward > token.tokenRemaining) {
                // In case of insufficient supply to reward
                tokenReward = token.tokenRemaining;
            }
            accRewardPerShare = accRewardPerShare.add(tokenReward.mul(token.magicNumber).div(stakedTokenSupply));
        }
        return user.totalAmount.mul(accRewardPerShare).div(token.magicNumber).sub(user.rewardDebt[_rid]);
    }
    
    function updatePool(uint256 _pid, uint256 _rid) public {
        PoolInfo storage pool = poolInfo[_pid];
        RewardTokenInfo storage token = rewardTokenInfo[_rid];
        uint256 lastRewardBlock = pool.lastRewardBlock[_rid];
        
        if (block.number <= lastRewardBlock) {
            return;
        }
        
        uint256 stakedTokenSupply = pool.stakedToken.balanceOf(address(this));
        if (stakedTokenSupply == 0 || token.tokenRemaining == 0) {
            pool.lastRewardBlock[_rid] = block.number;
            return;
        }

        uint256 multiplier = getMultiplier(lastRewardBlock, block.number);
        uint256 tokenReward = multiplier.mul(token.rewardPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
        if (tokenReward > token.tokenRemaining) {
            // In case of insufficient supply to reward
            tokenReward = token.tokenRemaining;
            token.tokenRemaining = 0;
        } else {
            token.tokenRemaining = token.tokenRemaining.sub(tokenReward);
        }
        token.tokenRewarded = token.tokenRewarded.add(tokenReward);
        pool.accRewardPerShare[_rid] = pool.accRewardPerShare[_rid].add(tokenReward.mul(token.magicNumber).div(stakedTokenSupply));
        pool.lastRewardBlock[_rid] = block.number;
    }
    
    function massUpdatePools() public {
        uint256 length = poolInfo.length;
        for (uint256 pid = 0; pid < length; ++pid) {
            for (uint256 rid = 0; rid < rewardTokenInfo.length; ++rid) {
                updatePool(pid, rid);
            }
        }
    }
    
    function deposit(uint256 _pid, uint256 _amount) public {
        PoolInfo storage pool = poolInfo[_pid];
        address _user = msg.sender;
        UserInfo storage user = userInfo[_pid][_user];
        for (uint256 rid = 0; rid < rewardTokenInfo.length; ++rid) {
            updatePool(_pid, rid);
            if (user.totalAmount > 0) {
                uint256 pending = user.totalAmount.mul(pool.accRewardPerShare[rid]).div(rewardTokenInfo[rid].magicNumber).sub(user.rewardDebt[rid]);
                if(pending > 0) {
                    _safeTokenTransfer(rewardTokenInfo[rid].rewardToken, msg.sender, pending);
                }
            }
        }
        if(_amount > 0) {
            pool.stakedToken.safeTransferFrom(address(msg.sender), address(this), _amount);
            user.totalAmount = user.totalAmount.add(_amount); 
            pool.totalAmount = pool.totalAmount.add(_amount);
            user.lockedInfo.push(LockedInfo(
                _amount,
                block.timestamp,
                block.timestamp.add(lockedTime),
                0,
                false
            ));
            if (!isStakedAddress[_pid][_user]) {
                isStakedAddress[_pid][_user] = true;
                pool.totalStakedAddress = pool.totalStakedAddress.add(1);
            }
        }
        for (uint256 rid = 0; rid < rewardTokenInfo.length; ++rid) {
            user.rewardDebt[rid] = user.totalAmount.mul(pool.accRewardPerShare[rid]).div(rewardTokenInfo[rid].magicNumber);
        }
        emit Deposit(msg.sender, _pid, _amount);
    }
    
    function withdraw(uint256 _pid, uint256 _amount, uint256 _lockedId) public {
        PoolInfo storage pool = poolInfo[_pid];
        address _user = msg.sender;
        UserInfo storage user = userInfo[_pid][_user];
        for (uint256 rid = 0; rid < rewardTokenInfo.length; ++rid) {
            updatePool(_pid, rid);
            if (user.totalAmount > 0) {
                uint256 pending = user.totalAmount.mul(pool.accRewardPerShare[rid]).div(rewardTokenInfo[rid].magicNumber).sub(user.rewardDebt[rid]);
                if(pending > 0) {
                    _safeTokenTransfer(rewardTokenInfo[rid].rewardToken, msg.sender, pending);
                }
            }
        }
        uint256 penlaty = 0;
        if (_amount > 0) {
            require(!user.lockedInfo[_lockedId].isWithdrawed, "MultiRewardTokenPool: This amount of lockedId is withdrawed");
            require(user.lockedInfo[_lockedId].amount == _amount, "MultiRewardTokenPool: Invalid amount of lockedId");
            uint256 expireTime = user.lockedInfo[_lockedId].expireTime;
            uint256 stakedTime = user.lockedInfo[_lockedId].stakedTime;
            if (expireTime < block.timestamp) {
                pool.stakedToken.safeTransfer(address(msg.sender), _amount);
            } else {
                uint256 interval = block.timestamp - stakedTime;
                if (interval <= phase1Time) {
                    penlaty = _amount.mul(PENLATY_RATIO1).div(100);
                } else if (interval <= phase2Time) {
                    penlaty = _amount.mul(PENLATY_RATIO2).div(100);
                } else {
                    penlaty = _amount.mul(PENLATY_RATIO3).div(100);
                }
                pool.stakedToken.safeTransfer(address(msg.sender), _amount.sub(penlaty));
                // transfer penlaty to black hole address
                pool.stakedToken.safeTransfer(BLACK_HOLE, penlaty);
            }
            user.lockedInfo[_lockedId].unlockTime = block.timestamp;
            user.totalAmount = user.totalAmount.sub(_amount); 
            pool.totalAmount = pool.totalAmount.sub(_amount);
            _setIsWithdrawedToTrue(_pid, msg.sender, _lockedId);
            if (user.totalAmount == 0) {
                isStakedAddress[_pid][_user] = false;
                pool.totalStakedAddress = pool.totalStakedAddress.sub(1);
            }
        }
        for (uint256 rid = 0; rid < rewardTokenInfo.length; ++rid) {
            user.rewardDebt[rid] = user.totalAmount.mul(pool.accRewardPerShare[rid]).div(rewardTokenInfo[rid].magicNumber);
        }
        emit Withdraw(msg.sender, _pid, _amount, _lockedId, penlaty);
    }

    // ======== INTERNAL METHODS ========= //
    
    function _safeTokenTransfer(IERC20 _token, address _to, uint256 _amount) internal {
        uint256 tokenBal = _token.balanceOf(address(this));
        if (_amount > tokenBal) {
            _token.transfer(_to, tokenBal);
        } else {
            _token.transfer(_to, _amount);
        }
    }
    
    function _setIsWithdrawedToTrue(uint256 _pid, address _user, uint256 _lockedId) internal {
        UserInfo storage user = userInfo[_pid][_user];
        user.lockedInfo[_lockedId].isWithdrawed = true;
    }

    mapping(uint256 => PoolInfo) private newPool;
    
    // ======== ONLY OWNER CONTROL METHODS ========== //

    function addSetter(address _newSetter) public onlyOwner returns (bool) {
        require(_newSetter != address(0), "MultiRewardTokenPool: NewSetter is the zero address");
        return EnumerableSet.add(_setter, _newSetter);
    }

    function delSetter(address _delSetter) public onlyOwner returns (bool) {
        require(_delSetter != address(0), "MultiRewardTokenPool: DelSetter is the zero address");
        return EnumerableSet.remove(_setter, _delSetter);
    }
    
    function addPool(
        uint256 _allocPoint, 
        IERC20 _stakedToken, 
        bool _withUpdate
    ) external onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        PoolInfo storage _newPool = newPool[0];
        for (uint rid = 0; rid < rewardTokenInfo.length; ++rid) {
            uint256 startBlock = rewardTokenInfo[rid].startBlock;
            uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
            _newPool.lastRewardBlock[rid] = lastRewardBlock;
            _newPool.accRewardPerShare[rid] = 0;
        }
        _newPool.stakedToken = _stakedToken;
        _newPool.allocPoint = _allocPoint;
        _newPool.totalAmount = 0;
        _newPool.totalStakedAddress = 0;
        poolInfo.push(_newPool);
        totalAllocPoint = totalAllocPoint.add(_allocPoint);
        pidOfPool[address(_stakedToken)] = poolInfo.length.sub(1);
        emit PoolAdded(poolInfo.length - 1, address(_stakedToken), _allocPoint);
    }
    
    function setPool(
        uint256 _pid, 
        uint256 _allocPoint, 
        bool _withUpdate    
    ) external onlyOwner {
        if (_withUpdate) {
            massUpdatePools();
        }
        totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
        poolInfo[_pid].allocPoint = _allocPoint;
        emit PoolSetted(_pid, address(poolInfo[_pid].stakedToken), _allocPoint);
    }
    
    function setRewardCycle(uint256 cycle) external onlyOwner {
        rewardCycle = cycle;
    }
    
    function setLockedTime(uint256 time) external onlyOwner {
        lockedTime = time;
    }
    
    function setPhase1Time(uint256 time) external onlyOwner {
        phase1Time = time;
    }
    
    function setPhase2Time(uint256 time) external onlyOwner {
        phase2Time = time;
    }
    
    function setPenlatyRatio1(uint256 ratio) external onlyOwner {
        PENLATY_RATIO1 = ratio;
    }
    
    function setPenlatyRatio2(uint256 ratio) external onlyOwner {
        PENLATY_RATIO2 = ratio;
    }
    
    function setPenlatyRatio3(uint256 ratio) external onlyOwner {
        PENLATY_RATIO3 = ratio;
    }
    
    function setBlockSpeed(uint256 speed) external onlyOwner {
        blockSpeed = speed;
    }
    
    // Withdraw Token rewards for emergency 
    function emergencyWithdrawRewards(uint256 rid) external onlyOwner {
        _safeTokenTransfer(rewardTokenInfo[rid].rewardToken, msg.sender, rewardTokenInfo[rid].rewardToken.balanceOf(address(this)));
        rewardTokenInfo[rid].tokenRemaining = 0;
    }
    
    function setDecimalsOfRewardToken(uint256 rid, uint256 _decimals) external onlyOwner {
        RewardTokenInfo storage rewardToken = rewardTokenInfo[rid];
        rewardToken.decimals = _decimals;
    }
    
    function setSymbolOfRewardToken(uint256 rid, string memory _symbol) external onlyOwner {
        RewardTokenInfo storage rewardToken = rewardTokenInfo[rid];
        rewardToken.symbol = _symbol;
    }

    function addRewardToken(
        uint256 _startTime,
        address _rewardToken,
        uint256 _decimals,
        string memory _symbol
    ) external onlySetter {
        require(_startTime > block.timestamp, "MultiRewardTokenPool: invalid start time");
        require(_rewardToken != address(poolInfo[0].stakedToken), "MultiRewardTokenPool: can't add DOG to be reward token");
        require(!isExistedRewardToken[_rewardToken], "MultiRewardTokenPool: existed reward token");
        massUpdatePools();
        rewardTokenInfo.push(RewardTokenInfo({
            rewardToken: IERC20(_rewardToken),
            decimals: _decimals,
            symbol: _symbol,
            magicNumber: 10 ** (30 - _decimals),
            startBlock: block.number + (_startTime - block.timestamp) / blockSpeed,
            endBlock: block.number + (_startTime - block.timestamp) / blockSpeed,
            rewardPerBlock: 0,
            tokenRemaining: 0,
            tokenRewarded: 0,
            rid: rewardTokenInfo.length
        }));
        ridOfReward[_rewardToken] = rewardTokenInfo.length - 1;
        setterOfRid[rewardTokenInfo.length - 1] = msg.sender;
        isExistedRewardToken[_rewardToken] = true;
        emit RewardTokenAdded(_rewardToken, _decimals, rewardTokenInfo.length - 1);
    }
    
    // Deposit new reward of Token and update TokenPerBlock by rid filter
    function depoistRewardToken(uint256 amount, uint256 rid) onlySetter external {
        require(setterOfRid[rid] == msg.sender, "MultiRewardTokenPool: incorrect setter of this reward token pool");
        massUpdatePools();
        RewardTokenInfo storage token = rewardTokenInfo[rid];
        uint256 prevBal = token.rewardToken.balanceOf(address(this));
        uint256 amountUnit = 10 ** token.decimals;
        token.rewardToken.safeTransferFrom(address(msg.sender), address(this), amount * amountUnit);
        uint256 currBal = token.rewardToken.balanceOf(address(this));
        require((currBal - prevBal) == amount * amountUnit, "MultiRewardTokenPool: incorrect balance after depositing");
        token.tokenRemaining = token.tokenRemaining.add(amount * amountUnit);
        token.rewardPerBlock = token.tokenRemaining.div(rewardCycle.div(blockSpeed));
        token.endBlock = block.number.add(rewardCycle.div(blockSpeed));
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_blackHole","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakedToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"PoolAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"stakedToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"PoolSetted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rid","type":"uint256"}],"name":"RewardTokenAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"lockedId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"penlaty","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BLACK_HOLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENLATY_RATIO1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENLATY_RATIO2","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PENLATY_RATIO3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_stakedToken","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_decimals","type":"uint256"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"addRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSetter","type":"address"}],"name":"addSetter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blockSpeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delSetter","type":"address"}],"name":"delSetter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rid","type":"uint256"}],"name":"depoistRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rid","type":"uint256"}],"name":"emergencyWithdrawRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getRewardTokenInfo","outputs":[{"components":[{"internalType":"contract IERC20","name":"rewardToken","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"magicNumber","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"tokenRemaining","type":"uint256"},{"internalType":"uint256","name":"tokenRewarded","type":"uint256"},{"internalType":"uint256","name":"rid","type":"uint256"}],"internalType":"struct MultiRewardTokenPool.RewardTokenInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getSetter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSetterLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserLockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"getUserLockedInfo","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"stakedTime","type":"uint256"},{"internalType":"uint256","name":"expireTime","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"bool","name":"isWithdrawed","type":"bool"}],"internalType":"struct MultiRewardTokenPool.LockedInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExistedRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_set","type":"address"}],"name":"isSetter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rid","type":"uint256"},{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase1Time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phase2Time","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"pidOfPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"stakedToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"totalStakedAddress","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardCycle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokenInfo","outputs":[{"internalType":"contract IERC20","name":"rewardToken","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"uint256","name":"magicNumber","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"tokenRemaining","type":"uint256"},{"internalType":"uint256","name":"tokenRewarded","type":"uint256"},{"internalType":"uint256","name":"rid","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ridOfReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"speed","type":"uint256"}],"name":"setBlockSpeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rid","type":"uint256"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setDecimalsOfRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setLockedTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"setPenlatyRatio1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"setPenlatyRatio2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"setPenlatyRatio3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setPhase1Time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"setPhase2Time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cycle","type":"uint256"}],"name":"setRewardCycle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rid","type":"uint256"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"setSymbolOfRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"setterOfRid","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","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":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_rid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_lockedId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405262093a8060065562278d00600755620d2f00600855621a5e00600955601e600a556014600b55600a600c556003600d553480156200004157600080fd5b5060405162003d3c38038062003d3c833981016040819052620000649162000181565b600062000070620000f6565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350601480546001600160a01b0319166001600160a01b038316179055620000ee601233620000fa602090811b6200269417901c565b5050620001b1565b3390565b600062000111836001600160a01b0384166200011a565b90505b92915050565b600062000128838362000169565b620001605750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000114565b50600062000114565b60009081526001919091016020526040902054151590565b60006020828403121562000193578081fd5b81516001600160a01b0381168114620001aa578182fd5b9392505050565b613b7b80620001c16000396000f3fe608060405234801561001057600080fd5b50600436106103365760003560e01c8063672d5d3b116101b25780639f094877116100f9578063c555e5e7116100a2578063df1dcaa91161007c578063df1dcaa914610667578063e2bbb1581461067a578063f2fde38b1461068d578063f5a696fd146106a057610336565b8063c555e5e714610639578063d8a1c74e1461064c578063d92607791461065457610336565b8063a8b38205116100d3578063a8b382051461060b578063b168824014610613578063b7c50c4c1461062657610336565b80639f094877146105e8578063a41fe49f146105f0578063a5ffbe311461060357610336565b806382a914591161015b57806393f1a40b1161013557806393f1a40b146105ba578063940bdc85146105cd57806396ed7f89146105d557610336565b806382a91459146105975780638da5cb5b1461059f5780638dbb1e3a146105a757610336565b8063715018a61161018c578063715018a614610569578063758bddf6146105715780637abceffd1461058457610336565b8063672d5d3b146105515780636912b2f8146105595780636ee010ae1461056157610336565b8063360a59e61161028157806349206d731161022a57806355eda4e81161020457806355eda4e8146105195780635793ed8014610521578063630b5ba114610534578063647428b91461053c57610336565b806349206d73146104d35780634e439a97146104e65780634ee018211461050657610336565b80634479fc671161025b5780634479fc6714610484578063456882bb146104ad57806346ca6bea146104c057610336565b8063360a59e61461044b5780633ca85f4d1461045e5780633fe543d71461047157610336565b80631526fe27116102e357806326e8159f116102bd57806326e8159f1461040557806330409c8514610418578063343dc3161461042b57610336565b80631526fe27146103c757806317caf6f1146103ea57806322c28011146103f257610336565b80630d2b19c6116103145780630d2b19c61461038e5780630fc4f00f146103a1578063134f5af9146103b457610336565b806305682a7b1461033b57806307167e9d146103645780630a33354714610379575b600080fd5b61034e610349366004612f45565b6106b3565b60405161035b91906131a4565b60405180910390f35b61036c6106ce565b60405161035b9190613adc565b61038c610387366004612f45565b6106d4565b005b61036c61039c3660046130ac565b610721565b61038c6103af366004612f45565b610912565b61038c6103c2366004612fa4565b610956565b6103da6103d5366004612f45565b610c12565b60405161035b94939291906133c1565b61036c610c53565b61038c610400366004612f45565b610c59565b61038c610413366004612f45565b610c9d565b61038c610426366004612f45565b610ce1565b61043e610439366004612f0d565b610e36565b60405161035b9190613351565b61043e610459366004612f0d565b610eae565b61038c61046c366004612f45565b610ec3565b61038c61047f36600461308b565b610f07565b610497610492366004612f45565b610f70565b60405161035b9a9998979695949392919061335c565b61036c6104bb366004612f75565b611064565b61038c6104ce3660046130d9565b6111be565b61036c6104e1366004612f0d565b6112da565b6104f96104f4366004612f75565b6112ec565b60405161035b91906131f5565b61036c610514366004612f0d565b6113be565b61034e6113d0565b61043e61052f366004612f0d565b6113df565b61038c611451565b61054461148b565b60405161035b9190613265565b61036c6115e4565b61036c6115e8565b61036c6115ee565b61038c6115f4565b61038c61057f366004612f45565b611695565b61038c610592366004613005565b6116d9565b61036c611936565b61034e61193c565b61036c6105b536600461308b565b61194b565b61036c6105c8366004612f75565b611957565b61036c611974565b61038c6105e336600461308b565b61197a565b61036c611b88565b61038c6105fe366004613106565b611b8e565b61036c611f6c565b61036c611f7d565b61038c610621366004613046565b611f83565b61043e610634366004612f0d565b611fff565b61038c61064736600461308b565b61200c565b61036c612277565b61034e610662366004612f45565b61227d565b61038c610675366004612f45565b6122b4565b61038c61068836600461308b565b6122f8565b61038c61069b366004612f0d565b612578565b61038c6106ae366004612f45565b612650565b6010602052600090815260409020546001600160a01b031681565b60085481565b6106dc6126a9565b6001600160a01b03166106ed61193c565b6001600160a01b03161461071c5760405162461bcd60e51b81526004016107139061389f565b60405180910390fd5b600d55565b6000806002848154811061073157fe5b600091825260208083208784526003825260408085206001600160a01b0389168652909252908320600180546006909402909201945092918890811061077357fe5b600091825260208083208a84526003870182526040808520546002890190935280852054885491517f70a08231000000000000000000000000000000000000000000000000000000008152600a90950290920195509193909290916001600160a01b0316906370a08231906107ec9030906004016131a4565b60206040518083038186803b15801561080457600080fd5b505afa158015610818573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083c9190612f5d565b9050814311801561084c57508015155b156108d157600061085d834361194b565b9050600061089260055461088c8a600101546108868a60060154876126ad90919063ffffffff16565b906126ad565b906126e7565b905085600701548111156108a7575060078501545b6108cc6108c58461088c8960030154856126ad90919063ffffffff16565b8690612719565b945050505b60008a81526001860160205260409020546003850154865461090292916108fc9161088c90886126ad565b9061273e565b96505050505050505b9392505050565b61091a6126a9565b6001600160a01b031661092b61193c565b6001600160a01b0316146109515760405162461bcd60e51b81526004016107139061389f565b600b55565b61095f33611fff565b61097b5760405162461bcd60e51b8152600401610713906139c5565b42841161099a5760405162461bcd60e51b81526004016107139061372b565b60026000815481106109a857fe5b60009182526020909120600690910201546001600160a01b03848116911614156109e45760405162461bcd60e51b815260040161071390613842565b6001600160a01b03831660009081526011602052604090205460ff1615610a1d5760405162461bcd60e51b815260040161071390613a22565b610a25611451565b6001604051806101400160405280856001600160a01b0316815260200183815260200184815260200184601e03600a0a8152602001600d5442880381610a6757fe5b0443018152602001600d5442880381610a7c57fe5b04430181526000602080830182905260408301829052606083018290526001805460809094019390935284548084018655948252908190208351600a9095020180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909516949094178455828101518051939493610b0b938501929190910190612dc4565b506040828101516002830155606083015160038301556080830151600483015560a0830151600583015560c0830151600683015560e08301516007830155610100830151600883015561012090920151600990910155600180546001600160a01b0386166000818152600f602090815285822060001994850190558454840182526010815285822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905582825260119052849020805460ff1916841790559154925191927f1967f04d043dcde420379c946155c044c22bb82e58a86f811326133e4f365e5192610c049287920190613ae5565b60405180910390a250505050565b60028181548110610c1f57fe5b600091825260209091206006909102018054600182015460048301546005909301546001600160a01b039092169350919084565b60055481565b610c616126a9565b6001600160a01b0316610c7261193c565b6001600160a01b031614610c985760405162461bcd60e51b81526004016107139061389f565b600655565b610ca56126a9565b6001600160a01b0316610cb661193c565b6001600160a01b031614610cdc5760405162461bcd60e51b81526004016107139061389f565b600955565b610ce96126a9565b6001600160a01b0316610cfa61193c565b6001600160a01b031614610d205760405162461bcd60e51b81526004016107139061389f565b610e0f60018281548110610d3057fe5b90600052602060002090600a020160000160009054906101000a90046001600160a01b03163360018481548110610d6357fe5b60009182526020909120600a90910201546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906370a0823190610dba9030906004016131a4565b60206040518083038186803b158015610dd257600080fd5b505afa158015610de6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0a9190612f5d565b612766565b600060018281548110610e1e57fe5b90600052602060002090600a02016007018190555050565b6000610e406126a9565b6001600160a01b0316610e5161193c565b6001600160a01b031614610e775760405162461bcd60e51b81526004016107139061389f565b6001600160a01b038216610e9d5760405162461bcd60e51b8152600401610713906138d4565b610ea8601283612947565b92915050565b60116020526000908152604090205460ff1681565b610ecb6126a9565b6001600160a01b0316610edc61193c565b6001600160a01b031614610f025760405162461bcd60e51b81526004016107139061389f565b600c55565b610f0f6126a9565b6001600160a01b0316610f2061193c565b6001600160a01b031614610f465760405162461bcd60e51b81526004016107139061389f565b600060018381548110610f5557fe5b600091825260209091206002600a9092020101919091555050565b60018181548110610f7d57fe5b6000918252602091829020600a9091020180546001808301805460408051601f60026000199685161561010002969096019093169490940491820187900487028401870190528083526001600160a01b03909316955092939092919083018282801561102a5780601f10610fff5761010080835404028352916020019161102a565b820191906000526020600020905b81548152906001019060200180831161100d57829003601f168201915b505050505090806002015490806003015490806004015490806005015490806006015490806007015490806008015490806009015490508a565b600061106e612e42565b60008481526003602090815260408083206001600160a01b0387168452825280832081518083018352815481526002820180548451818702810187019095528085529195929486810194939192919084015b828210156111235760008481526020908190206040805160a081018252600586029092018054835260018082015484860152600282015492840192909252600381015460608401526004015460ff161515608083015290835290920191016110c0565b5050509152505060208101519091506000805b82518110156111b4574283828151811061114c57fe5b60200260200101516040015111801561117a575082818151811061116c57fe5b602002602001015160800151155b156111ac576111a983828151811061118e57fe5b6020026020010151600001518361271990919063ffffffff16565b91505b600101611136565b5095945050505050565b6111c66126a9565b6001600160a01b03166111d761193c565b6001600160a01b0316146111fd5760405162461bcd60e51b81526004016107139061389f565b801561120b5761120b611451565b611248826112426002868154811061121f57fe5b90600052602060002090600602016001015460055461273e90919063ffffffff16565b90612719565b600581905550816002848154811061125c57fe5b9060005260206000209060060201600101819055506002838154811061127e57fe5b60009182526020909120600690910201546040516001600160a01b03909116907fe6f0f5459b1bab05d18afd5d02a2f33a1dd98c95930325c2a744565241077817906112cd9086908690613ae5565b60405180910390a2505050565b600f6020526000908152604090205481565b60606112f6612e42565b60008481526003602090815260408083206001600160a01b0387168452825280832081518083018352815481526002820180548451818702810187019095528085529195929486810194939192919084015b828210156113ab5760008481526020908190206040805160a081018252600586029092018054835260018082015484860152600282015492840192909252600381015460608401526004015460ff16151560808301529083529092019101611348565b5050509152505060200151949350505050565b600e6020526000908152604090205481565b6014546001600160a01b031681565b60006113e96126a9565b6001600160a01b03166113fa61193c565b6001600160a01b0316146114205760405162461bcd60e51b81526004016107139061389f565b6001600160a01b0382166114465760405162461bcd60e51b815260040161071390613457565b610ea8601283612694565b60025460005b818110156114875760005b60015481101561147e57611476828261197a565b600101611462565b50600101611457565b5050565b60606001805480602002602001604051908101604052809291908181526020016000905b828210156115db5760008481526020908190206040805161014081018252600a860290920180546001600160a01b03168352600180820180548451600261010094831615949094026000190190911692909204601f8101879004870283018701909452838252939491938583019391929091908301828280156115735780601f1061154857610100808354040283529160200191611573565b820191906000526020600020905b81548152906001019060200180831161155657829003601f168201915b5050505050815260200160028201548152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820154815260200160088201548152602001600982015481525050815260200190600101906114af565b50505050905090565b4390565b600c5481565b60065481565b6115fc6126a9565b6001600160a01b031661160d61193c565b6001600160a01b0316146116335760405162461bcd60e51b81526004016107139061389f565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b61169d6126a9565b6001600160a01b03166116ae61193c565b6001600160a01b0316146116d45760405162461bcd60e51b81526004016107139061389f565b600a55565b6116e16126a9565b6001600160a01b03166116f261193c565b6001600160a01b0316146117185760405162461bcd60e51b81526004016107139061389f565b801561172657611726611451565b600080805260156020527fa31547ce6245cdb9ecea19cf8c7eb9f5974025bb4075011409251ae855b30aed905b6001548110156117bc5760006001828154811061176c57fe5b90600052602060002090600a0201600401549050600081431161178f5781611791565b435b6000848152600286016020908152604080832093909355600387019052908120555050600101611753565b5080546001600160a01b038085167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617835560018084018781556000600486018181556005808801838155600280549687018155909352875460069095027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81018054909816959096169490941790955590547f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf84015592547f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad283015591547f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad390910155546118ce9085612719565b6005556002546118df90600161273e565b6001600160a01b0384166000818152600e60205260409081902092909255600254915190917f6c5d0ef1d0199b6de41ecbce95f59643be4d723ca363faf92d756e61e82fb13e91610c049160001901908890613ae5565b60095481565b6000546001600160a01b031690565b600061090b828461273e565b600360209081526000928352604080842090915290825290205481565b600b5481565b60006002838154811061198957fe5b906000526020600020906006020190506000600183815481106119a857fe5b90600052602060002090600a0201905060008260020160008581526020019081526020016000205490508043116119e157505050611487565b82546040517f70a082310000000000000000000000000000000000000000000000000000000081526000916001600160a01b0316906370a0823190611a2a9030906004016131a4565b60206040518083038186803b158015611a4257600080fd5b505afa158015611a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7a9190612f5d565b9050801580611a8b57506007830154155b15611aac575050506000828152600290910160205260409020439055611487565b6000611ab8834361194b565b90506000611ae160055461088c88600101546108868960060154876126ad90919063ffffffff16565b90508460070154811115611b0057506007840180546000909155611b15565b6007850154611b0f908261273e565b60078601555b6008850154611b249082612719565b60088601556003850154611b5a90611b4390859061088c9085906126ad565b600089815260038901602052604090205490612719565b6000888152600388016020908152604080832093909355600290980190975290952043905550505050505050565b600a5481565b600060028481548110611b9d57fe5b6000918252602080832087845260038252604080852033808752935284206006909302019350915b600154811015611c7757611bd9878261197a565b815415611c6f576000818152600180840160205260408220548154611c34926108fc9186908110611c0657fe5b600091825260208083206003600a90930201820154888452918b019052604090912054875461088c916126ad565b90508015611c6d57611c6d60018381548110611c4c57fe5b60009182526020909120600a90910201546001600160a01b03163383612766565b505b600101611bc5565b5060008515611eb657816002018581548110611c8f57fe5b600091825260209091206004600590920201015460ff1615611cc35760405162461bcd60e51b8152600401610713906135a5565b85826002018681548110611cd357fe5b90600052602060002090600502016000015414611d025760405162461bcd60e51b8152600401610713906134b4565b6000826002018681548110611d1357fe5b90600052602060002090600502016002015490506000836002018781548110611d3857fe5b906000526020600020906005020160010154905042821015611d6f578554611d6a906001600160a01b0316338a61295c565b611e1c565b60085442829003908111611d9e57611d97606461088c600a548c6126ad90919063ffffffff16565b9350611dde565b6009548111611dc157611d97606461088c600b548c6126ad90919063ffffffff16565b611ddb606461088c600c548c6126ad90919063ffffffff16565b93505b611dfe33611dec8b8761273e565b89546001600160a01b0316919061295c565b6014548754611e1a916001600160a01b0391821691168661295c565b505b42846002018881548110611e2c57fe5b60009182526020909120600360059092020101558354611e4c908961273e565b84556004860154611e5d908961273e565b6004870155611e6d893389612a02565b8354611eb35760008981526004602090815260408083206001600160a01b03891684529091529020805460ff191690556005860154611ead90600161273e565b60058701555b50505b60005b600154811015611f1d57611f0160018281548110611ed357fe5b600091825260208083206003600a909302018201548584529189019052604090912054855461088c916126ad565b6000828152600180860160205260409091209190915501611eb9565b508487336001600160a01b03167fe08737ac48a1dab4b1a46c7dc9398bd5bfc6d7ad6fabb7cd8caa254de14def358985604051611f5b929190613ae5565b60405180910390a450505050505050565b6000611f786012612a60565b905090565b60075481565b611f8b6126a9565b6001600160a01b0316611f9c61193c565b6001600160a01b031614611fc25760405162461bcd60e51b81526004016107139061389f565b600060018381548110611fd157fe5b90600052602060002090600a0201905081816001019080519060200190611ff9929190612dc4565b50505050565b6000610ea8601283612a6b565b61201533611fff565b6120315760405162461bcd60e51b8152600401610713906139c5565b6000818152601060205260409020546001600160a01b031633146120675760405162461bcd60e51b8152600401610713906136cd565b61206f611451565b60006001828154811061207e57fe5b600091825260208220600a9091020180546040517f70a082310000000000000000000000000000000000000000000000000000000081529193506001600160a01b0316906370a08231906120d69030906004016131a4565b60206040518083038186803b1580156120ee57600080fd5b505afa158015612102573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121269190612f5d565b60028301548354919250600a0a9061214b906001600160a01b03163330888502612a80565b82546040517f70a082310000000000000000000000000000000000000000000000000000000081526000916001600160a01b0316906370a08231906121949030906004016131a4565b60206040518083038186803b1580156121ac57600080fd5b505afa1580156121c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e49190612f5d565b9050818602838203146122095760405162461bcd60e51b815260040161071390613931565b600784015461221a90878402612719565b6007850155600d5460065461223e9161223391906126e7565b6007860154906126e7565b8460060181905550612267612260600d546006546126e790919063ffffffff16565b4390612719565b8460050181905550505050505050565b600d5481565b60006001612289611f6c565b038211156122a95760405162461bcd60e51b815260040161071390613788565b610ea8601283612aa1565b6122bc6126a9565b6001600160a01b03166122cd61193c565b6001600160a01b0316146122f35760405162461bcd60e51b81526004016107139061389f565b600755565b60006002838154811061230757fe5b6000918252602080832086845260038252604080852033808752935284206006909302019350915b60015481101561239257612343868261197a565b81541561238a576000818152600180840160205260408220548154612370926108fc9186908110611c0657fe5b905080156123885761238860018381548110611c4c57fe5b505b60010161232f565b5083156124c75782546123b0906001600160a01b0316333087612a80565b80546123bc9085612719565b815560048301546123cd9085612719565b60048401556040805160a081018252858152426020820181905260075460028501938301916123fb91612719565b815260006020808301829052604092830182905284546001808201875595835281832085516005909202019081558482015195810195909555838301516002860155606084015160038601556080909301516004948501805460ff19169115159190911790558881529282528083206001600160a01b038616845290915290205460ff166124c75760008581526004602090815260408083206001600160a01b03861684529091529020805460ff1916600190811790915560058401546124c191612719565b60058401555b60005b60015481101561252e57612512600182815481106124e457fe5b600091825260208083206003600a909302018201548584529188019052604090912054845461088c916126ad565b60008281526001808501602052604090912091909155016124ca565b5084336001600160a01b03167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15866040516125699190613adc565b60405180910390a35050505050565b6125806126a9565b6001600160a01b031661259161193c565b6001600160a01b0316146125b75760405162461bcd60e51b81526004016107139061389f565b6001600160a01b0381166125dd5760405162461bcd60e51b815260040161071390613511565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6126586126a9565b6001600160a01b031661266961193c565b6001600160a01b03161461268f5760405162461bcd60e51b81526004016107139061389f565b600855565b600061090b836001600160a01b038416612aad565b3390565b6000826126bc57506000610ea8565b828202828482816126c957fe5b041461090b5760405162461bcd60e51b8152600401610713906137e5565b60008082116127085760405162461bcd60e51b815260040161071390613696565b81838161271157fe5b049392505050565b60008282018381101561090b5760405162461bcd60e51b81526004016107139061356e565b6000828211156127605760405162461bcd60e51b815260040161071390613602565b50900390565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526000906001600160a01b038516906370a08231906127ae9030906004016131a4565b60206040518083038186803b1580156127c657600080fd5b505afa1580156127da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127fe9190612f5d565b9050808211156128a7576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063a9059cbb9061284f90869085906004016131dc565b602060405180830381600087803b15801561286957600080fd5b505af115801561287d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a19190612f29565b50611ff9565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063a9059cbb906128ee90869086906004016131dc565b602060405180830381600087803b15801561290857600080fd5b505af115801561291c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129409190612f29565b5050505050565b600061090b836001600160a01b038416612af7565b6129fd8363a9059cbb60e01b848460405160240161297b9291906131dc565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612bbd565b505050565b60008381526003602090815260408083206001600160a01b038616845290915290206002810180546001919084908110612a3857fe5b60009182526020909120600590910201600401805460ff191691151591909117905550505050565b6000610ea882612c4c565b600061090b836001600160a01b038416612c50565b611ff9846323b872dd60e01b85858560405160240161297b939291906131b8565b600061090b8383612c68565b6000612ab98383612c50565b612aef57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ea8565b506000610ea8565b60008181526001830160205260408120548015612bb35783546000198083019190810190600090879083908110612b2a57fe5b9060005260206000200154905080876000018481548110612b4757fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080612b7757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ea8565b6000915050610ea8565b6060612c12826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612cad9092919063ffffffff16565b8051909150156129fd5780806020019051810190612c309190612f29565b6129fd5760405162461bcd60e51b815260040161071390613a7f565b5490565b60009081526001919091016020526040902054151590565b81546000908210612c8b5760405162461bcd60e51b8152600401610713906133fa565b826000018281548110612c9a57fe5b9060005260206000200154905092915050565b6060612cbc8484600085612cc4565b949350505050565b606082471015612ce65760405162461bcd60e51b815260040161071390613639565b612cef85612d85565b612d0b5760405162461bcd60e51b81526004016107139061398e565b60006060866001600160a01b03168587604051612d289190613188565b60006040518083038185875af1925050503d8060008114612d65576040519150601f19603f3d011682016040523d82523d6000602084013e612d6a565b606091505b5091509150612d7a828286612d8b565b979650505050505050565b3b151590565b60608315612d9a57508161090b565b825115612daa5782518084602001fd5b8160405162461bcd60e51b815260040161071391906133e7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612e0557805160ff1916838001178555612e32565b82800160010185558215612e32579182015b82811115612e32578251825591602001919060010190612e17565b50612e3e929150612e5c565b5090565b604051806040016040528060008152602001606081525090565b5b80821115612e3e5760008155600101612e5d565b600082601f830112612e81578081fd5b813567ffffffffffffffff80821115612e98578283fd5b60405160207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501168201018181108382111715612ed6578485fd5b604052828152925082848301602001861015612ef157600080fd5b8260208601602083013760006020848301015250505092915050565b600060208284031215612f1e578081fd5b813561090b81613b1f565b600060208284031215612f3a578081fd5b815161090b81613b37565b600060208284031215612f56578081fd5b5035919050565b600060208284031215612f6e578081fd5b5051919050565b60008060408385031215612f87578081fd5b823591506020830135612f9981613b1f565b809150509250929050565b60008060008060808587031215612fb9578182fd5b843593506020850135612fcb81613b1f565b925060408501359150606085013567ffffffffffffffff811115612fed578182fd5b612ff987828801612e71565b91505092959194509250565b600080600060608486031215613019578283fd5b83359250602084013561302b81613b1f565b9150604084013561303b81613b37565b809150509250925092565b60008060408385031215613058578182fd5b82359150602083013567ffffffffffffffff811115613075578182fd5b61308185828601612e71565b9150509250929050565b6000806040838503121561309d578182fd5b50508035926020909101359150565b6000806000606084860312156130c0578283fd5b8335925060208401359150604084013561303b81613b1f565b6000806000606084860312156130ed578283fd5b8335925060208401359150604084013561303b81613b37565b60008060006060848603121561311a578283fd5b505081359360208301359350604090920135919050565b6001600160a01b03169052565b60008151808452613156816020860160208601613af3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000825161319a818460208701613af3565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b602080825282518282018190526000919060409081850190868401855b8281101561325857815180518552868101518786015285810151868601526060808201519086015260809081015115159085015260a09093019290850190600101613212565b5091979650505050505050565b60208082528251828201819052600091906040908185019080840286018301878501865b83811015613343577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281516101406132c8858351613131565b88820151818a8701526132dd8287018261313e565b838a0151878b0152606080850151908801526080808501519088015260a0808501519088015260c0808501519088015260e08085015190880152610100808501519088015261012093840151939096019290925250509386019390860190600101613289565b509098975050505050505050565b901515815260200190565b60006101406001600160a01b038d16835280602084015261337f8184018d61313e565b604084019b909b5250506060810197909752608087019590955260a086019390935260c085019190915260e08401526101008301526101209091015292915050565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b60006020825261090b602083018461313e565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60408201527f6473000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526033908201527f4d756c7469526577617264546f6b656e506f6f6c3a204e65775365747465722060408201527f697320746865207a65726f206164647265737300000000000000000000000000606082015260800190565b60208082526030908201527f4d756c7469526577617264546f6b656e506f6f6c3a20496e76616c696420616d60408201527f6f756e74206f66206c6f636b6564496400000000000000000000000000000000606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b6020808252603b908201527f4d756c7469526577617264546f6b656e506f6f6c3a205468697320616d6f756e60408201527f74206f66206c6f636b6564496420697320776974686472617765640000000000606082015260800190565b6020808252601e908201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601a908201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604082015260600190565b602080825260409082018190527f4d756c7469526577617264546f6b656e506f6f6c3a20696e636f727265637420908201527f736574746572206f6620746869732072657761726420746f6b656e20706f6f6c606082015260800190565b60208082526028908201527f4d756c7469526577617264546f6b656e506f6f6c3a20696e76616c696420737460408201527f6172742074696d65000000000000000000000000000000000000000000000000606082015260800190565b60208082526029908201527f4d756c7469526577617264546f6b656e506f6f6c3a20696e646578206f75742060408201527f6f6620626f756e64730000000000000000000000000000000000000000000000606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f60408201527f7700000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526036908201527f4d756c7469526577617264546f6b656e506f6f6c3a2063616e2774206164642060408201527f444f4720746f2062652072657761726420746f6b656e00000000000000000000606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526033908201527f4d756c7469526577617264546f6b656e506f6f6c3a2044656c5365747465722060408201527f697320746865207a65726f206164647265737300000000000000000000000000606082015260800190565b60208082526038908201527f4d756c7469526577617264546f6b656e506f6f6c3a20696e636f72726563742060408201527f62616c616e6365206166746572206465706f736974696e670000000000000000606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526024908201527f4d756c7469526577617264546f6b656e506f6f6c3a204e6f742074686520736560408201527f7474657200000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4d756c7469526577617264546f6b656e506f6f6c3a206578697374656420726560408201527f7761726420746f6b656e00000000000000000000000000000000000000000000606082015260800190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b90815260200190565b918252602082015260400190565b60005b83811015613b0e578181015183820152602001613af6565b83811115611ff95750506000910152565b6001600160a01b0381168114613b3457600080fd5b50565b8015158114613b3457600080fdfea26469706673582212209fe7f4bb7bc54ac6e843fbad8662695d9bb858a160e7b252dd56b9cdb4724e6d64736f6c634300060c00330000000000000000000000002ce97416ca28498e6f3dd7306d00ea5784ded071

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

0000000000000000000000002ce97416ca28498e6f3dd7306d00ea5784ded071

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000002ce97416ca28498e6f3dd7306d00ea5784ded071


Deployed ByteCode Sourcemap

35214:18659:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37997:46;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37488:35;;;:::i;:::-;;;;;;;:::i;50663:94::-;;;;;;:::i;:::-;;:::i;:::-;;40119:1168;;;;;;:::i;:::-;;:::i;50437:101::-;;;;;;:::i;:::-;;:::i;51513:1319::-;;;;;;:::i;:::-;;:::i;37079:26::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;37367:30::-;;;:::i;49904:96::-;;;;;;:::i;:::-;;:::i;50220:92::-;;;;;;:::i;:::-;;:::i;50815:258::-;;;;;;:::i;:::-;;:::i;48176:237::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;38050:52::-;;;;;;:::i;:::-;;:::i;50550:101::-;;;;;;:::i;:::-;;:::i;51085:205::-;;;;;;:::i;:::-;;:::i;37032:40::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;:::i;39586:521::-;;;;;;:::i;:::-;;:::i;49460:432::-;;;;;;:::i;:::-;;:::i;37944:46::-;;;;;;:::i;:::-;;:::i;39275:193::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;37846:44::-;;;;;;:::i;:::-;;:::i;38156:25::-;;;:::i;47934:234::-;;;;;;:::i;:::-;;:::i;42629:278::-;;;:::i;38943:119::-;;;:::i;:::-;;;;;;;:::i;39480:94::-;;;:::i;37654:34::-;;;:::i;37404:35::-;;;:::i;34534:148::-;;;:::i;50324:101::-;;;;;;:::i;:::-;;:::i;48425:1023::-;;;;;;:::i;:::-;;:::i;37530:35::-;;;:::i;33883:87::-;;;:::i;39142:121::-;;;;;;:::i;:::-;;:::i;37175:66::-;;;;;;:::i;:::-;;:::i;37613:34::-;;;:::i;41299:1318::-;;;;;;:::i;:::-;;:::i;37572:34::-;;;:::i;44533:2689::-;;;;;;:::i;:::-;;:::i;38462:112::-;;;:::i;37446:35::-;;;:::i;51302:203::-;;;;;;:::i;:::-;;:::i;38582:122::-;;;;;;:::i;:::-;;:::i;52919:951::-;;;;;;:::i;:::-;;:::i;37758:29::-;;;:::i;38712:219::-;;;;;;:::i;:::-;;:::i;50012:92::-;;;;;;:::i;:::-;;:::i;42919:1602::-;;;;;;:::i;:::-;;:::i;34837:244::-;;;;;;:::i;:::-;;:::i;50116:92::-;;;;;;:::i;:::-;;:::i;37997:46::-;;;;;;;;;;;;-1:-1:-1;;;;;37997:46:0;;:::o;37488:35::-;;;;:::o;50663:94::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;;;;;;;;;50731:10:::1;:18:::0;50663:94::o;40119:1168::-;40206:7;40226:21;40250:8;40259:4;40250:14;;;;;;;;;;;;;;;;40299;;;:8;:14;;;;;;-1:-1:-1;;;;;40299:21:0;;;;;;;;;;40363:15;:21;;40250:14;;;;;;;;-1:-1:-1;40299:21:0;40250:14;40379:4;;40363:21;;;;;;;;;;;;;;40423:28;;;:22;;;:28;;;;;;;40488:20;;;:26;;;;;;;40553:16;;:41;;;;;40363:21;;;;;;;;-1:-1:-1;40423:28:0;;40488:26;;40363:21;;-1:-1:-1;;;;;40553:16:0;;:26;;:41;;40588:4;;40553:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40525:69;;40624:15;40609:12;:30;:56;;;;-1:-1:-1;40643:22:0;;;40609:56;40605:568;;;40682:18;40703:44;40717:15;40734:12;40703:13;:44::i;:::-;40682:65;;40762:19;40784:78;40846:15;;40784:57;40825:4;:15;;;40784:36;40799:5;:20;;;40784:10;:14;;:36;;;;:::i;:::-;:40;;:57::i;:::-;:61;;:78::i;:::-;40762:100;;40895:5;:20;;;40881:11;:34;40877:170;;;-1:-1:-1;41011:20:0;;;;40877:170;41081:80;41103:57;41142:17;41103:34;41119:5;:17;;;41103:11;:15;;:34;;;;:::i;:57::-;41081:17;;:21;:80::i;:::-;41061:100;;40605:568;;;41257:21;;;;:15;;;:21;;;;;;41234:17;;;;41190:16;;:89;;41257:21;41190:62;;:39;;41211:17;41190:20;:39::i;:62::-;:66;;:89::i;:::-;41183:96;;;;;;;;40119:1168;;;;;;:::o;50437:101::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50508:14:::1;:22:::0;50437:101::o;51513:1319::-;38231:20;38240:10;38231:8;:20::i;:::-;38223:69;;;;-1:-1:-1;;;38223:69:0;;;;;;;:::i;:::-;51716:15:::1;51703:10;:28;51695:81;;;;-1:-1:-1::0;;;51695:81:0::1;;;;;;;:::i;:::-;51819:8;51828:1;51819:11;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:23:::0;-1:-1:-1;;;;;51795:48:0;;::::1;51819:23:::0;::::1;51795:48;;51787:115;;;;-1:-1:-1::0;;;51787:115:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;51922:34:0;::::1;;::::0;;;:20:::1;:34;::::0;;;;;::::1;;51921:35;51913:90;;;;-1:-1:-1::0;;;51913:90:0::1;;;;;;;:::i;:::-;52014:17;:15;:17::i;:::-;52042:15;52063:495;;;;;;;;52114:12;-1:-1:-1::0;;;;;52063:495:0::1;;;;;52184:7;52063:495;;;;52152:9;52063:495;;;;52231:9;52226:2;:14;52219:2;:22;52063:495;;;;52316:10;;52297:15;52284:10;:28;52283:43;;;;;;52268:12;:58;52063:495;;;;52399:10;;52380:15;52367:10;:28;52366:43;;;;;;52351:12;:58;52063:495:::0;;52440:1:::1;52063:495;::::0;;::::1;::::0;;;;;;;;;;;;;;;52524:15:::1;:22:::0;;52063:495;;;;;;;;52042:517;;;;::::1;::::0;;;;;;;;;;;::::1;::::0;;::::1;;::::0;;;::::1;-1:-1:-1::0;;;;;52042:517:0;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;;;;;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;52042:517:0::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;52623:1:::1;52598:22:::0;;-1:-1:-1;;;;;52570:25:0;::::1;-1:-1:-1::0;52570:25:0;;;:11:::1;:25;::::0;;;;;;-1:-1:-1;;52598:26:0;;;52570:54;;52647:22;;:26;;52635:39;;:11:::1;:39:::0;;;;;:52;;;::::1;52677:10;52635:52;::::0;;52698:34;;;:20:::1;:34:::0;;;;;:41;;-1:-1:-1;;52698:41:0::1;::::0;::::1;::::0;;52797:22;;52755:69;;52570:25;;52755:69:::1;::::0;::::1;::::0;52786:9;;52797:26;;52755:69:::1;:::i;:::-;;;;;;;;51513:1319:::0;;;;:::o;37079:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37079:26:0;;;;-1:-1:-1;37079:26:0;;;:::o;37367:30::-;;;;:::o;49904:96::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;49973:11:::1;:19:::0;49904:96::o;50220:92::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50287:10:::1;:17:::0;50220:92::o;50815:258::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50892:123:::1;50911:15;50927:3;50911:20;;;;;;;;;;;;;;;;;;:32;;;;;;;;;;-1:-1:-1::0;;;;;50911:32:0::1;50945:10;50957:15;50973:3;50957:20;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:32:::0;:57:::1;::::0;;;;-1:-1:-1;;;;;50957:32:0;;::::1;::::0;:42:::1;::::0;:57:::1;::::0;51008:4:::1;::::0;50957:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50892:18;:123::i;:::-;51064:1;51026:15;51042:3;51026:20;;;;;;;;;;;;;;;;;;:35;;:39;;;;50815:258:::0;:::o;48176:237::-;48241:4;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;48266:24:0;::::1;48258:88;;;;-1:-1:-1::0;;;48258:88:0::1;;;;;;;:::i;:::-;48364:41;48385:7;48394:10;48364:20;:41::i;:::-;48357:48:::0;48176:237;-1:-1:-1;;48176:237:0:o;38050:52::-;;;;;;;;;;;;;;;:::o;50550:101::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50621:14:::1;:22:::0;50550:101::o;51085:205::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;51181:35:::1;51219:15;51235:3;51219:20;;;;;;;;;::::0;;;::::1;::::0;;;51250::::1;51219;::::0;;::::1;;51250;:32:::0;;;;-1:-1:-1;;51085:205:0:o;37032:40::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37032:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37032:40:0;;;;-1:-1:-1;37032:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;39586:521::-;39664:7;39684:20;;:::i;:::-;39707:14;;;;:8;:14;;;;;;;;-1:-1:-1;;;;;39707:21:0;;;;;;;;;39684:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39707:21;;39684:44;;;;;;;;39707:14;39684:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;39684:44:0;;-1:-1:-1;;39772:15:0;;;;39684:44;;-1:-1:-1;39798:20:0;;39833:237;39853:10;:17;39849:1;:21;39833:237;;;39923:15;39896:10;39907:1;39896:13;;;;;;;;;;;;;;:24;;;:42;:73;;;;;39943:10;39954:1;39943:13;;;;;;;;;;;;;;:26;;;39942:27;39896:73;39892:167;;;40005:38;40022:10;40033:1;40022:13;;;;;;;;;;;;;;:20;;;40005:12;:16;;:38;;;;:::i;:::-;39990:53;;39892:167;39872:3;;39833:237;;;-1:-1:-1;40087:12:0;39586:521;-1:-1:-1;;;;;39586:521:0:o;49460:432::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;49604:11:::1;49600:61;;;49632:17;:15;:17::i;:::-;49689:63;49740:11;49689:46;49709:8;49718:4;49709:14;;;;;;;;;;;;;;;;;;:25;;;49689:15;;:19;;:46;;;;:::i;:::-;:50:::0;::::1;:63::i;:::-;49671:15;:81;;;;49791:11;49763:8;49772:4;49763:14;;;;;;;;;;;;;;;;;;:25;;:39;;;;49843:8;49852:4;49843:14;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;:26:::0;49818:66:::1;::::0;-1:-1:-1;;;;;49843:26:0;;::::1;::::0;49818:66:::1;::::0;::::1;::::0;49829:4;;49872:11;;49818:66:::1;:::i;:::-;;;;;;;;49460:432:::0;;;:::o;37944:46::-;;;;;;;;;;;;;:::o;39275:193::-;39351:19;39383:20;;:::i;:::-;39406:14;;;;:8;:14;;;;;;;;-1:-1:-1;;;;;39406:21:0;;;;;;;;;39383:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39406:21;;39383:44;;;;;;;;39406:14;39383:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;39383:44:0;;-1:-1:-1;;39445:15:0;;;;39275:193;-1:-1:-1;;;;39275:193:0:o;37846:44::-;;;;;;;;;;;;;:::o;38156:25::-;;;-1:-1:-1;;;;;38156:25:0;;:::o;47934:234::-;47999:4;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;48024:24:0;::::1;48016:88;;;;-1:-1:-1::0;;;48016:88:0::1;;;;;;;:::i;:::-;48122:38;48140:7;48149:10;48122:17;:38::i;42629:278::-:0;42691:8;:15;42674:14;42717:183;42745:6;42739:3;:12;42717:183;;;42780:11;42775:114;42803:15;:22;42797:28;;42775:114;;;42853:20;42864:3;42869;42853:10;:20::i;:::-;42827:5;;42775:114;;;-1:-1:-1;42753:5:0;;42717:183;;;;42629:278;:::o;38943:119::-;38995:24;39039:15;39032:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39032:22:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39032:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38943:119;:::o;39480:94::-;39554:12;39480:94;:::o;37654:34::-;;;;:::o;37404:35::-;;;;:::o;34534:148::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;34641:1:::1;34625:6:::0;;34604:40:::1;::::0;-1:-1:-1;;;;;34625:6:0;;::::1;::::0;34604:40:::1;::::0;34641:1;;34604:40:::1;34672:1;34655:19:::0;;;::::1;::::0;;34534:148::o;50324:101::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50395:14:::1;:22:::0;50324:101::o;48425:1023::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;48572:11:::1;48568:61;;;48600:17;:15;:17::i;:::-;48639:25;48667:10:::0;;;:7:::1;:10;::::0;;;48688:341:::1;48713:15;:22:::0;48707:28;::::1;48688:341;;;48759:18;48780:15;48796:3;48780:20;;;;;;;;;;;;;;;;;;:31;;;48759:52;;48826:23;48867:10;48852:12;:25;:53;;48895:10;48852:53;;;48880:12;48852:53;48920:29;::::0;;;:24:::1;::::0;::::1;:29;::::0;;;;;;;:47;;;;48982:26:::1;::::0;::::1;:31:::0;;;;;:35;-1:-1:-1;;48737:5:0::1;;48688:341;;;-1:-1:-1::0;49039:35:0;;-1:-1:-1;;;;;49039:35:0;;::::1;::::0;;;::::1;;::::0;;;49085:19;;::::1;:33:::0;;;49039:20:::1;49129;::::0;::::1;:24:::0;;;49164:27:::1;::::0;;::::1;:31:::0;;;49206:8:::1;:23:::0;;;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;49258:15;:32:::1;::::0;49107:11;49258:19:::1;:32::i;:::-;49240:15;:50:::0;49336:8:::1;:15:::0;:22:::1;::::0;49356:1:::1;49336:19;:22::i;:::-;-1:-1:-1::0;;;;;49301:32:0;::::1;;::::0;;;:9:::1;:32;::::0;;;;;;:57;;;;49384:8:::1;:15:::0;49374:66;;49301:32;;49374:66:::1;::::0;::::1;::::0;-1:-1:-1;;49384:19:0;;49428:11;;49374:66:::1;:::i;37530:35::-:0;;;;:::o;33883:87::-;33929:7;33956:6;-1:-1:-1;;;;;33956:6:0;33883:87;:::o;39142:121::-;39214:7;39241:14;:3;39249:5;39241:7;:14::i;37175:66::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;37613:34::-;;;;:::o;41299:1318::-;41365:21;41389:8;41398:4;41389:14;;;;;;;;;;;;;;;;;;41365:38;;41414:29;41446:15;41462:4;41446:21;;;;;;;;;;;;;;;;;;41414:53;;41478:23;41504:4;:20;;:26;41525:4;41504:26;;;;;;;;;;;;41478:52;;41571:15;41555:12;:31;41551:70;;41603:7;;;;;41551:70;41669:16;;:41;;;;;41641:25;;-1:-1:-1;;;;;41669:16:0;;:26;;:41;;41704:4;;41669:41;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;41641:69;-1:-1:-1;41725:22:0;;;:51;;-1:-1:-1;41751:20:0;;;;:25;41725:51;41721:146;;;-1:-1:-1;;;41793:26:0;;;;:20;;;;:26;;;;;41822:12;41793:41;;41849:7;;41721:146;41879:18;41900:44;41914:15;41931:12;41900:13;:44::i;:::-;41879:65;;41955:19;41977:78;42039:15;;41977:57;42018:4;:15;;;41977:36;41992:5;:20;;;41977:10;:14;;:36;;;;:::i;:78::-;41955:100;;42084:5;:20;;;42070:11;:34;42066:290;;;-1:-1:-1;42192:20:0;;;;;42250:1;42227:24;;;42066:290;;;42307:20;;;;:37;;42332:11;42307:24;:37::i;:::-;42284:20;;;:60;42066:290;42388:19;;;;:36;;42412:11;42388:23;:36::i;:::-;42366:19;;;:58;42515:17;;;;42466:91;;42499:57;;42538:17;;42499:34;;:11;;:15;:34::i;:57::-;42466:28;;;;:22;;;:28;;;;;;;:32;:91::i;:::-;42435:28;;;;:22;;;:28;;;;;;;;:122;;;;42568:20;;;;:26;;;;;;42597:12;42568:41;;-1:-1:-1;;;;;41299:1318:0;;:::o;37572:34::-;;;;:::o;44533:2689::-;44619:21;44643:8;44652:4;44643:14;;;;;;;;;;;;;;;;44729;;;:8;:14;;;;;;44684:10;44729:21;;;;;;;44643:14;;;;;;-1:-1:-1;44684:10:0;44761:463;44789:15;:22;44783:28;;44761:463;;;44835:21;44846:4;44852:3;44835:10;:21::i;:::-;44875:16;;:20;44871:342;;44916:15;45026:20;;;:15;;;;:20;;;;;;44988;;44934:113;;:87;;45042:3;;44988:20;;;;;;;;;;;;;;:32;:20;;;;;:32;;;44955:27;;;:22;;;:27;;;;;;;44934:16;;:49;;:20;:49::i;:113::-;44916:131;-1:-1:-1;45069:11:0;;45066:132;;45105:73;45124:15;45140:3;45124:20;;;;;;;;;;;;;;;;;;;;;:32;-1:-1:-1;;;;;45124:32:0;45158:10;45170:7;45105:18;:73::i;:::-;44871:342;;44813:5;;44761:463;;;-1:-1:-1;45234:15:0;45268:11;;45264:1674;;45305:4;:15;;45321:9;45305:26;;;;;;;;;;;;;;;;:39;:26;;;;;:39;;;;45304:40;45296:112;;;;-1:-1:-1;;;45296:112:0;;;;;;;:::i;:::-;45468:7;45431:4;:15;;45447:9;45431:26;;;;;;;;;;;;;;;;;;:33;;;:44;45423:105;;;;-1:-1:-1;;;45423:105:0;;;;;;;:::i;:::-;45543:18;45564:4;:15;;45580:9;45564:26;;;;;;;;;;;;;;;;;;:37;;;45543:58;;45616:18;45637:4;:15;;45653:9;45637:26;;;;;;;;;;;;;;;;;;:37;;;45616:58;;45706:15;45693:10;:28;45689:788;;;45742:16;;:59;;-1:-1:-1;;;;;45742:16:0;45780:10;45793:7;45742:29;:59::i;:::-;45689:788;;;45924:10;;45861:15;:28;;;;45912:22;;45908:335;;45969:36;46001:3;45969:27;45981:14;;45969:7;:11;;:27;;;;:::i;:36::-;45959:46;;45908:335;;;46047:10;;46035:8;:22;46031:212;;46092:36;46124:3;46092:27;46104:14;;46092:7;:11;;:27;;;;:::i;46031:212::-;46187:36;46219:3;46187:27;46199:14;;46187:7;:11;;:27;;;;:::i;:36::-;46177:46;;46031:212;46261:72;46299:10;46312:20;:7;46324;46312:11;:20::i;:::-;46261:16;;-1:-1:-1;;;;;46261:16:0;;:72;:29;:72::i;:::-;46441:10;;46411:16;;:50;;-1:-1:-1;;;;;46411:16:0;;;;46441:10;46453:7;46411:29;:50::i;:::-;45689:788;;46531:15;46491:4;:15;;46507:9;46491:26;;;;;;;;;;;;;;;;:37;:26;;;;;:37;:55;46580:16;;:29;;46601:7;46580:20;:29::i;:::-;46561:48;;46644:16;;;;:29;;46665:7;46644:20;:29::i;:::-;46625:16;;;:48;46688:51;46711:4;46717:10;46729:9;46688:22;:51::i;:::-;46758:16;;46754:173;;46831:5;46800:21;;;:15;:21;;;;;;;;-1:-1:-1;;;;;46800:28:0;;;;;;;;;:36;;-1:-1:-1;;46800:36:0;;;46881:23;;;;:30;;46800:36;46881:27;:30::i;:::-;46855:23;;;:56;46754:173;45264:1674;;;46953:11;46948:196;46976:15;:22;46970:28;;46948:196;;;47045:87;47099:15;47115:3;47099:20;;;;;;;;;;;;;;;;:32;:20;;;;;:32;;;47066:27;;;:22;;;:27;;;;;;;47045:16;;:49;;:20;:49::i;:87::-;47022:20;;;;:15;;;;:20;;;;;;:110;;;;47000:5;46948:196;;;;47195:9;47180:4;47168:10;-1:-1:-1;;;;;47159:55:0;;47186:7;47206;47159:55;;;;;;;:::i;:::-;;;;;;;;44533:2689;;;;;;;:::o;38462:112::-;38510:7;38537:29;38558:7;38537:20;:29::i;:::-;38530:36;;38462:112;:::o;37446:35::-;;;;:::o;51302:203::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;51400:35:::1;51438:15;51454:3;51438:20;;;;;;;;;;;;;;;;;;51400:58;;51490:7;51469:11;:18;;:28;;;;;;;;;;;;:::i;:::-;;34174:1;51302:203:::0;;:::o;38582:122::-;38635:4;38659:37;38682:7;38691:4;38659:22;:37::i;52919:951::-;38231:20;38240:10;38231:8;:20::i;:::-;38223:69;;;;-1:-1:-1;;;38223:69:0;;;;;;;:::i;:::-;53015:16:::1;::::0;;;:11:::1;:16;::::0;;;;;-1:-1:-1;;;;;53015:16:0::1;53035:10;53015:30;53007:107;;;;-1:-1:-1::0;;;53007:107:0::1;;;;;;;:::i;:::-;53125:17;:15;:17::i;:::-;53153:29;53185:15;53201:3;53185:20;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;;::::1;;53234:17:::0;;:42:::1;::::0;;;;53185:20;;-1:-1:-1;;;;;;53234:17:0::1;::::0;:27:::1;::::0;:42:::1;::::0;53270:4:::1;::::0;53234:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53314:14;::::0;::::1;::::0;53339:17;;53216:60;;-1:-1:-1;53308:2:0::1;:20;::::0;53339:91:::1;::::0;-1:-1:-1;;;;;53339:17:0::1;53382:10;53403:4;53410:19:::0;;::::1;53339:34;:91::i;:::-;53459:17:::0;;:42:::1;::::0;;;;53441:15:::1;::::0;-1:-1:-1;;;;;53459:17:0::1;::::0;:27:::1;::::0;:42:::1;::::0;53495:4:::1;::::0;53459:42:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53441:60;;53552:10;53543:6;:19;53531:7;53521;:17;53520:42;53512:111;;;;-1:-1:-1::0;;;53512:111:0::1;;;;;;;:::i;:::-;53657:20;::::0;::::1;::::0;:45:::1;::::0;53682:19;;::::1;53657:24;:45::i;:::-;53634:20;::::0;::::1;:68:::0;53777:10:::1;::::0;53761:11:::1;::::0;53736:53:::1;::::0;53761:27:::1;::::0;:11;:15:::1;:27::i;:::-;53736:20;::::0;::::1;::::0;;:24:::1;:53::i;:::-;53713:5;:20;;:76;;;;53817:45;53834:27;53850:10;;53834:11;;:15;;:27;;;;:::i;:::-;53817:12;::::0;:16:::1;:45::i;:::-;53800:5;:14;;:62;;;;38303:1;;;;52919:951:::0;;:::o;37758:29::-;;;;:::o;38712:219::-;38768:7;38825:1;38805:17;:15;:17::i;:::-;:21;38795:6;:31;;38787:85;;;;-1:-1:-1;;;38787:85:0;;;;;;;:::i;:::-;38890:33;38907:7;38916:6;38890:16;:33::i;50012:92::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50079:10:::1;:17:::0;50012:92::o;42919:1602::-;42985:21;43009:8;43018:4;43009:14;;;;;;;;;;;;;;;;43095;;;:8;:14;;;;;;43050:10;43095:21;;;;;;;43009:14;;;;;;-1:-1:-1;43050:10:0;43127:463;43155:15;:22;43149:28;;43127:463;;;43201:21;43212:4;43218:3;43201:10;:21::i;:::-;43241:16;;:20;43237:342;;43282:15;43392:20;;;:15;;;;:20;;;;;;43354;;43300:113;;:87;;43408:3;;43354:20;;;;;43300:113;43282:131;-1:-1:-1;43435:11:0;;43432:132;;43471:73;43490:15;43506:3;43490:20;;;;;;;43471:73;43237:342;;43179:5;;43127:463;;;-1:-1:-1;43603:11:0;;43600:658;;43631:16;;:78;;-1:-1:-1;;;;;43631:16:0;43673:10;43694:4;43701:7;43631:33;:78::i;:::-;43743:16;;:29;;43764:7;43743:20;:29::i;:::-;43724:48;;43807:16;;;;:29;;43828:7;43807:20;:29::i;:::-;43788:16;;;:48;43872:179;;;;;;;;;;;43927:15;43872:179;;;;;;43981:10;;43851:15;;;;43872:179;;;43961:31;;:19;:31::i;:::-;43872:179;;44011:1;43872:179;;;;;;;;;;;;;;43851:201;;43872:179;43851:201;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43851:201:0;;;;;;;;;;44072:21;;;;;;;;;-1:-1:-1;;;;;44072:28:0;;;;;;;;;;43851:201;44072:28;44067:180;;44121:21;;;;:15;:21;;;;;;;;-1:-1:-1;;;;;44121:28:0;;;;;;;;;:35;;-1:-1:-1;;44121:35:0;44152:4;44121:35;;;;;;44201:23;;;;:30;;:27;:30::i;:::-;44175:23;;;:56;44067:180;44273:11;44268:196;44296:15;:22;44290:28;;44268:196;;;44365:87;44419:15;44435:3;44419:20;;;;;;;;;;;;;;;;:32;:20;;;;;:32;;;44386:27;;;:22;;;:27;;;;;;;44365:16;;:49;;:20;:49::i;:87::-;44342:20;;;;:15;;;;:20;;;;;;:110;;;;44320:5;44268:196;;;;44499:4;44487:10;-1:-1:-1;;;;;44479:34:0;;44505:7;44479:34;;;;;;:::i;:::-;;;;;;;;42919:1602;;;;;:::o;34837:244::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;34926:22:0;::::1;34918:73;;;;-1:-1:-1::0;;;34918:73:0::1;;;;;;;:::i;:::-;35028:6;::::0;;35007:38:::1;::::0;-1:-1:-1;;;;;35007:38:0;;::::1;::::0;35028:6;::::1;::::0;35007:38:::1;::::0;::::1;35056:6;:17:::0;;;::::1;-1:-1:-1::0;;;;;35056:17:0;;;::::1;::::0;;;::::1;::::0;;34837:244::o;50116:92::-;34114:12;:10;:12::i;:::-;-1:-1:-1;;;;;34103:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;34103:23:0;;34095:68;;;;-1:-1:-1;;;34095:68:0;;;;;;;:::i;:::-;50183:10:::1;:17:::0;50116:92::o;6689:152::-;6759:4;6783:50;6788:3;-1:-1:-1;;;;;6808:23:0;;6783:4;:50::i;32420:106::-;32508:10;32420:106;:::o;21452:220::-;21510:7;21534:6;21530:20;;-1:-1:-1;21549:1:0;21542:8;;21530:20;21573:5;;;21577:1;21573;:5;:1;21597:5;;;;;:10;21589:56;;;;-1:-1:-1;;;21589:56:0;;;;;;;:::i;22150:153::-;22208:7;22240:1;22236;:5;22228:44;;;;-1:-1:-1;;;22228:44:0;;;;;;;:::i;:::-;22294:1;22290;:5;;;;;;;22150:153;-1:-1:-1;;;22150:153:0:o;20573:179::-;20631:7;20663:5;;;20687:6;;;;20679:46;;;;-1:-1:-1;;;20679:46:0;;;;;;;:::i;21035:158::-;21093:7;21126:1;21121;:6;;21113:49;;;;-1:-1:-1;;;21113:49:0;;;;;;;:::i;:::-;-1:-1:-1;21180:5:0;;;21035:158::o;47283:304::-;47395:31;;;;;47376:16;;-1:-1:-1;;;;;47395:16:0;;;;;:31;;47420:4;;47395:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47376:50;;47451:8;47441:7;:18;47437:143;;;47476:30;;;;;-1:-1:-1;;;;;47476:15:0;;;;;:30;;47492:3;;47497:8;;47476:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47437:143;;;47539:29;;;;;-1:-1:-1;;;;;47539:15:0;;;;;:29;;47555:3;;47560:7;;47539:29;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;47283:304;;;;:::o;7017:158::-;7090:4;7114:53;7122:3;-1:-1:-1;;;;;7142:23:0;;7114:7;:53::i;28713:177::-;28796:86;28816:5;28846:23;;;28871:2;28875:5;28823:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28796:19;:86::i;:::-;28713:177;;;:::o;47599:210::-;47699:21;47723:14;;;:8;:14;;;;;;;;-1:-1:-1;;;;;47723:21:0;;;;;;;;;47755:15;;;:26;;47797:4;;47755:15;47771:9;;47755:26;;;;;;;;;;;;;;;;;;;:39;;:46;;-1:-1:-1;;47755:46:0;;;;;;;;;;-1:-1:-1;;;;47599:210:0:o;7514:117::-;7577:7;7604:19;7612:3;7604:7;:19::i;7261:167::-;7341:4;7365:55;7375:3;-1:-1:-1;;;;;7395:23:0;;7365:9;:55::i;28898:205::-;28999:96;29019:5;29049:27;;;29078:4;29084:2;29088:5;29026:68;;;;;;;;;;:::i;7975:158::-;8049:7;8100:22;8104:3;8116:5;8100:3;:22::i;1753:414::-;1816:4;1838:21;1848:3;1853:5;1838:9;:21::i;:::-;1833:327;;-1:-1:-1;1876:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;2059:18;;2037:19;;;:12;;;:19;;;;;;:40;;;;2092:11;;1833:327;-1:-1:-1;2143:5:0;2136:12;;2343:1544;2409:4;2548:19;;;:12;;;:19;;;;;;2584:15;;2580:1300;;3019:18;;-1:-1:-1;;2970:14:0;;;;3019:22;;;;2946:21;;3019:3;;:22;;3306;;;;;;;;;;;;;;3286:42;;3452:9;3423:3;:11;;3435:13;3423:26;;;;;;;;;;;;;;;;;;;:38;;;;3529:23;;;3571:1;3529:12;;;:23;;;;;;3555:17;;;3529:43;;3681:17;;3529:3;;3681:17;;;;;;;;;;;;;;;;;;;;;;3776:3;:12;;:19;3789:5;3776:19;;;;;;;;;;;3769:26;;;3819:4;3812:11;;;;;;;;2580:1300;3863:5;3856:12;;;;;31018:761;31442:23;31468:69;31496:4;31468:69;;;;;;;;;;;;;;;;;31476:5;-1:-1:-1;;;;;31468:27:0;;;:69;;;;;:::i;:::-;31552:17;;31442:95;;-1:-1:-1;31552:21:0;31548:224;;31694:10;31683:30;;;;;;;;;;;;:::i;:::-;31675:85;;;;-1:-1:-1;;;31675:85:0;;;;;;;:::i;4188:109::-;4271:18;;4188:109::o;3973:129::-;4046:4;4070:19;;;:12;;;;;:19;;;;;;:24;;;3973:129::o;4641:204::-;4736:18;;4708:7;;4736:26;-1:-1:-1;4728:73:0;;;;-1:-1:-1;;;4728:73:0;;;;;;;:::i;:::-;4819:3;:11;;4831:5;4819:18;;;;;;;;;;;;;;;;4812:25;;4641:204;;;;:::o;13437:195::-;13540:12;13572:52;13594:6;13602:4;13608:1;13611:12;13572:21;:52::i;:::-;13565:59;13437:195;-1:-1:-1;;;;13437:195:0:o;14489:530::-;14616:12;14674:5;14649:21;:30;;14641:81;;;;-1:-1:-1;;;14641:81:0;;;;;;;:::i;:::-;14741:18;14752:6;14741:10;:18::i;:::-;14733:60;;;;-1:-1:-1;;;14733:60:0;;;;;;;:::i;:::-;14867:12;14881:23;14908:6;-1:-1:-1;;;;;14908:11:0;14928:5;14936:4;14908:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14866:75;;;;14959:52;14977:7;14986:10;14998:12;14959:17;:52::i;:::-;14952:59;14489:530;-1:-1:-1;;;;;;;14489:530:0:o;10519:422::-;10886:20;10925:8;;;10519:422::o;17029:742::-;17144:12;17173:7;17169:595;;;-1:-1:-1;17204:10:0;17197:17;;17169:595;17318:17;;:21;17314:439;;17581:10;17575:17;17642:15;17629:10;17625:2;17621:19;17614:44;17529:148;17724:12;17717:20;;-1:-1:-1;;;17717:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;576:442;;678:3;671:4;663:6;659:17;655:27;645:2;;-1:-1;;686:12;645:2;733:6;720:20;36687:18;;36679:6;36676:30;36673:2;;;-1:-1;;36709:12;36673:2;36342;36336:9;36850:4;36782:9;671:4;36767:6;36763:17;36759:33;36372:6;36368:17;;36479:6;36467:10;36464:22;36687:18;36431:10;36428:34;36425:62;36422:2;;;-1:-1;;36490:12;36422:2;36342;36509:22;826:21;;;746:74;-1:-1;746:74;926:16;;;36850:4;926:16;923:25;-1:-1;920:2;;;961:1;;951:12;920:2;39948:6;36850:4;868:6;864:17;36850:4;902:5;898:16;39925:30;40004:1;36850:4;39995:6;902:5;39986:16;;39979:27;;;;638:380;;;;:::o;1304:241::-;;1408:2;1396:9;1387:7;1383:23;1379:32;1376:2;;;-1:-1;;1414:12;1376:2;85:6;72:20;97:33;124:5;97:33;:::i;1552:257::-;;1664:2;1652:9;1643:7;1639:23;1635:32;1632:2;;;-1:-1;;1670:12;1632:2;354:6;348:13;366:30;390:5;366:30;:::i;1816:241::-;;1920:2;1908:9;1899:7;1895:23;1891:32;1888:2;;;-1:-1;;1926:12;1888:2;-1:-1;1093:20;;1882:175;-1:-1;1882:175::o;2064:263::-;;2179:2;2167:9;2158:7;2154:23;2150:32;2147:2;;;-1:-1;;2185:12;2147:2;-1:-1;1241:13;;2141:186;-1:-1;2141:186::o;2334:366::-;;;2455:2;2443:9;2434:7;2430:23;2426:32;2423:2;;;-1:-1;;2461:12;2423:2;1106:6;1093:20;2513:63;;2613:2;2656:9;2652:22;72:20;97:33;124:5;97:33;:::i;:::-;2621:63;;;;2417:283;;;;;:::o;2707:723::-;;;;;2872:3;2860:9;2851:7;2847:23;2843:33;2840:2;;;-1:-1;;2879:12;2840:2;1106:6;1093:20;2931:63;;3031:2;3074:9;3070:22;72:20;97:33;124:5;97:33;:::i;:::-;3039:63;-1:-1;3139:2;3178:22;;1093:20;;-1:-1;3275:2;3260:18;;3247:32;3299:18;3288:30;;3285:2;;;-1:-1;;3321:12;3285:2;3351:63;3406:7;3397:6;3386:9;3382:22;3351:63;:::i;:::-;3341:73;;;2834:596;;;;;;;:::o;3437:515::-;;;;3587:2;3575:9;3566:7;3562:23;3558:32;3555:2;;;-1:-1;;3593:12;3555:2;1106:6;1093:20;3645:63;;3745:2;3803:9;3799:22;490:20;515:48;557:5;515:48;:::i;:::-;3753:78;-1:-1;3868:2;3904:22;;206:20;231:30;206:20;231:30;:::i;:::-;3876:60;;;;3549:403;;;;;:::o;3959:472::-;;;4090:2;4078:9;4069:7;4065:23;4061:32;4058:2;;;-1:-1;;4096:12;4058:2;1106:6;1093:20;4148:63;;4276:2;4265:9;4261:18;4248:32;4300:18;4292:6;4289:30;4286:2;;;-1:-1;;4322:12;4286:2;4352:63;4407:7;4398:6;4387:9;4383:22;4352:63;:::i;:::-;4342:73;;;4052:379;;;;;:::o;4438:366::-;;;4559:2;4547:9;4538:7;4534:23;4530:32;4527:2;;;-1:-1;;4565:12;4527:2;-1:-1;;1093:20;;;4717:2;4756:22;;;1093:20;;-1:-1;4521:283::o;4811:491::-;;;;4949:2;4937:9;4928:7;4924:23;4920:32;4917:2;;;-1:-1;;4955:12;4917:2;1106:6;1093:20;5007:63;;5107:2;5150:9;5146:22;1093:20;5115:63;;5215:2;5258:9;5254:22;72:20;97:33;124:5;97:33;:::i;5309:485::-;;;;5444:2;5432:9;5423:7;5419:23;5415:32;5412:2;;;-1:-1;;5450:12;5412:2;1106:6;1093:20;5502:63;;5602:2;5645:9;5641:22;1093:20;5610:63;;5710:2;5750:9;5746:22;206:20;231:30;255:5;231:30;:::i;5801:491::-;;;;5939:2;5927:9;5918:7;5914:23;5910:32;5907:2;;;-1:-1;;5945:12;5907:2;-1:-1;;1093:20;;;6097:2;6136:22;;1093:20;;-1:-1;6205:2;6244:22;;;1093:20;;5901:391;-1:-1;5901:391::o;9820:146::-;-1:-1;;;;;39433:54;9896:65;;9890:76::o;10136:327::-;;10271:5;37380:12;38305:6;38300:3;38293:19;10355:52;10400:6;38342:4;38337:3;38333:14;38342:4;10381:5;10377:16;10355:52;:::i;:::-;40385:2;40365:14;40381:7;40361:28;10419:39;;;;38342:4;10419:39;;10218:245;-1:-1;;10218:245::o;22052:271::-;;9617:5;37380:12;9728:52;9773:6;9768:3;9761:4;9754:5;9750:16;9728:52;:::i;:::-;9792:16;;;;;22186:137;-1:-1;;22186:137::o;22330:222::-;-1:-1;;;;;39433:54;;;;6958:37;;22457:2;22442:18;;22428:124::o;22559:444::-;-1:-1;;;;;39433:54;;;6958:37;;39433:54;;;;22906:2;22891:18;;6958:37;22989:2;22974:18;;21883:37;;;;22742:2;22727:18;;22713:290::o;23010:333::-;-1:-1;;;;;39433:54;;;;6958:37;;23329:2;23314:18;;21883:37;23165:2;23150:18;;23136:207::o;23350:482::-;23583:2;23597:47;;;37380:12;;23568:18;;;38293:19;;;23350:482;;23583:2;38333:14;;;;;;37015;;;23350:482;7648:344;7673:6;7670:1;7667:13;7648:344;;;7734:13;;19070:23;;21883:37;;19236:16;;;19230:23;19307:14;;;21883:37;19396:16;;;19390:23;19467:14;;;21883:37;19567:4;19556:16;;;19550:23;19627:14;;;21883:37;19729:4;19718:16;;;19712:23;39232:13;39225:21;19783:14;;;9300:34;6574:4;6565:14;;;;37972;;;;7695:1;7688:9;7648:344;;;-1:-1;23650:172;;23554:278;-1:-1;;;;;;;23554:278::o;23839:502::-;24082:2;24096:47;;;37380:12;;24067:18;;;38293:19;;;23839:502;;24082:2;38333:14;;;;;;8608:17;;;8599:27;;;;37015:14;;;23839:502;8769:429;8794:6;8791:1;8788:13;8769:429;;;8846:20;24071:9;8850:4;8846:20;;8841:3;8834:33;8901:6;8895:13;20080:6;20184:78;20247:14;20161:16;20155:23;20184:78;:::i;:::-;24082:2;20336:5;20332:16;20326:23;20080:6;24082:2;20373:3;20369:14;20362:38;20415:73;20080:6;20075:3;20071:16;20469:12;20415:73;:::i;:::-;20566:16;;;20560:23;20637:14;;;21883:37;20738:4;20727:16;;;20721:23;20798:14;;;21883:37;20898:4;20887:16;;;20881:23;20958:14;;;21883:37;21056:4;21045:16;;;21039:23;21116:14;;;21883:37;21220:4;21209:16;;;21203:23;21280:14;;;21883:37;21384:4;21373:16;;;21367:23;21444:14;;;21883:37;21547:6;21536:18;;;21530:25;21609:16;;;21883:37;21704:6;21693:18;;;21687:25;21766:16;;;;21883:37;;;;-1:-1;;9177:14;;;;37972;;;;8816:1;8809:9;8769:429;;;-1:-1;24149:182;;24053:288;-1:-1;;;;;;;;24053:288::o;24348:210::-;39232:13;;39225:21;9300:34;;24469:2;24454:18;;24440:118::o;24565:1346::-;;24979:3;-1:-1;;;;;39148:5;39433:54;9903:3;9896:65;24979:3;25113:2;25102:9;25098:18;25091:48;25153:78;24979:3;24968:9;24964:19;25217:6;25153:78;:::i;:::-;25310:2;25295:18;;21883:37;;;;-1:-1;;25393:2;25378:18;;21883:37;;;;25476:3;25461:19;;21883:37;;;;25560:3;25545:19;;21883:37;;;;25644:3;25629:19;;21883:37;;;;25728:3;25713:19;;21883:37;25812:3;25797:19;;21883:37;25896:3;25881:19;;;21883:37;25145:86;24950:961;-1:-1;;24950:961::o;25918:586::-;-1:-1;;;;;39433:54;;;;9896:65;;26324:2;26309:18;;21883:37;;;;26407:2;26392:18;;21883:37;26490:2;26475:18;;21883:37;26144:3;26129:19;;26115:389::o;26511:310::-;;26658:2;26679:17;26672:47;26733:78;26658:2;26647:9;26643:18;26797:6;26733:78;:::i;26828:416::-;27028:2;27042:47;;;11049:2;27013:18;;;38293:19;11085:34;38333:14;;;11065:55;11154:4;11140:12;;;11133:26;11178:12;;;26999:245::o;27251:416::-;27451:2;27465:47;;;11429:2;27436:18;;;38293:19;11465:34;38333:14;;;11445:55;11534:21;11520:12;;;11513:43;11575:12;;;27422:245::o;27674:416::-;27874:2;27888:47;;;11826:2;27859:18;;;38293:19;11862:34;38333:14;;;11842:55;11931:18;11917:12;;;11910:40;11969:12;;;27845:245::o;28097:416::-;28297:2;28311:47;;;12220:2;28282:18;;;38293:19;12256:34;38333:14;;;12236:55;12325:8;12311:12;;;12304:30;12353:12;;;28268:245::o;28520:416::-;28720:2;28734:47;;;12604:2;28705:18;;;38293:19;12640:29;38333:14;;;12620:50;12689:12;;;28691:245::o;28943:416::-;29143:2;29157:47;;;12940:2;29128:18;;;38293:19;12976:34;38333:14;;;12956:55;13045:29;13031:12;;;13024:51;13094:12;;;29114:245::o;29366:416::-;29566:2;29580:47;;;13345:2;29551:18;;;38293:19;13381:32;38333:14;;;13361:53;13433:12;;;29537:245::o;29789:416::-;29989:2;30003:47;;;13684:2;29974:18;;;38293:19;13720:34;38333:14;;;13700:55;13789:8;13775:12;;;13768:30;13817:12;;;29960:245::o;30212:416::-;30412:2;30426:47;;;14068:2;30397:18;;;38293:19;14104:28;38333:14;;;14084:49;14152:12;;;30383:245::o;30635:416::-;30835:2;30849:47;;;14403:2;30820:18;;;38293:19;;;14439:34;38333:14;;;14419:55;14508:34;14494:12;;;14487:56;14562:12;;;30806:245::o;31058:416::-;31258:2;31272:47;;;14813:2;31243:18;;;38293:19;14849:34;38333:14;;;14829:55;14918:10;14904:12;;;14897:32;14948:12;;;31229:245::o;31481:416::-;31681:2;31695:47;;;15199:2;31666:18;;;38293:19;15235:34;38333:14;;;15215:55;15304:11;15290:12;;;15283:33;15335:12;;;31652:245::o;31904:416::-;32104:2;32118:47;;;15586:2;32089:18;;;38293:19;15622:34;38333:14;;;15602:55;15691:3;15677:12;;;15670:25;15714:12;;;32075:245::o;32327:416::-;32527:2;32541:47;;;15965:2;32512:18;;;38293:19;16001:34;38333:14;;;15981:55;16070:24;16056:12;;;16049:46;16114:12;;;32498:245::o;32750:416::-;32950:2;32964:47;;;32935:18;;;38293:19;16401:34;38333:14;;;16381:55;16455:12;;;32921:245::o;33173:416::-;33373:2;33387:47;;;16706:2;33358:18;;;38293:19;16742:34;38333:14;;;16722:55;16811:21;16797:12;;;16790:43;16852:12;;;33344:245::o;33596:416::-;33796:2;33810:47;;;17103:2;33781:18;;;38293:19;17139:34;38333:14;;;17119:55;17208:26;17194:12;;;17187:48;17254:12;;;33767:245::o;34019:416::-;34219:2;34233:47;;;17505:2;34204:18;;;38293:19;17541:31;38333:14;;;17521:52;17592:12;;;34190:245::o;34442:416::-;34642:2;34656:47;;;17843:2;34627:18;;;38293:19;17879:34;38333:14;;;17859:55;17948:6;17934:12;;;17927:28;17974:12;;;34613:245::o;34865:416::-;35065:2;35079:47;;;18225:2;35050:18;;;38293:19;18261:34;38333:14;;;18241:55;18330:12;18316;;;18309:34;18362:12;;;35036:245::o;35288:416::-;35488:2;35502:47;;;18613:2;35473:18;;;38293:19;18649:34;38333:14;;;18629:55;18718:12;18704;;;18697:34;18750:12;;;35459:245::o;35711:222::-;21883:37;;;35838:2;35823:18;;35809:124::o;35940:333::-;21883:37;;;36259:2;36244:18;;21883:37;36095:2;36080:18;;36066:207::o;40021:268::-;40086:1;40093:101;40107:6;40104:1;40101:13;40093:101;;;40174:11;;;40168:18;40155:11;;;40148:39;40129:2;40122:10;40093:101;;;40209:6;40206:1;40203:13;40200:2;;;-1:-1;;40086:1;40256:16;;40249:27;40070:219::o;40402:117::-;-1:-1;;;;;40489:5;39433:54;40464:5;40461:35;40451:2;;40510:1;;40500:12;40451:2;40445:74;:::o;40526:111::-;40607:5;39232:13;39225:21;40585:5;40582:32;40572:2;;40628:1;;40618:12

Swarm Source

ipfs://9fe7f4bb7bc54ac6e843fbad8662695d9bb858a160e7b252dd56b9cdb4724e6d
Block Transaction Gas Used Reward
Age Block Fee Address Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading