ETH Price: $2,084.74 (-1.77%)

Contract

0xeb94e7cD446a15DCab9C5d04dc5Bb805E528DCbb
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Withdraw181822382023-09-21 5:41:11896 days ago1695274871IN
0xeb94e7cD...5E528DCbb
0 ETH0.000700067.36025982
Withdraw181788792023-09-20 18:25:11897 days ago1695234311IN
0xeb94e7cD...5E528DCbb
0 ETH0.0023292524.48595752
Withdraw181260412023-09-13 7:57:11904 days ago1694591831IN
0xeb94e7cD...5E528DCbb
0 ETH0.0033699830.03498298
Withdraw181255712023-09-13 6:22:23904 days ago1694586143IN
0xeb94e7cD...5E528DCbb
0 ETH0.0021393122.48646484
Withdraw181199262023-09-12 11:22:47905 days ago1694517767IN
0xeb94e7cD...5E528DCbb
0 ETH0.0015237713.57918109
Withdraw180912542023-09-08 10:58:59909 days ago1694170739IN
0xeb94e7cD...5E528DCbb
0 ETH0.0010254110.77951713
Withdraw180906932023-09-08 9:05:35909 days ago1694163935IN
0xeb94e7cD...5E528DCbb
0 ETH0.0026911112.69102174
Withdraw180842932023-09-07 11:36:59910 days ago1694086619IN
0xeb94e7cD...5E528DCbb
0 ETH0.0012767513.42001236
Withdraw180836312023-09-07 9:22:47910 days ago1694078567IN
0xeb94e7cD...5E528DCbb
0 ETH0.00149715.73706991
Withdraw180767872023-09-06 10:22:59911 days ago1693995779IN
0xeb94e7cD...5E528DCbb
0 ETH0.0014659515.41068462
Withdraw180756772023-09-06 6:37:23911 days ago1693982243IN
0xeb94e7cD...5E528DCbb
0 ETH0.000910369.57125268
Withdraw180752742023-09-06 5:15:59911 days ago1693977359IN
0xeb94e7cD...5E528DCbb
0 ETH0.000894929.40893367
Withdraw180748892023-09-06 3:58:59911 days ago1693972739IN
0xeb94e7cD...5E528DCbb
0 ETH0.0009901310.41001535
Withdraw180733162023-09-05 22:42:47912 days ago1693953767IN
0xeb94e7cD...5E528DCbb
0 ETH0.0029962826.69866634
Withdraw180725122023-09-05 19:59:47912 days ago1693943987IN
0xeb94e7cD...5E528DCbb
0 ETH0.0012108112.72694751
Withdraw180724252023-09-05 19:41:59912 days ago1693942919IN
0xeb94e7cD...5E528DCbb
0 ETH0.0015491513.80532213
Withdraw180723822023-09-05 19:33:23912 days ago1693942403IN
0xeb94e7cD...5E528DCbb
0 ETH0.0014997715.76622495
Withdraw180715572023-09-05 16:46:23912 days ago1693932383IN
0xeb94e7cD...5E528DCbb
0 ETH0.0017171522.0040951
Withdraw180710822023-09-05 15:09:59912 days ago1693926599IN
0xeb94e7cD...5E528DCbb
0 ETH0.00157216.52336652
Withdraw180703712023-09-05 12:46:59912 days ago1693918019IN
0xeb94e7cD...5E528DCbb
0 ETH0.0013025113.69422358
Withdraw180692162023-09-05 8:54:59912 days ago1693904099IN
0xeb94e7cD...5E528DCbb
0 ETH0.0012364813
Withdraw180677602023-09-05 4:01:59912 days ago1693886519IN
0xeb94e7cD...5E528DCbb
0 ETH0.0011220111.79499674
Withdraw180665822023-09-05 0:04:23913 days ago1693872263IN
0xeb94e7cD...5E528DCbb
0 ETH0.0004191814.43420084
Withdraw180665822023-09-05 0:04:23913 days ago1693872263IN
0xeb94e7cD...5E528DCbb
0 ETH0.0004191814.43420084
Withdraw180665822023-09-05 0:04:23913 days ago1693872263IN
0xeb94e7cD...5E528DCbb
0 ETH0.0013732414.43420084
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer180453452023-09-02 0:43:47916 days ago1693615427
0xeb94e7cD...5E528DCbb
11.79248683 ETH
Transfer180448442023-09-01 23:02:11916 days ago1693609331
0xeb94e7cD...5E528DCbb
0.01555573 ETH
Transfer180448302023-09-01 22:59:23916 days ago1693609163
0xeb94e7cD...5E528DCbb
0.02167121 ETH
Transfer180448132023-09-01 22:55:47916 days ago1693608947
0xeb94e7cD...5E528DCbb
0.03839561 ETH
Transfer180444992023-09-01 21:52:23916 days ago1693605143
0xeb94e7cD...5E528DCbb
0.07509815 ETH
Transfer180444612023-09-01 21:44:47916 days ago1693604687
0xeb94e7cD...5E528DCbb
0.03072453 ETH
Transfer180444572023-09-01 21:43:59916 days ago1693604639
0xeb94e7cD...5E528DCbb
0.02377512 ETH
Transfer180443612023-09-01 21:24:47916 days ago1693603487
0xeb94e7cD...5E528DCbb
0.03142773 ETH
Transfer180443322023-09-01 21:18:59916 days ago1693603139
0xeb94e7cD...5E528DCbb
0.13005231 ETH
Transfer180443242023-09-01 21:17:23916 days ago1693603043
0xeb94e7cD...5E528DCbb
0.037653 ETH
Transfer180442552023-09-01 21:03:35916 days ago1693602215
0xeb94e7cD...5E528DCbb
0.02066169 ETH
Transfer180442052023-09-01 20:53:35916 days ago1693601615
0xeb94e7cD...5E528DCbb
0.04246897 ETH
Transfer180441282023-09-01 20:37:59916 days ago1693600679
0xeb94e7cD...5E528DCbb
0.03138122 ETH
Transfer180438022023-09-01 19:31:59916 days ago1693596719
0xeb94e7cD...5E528DCbb
0.25402205 ETH
Transfer180436722023-09-01 19:05:11916 days ago1693595111
0xeb94e7cD...5E528DCbb
0.20893151 ETH
Transfer180433502023-09-01 17:59:59916 days ago1693591199
0xeb94e7cD...5E528DCbb
0.1355927 ETH
Transfer180432842023-09-01 17:46:35916 days ago1693590395
0xeb94e7cD...5E528DCbb
0.13778176 ETH
Transfer180432632023-09-01 17:42:23916 days ago1693590143
0xeb94e7cD...5E528DCbb
0.14353565 ETH
Transfer180421972023-09-01 14:08:23916 days ago1693577303
0xeb94e7cD...5E528DCbb
0.05316666 ETH
Transfer180417222023-09-01 12:32:11916 days ago1693571531
0xeb94e7cD...5E528DCbb
0.05707696 ETH
Transfer180415442023-09-01 11:56:23916 days ago1693569383
0xeb94e7cD...5E528DCbb
0.04811825 ETH
Transfer180413042023-09-01 11:08:11916 days ago1693566491
0xeb94e7cD...5E528DCbb
0.14364369 ETH
Transfer180407972023-09-01 9:26:11916 days ago1693560371
0xeb94e7cD...5E528DCbb
0.02678058 ETH
Transfer180405122023-09-01 8:28:47916 days ago1693556927
0xeb94e7cD...5E528DCbb
0.02366123 ETH
Transfer180404682023-09-01 8:19:59916 days ago1693556399
0xeb94e7cD...5E528DCbb
0.01232507 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RavenFundStaking

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2023-08-21
*/

// RavenFund - Staking
//
// The raven symbolizes prophecy, insight, transformation, and intelligence. It also represents long-term success.
// The 1st AI-powered hedge fund
//
// https://www.ravenfund.app/
// https://twitter.com/RavenFund
// https://t.me/RavenFundPortal

// File: @openzeppelin/contracts/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;



/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

// File: @unlock-protocol/contracts/dist/PublicLock/IPublicLockV13.sol


pragma solidity >=0.5.17 <0.9.0;
pragma experimental ABIEncoderV2;

/**
 * @title The PublicLock Interface
 */

interface IPublicLockV13 {
  /// Functions
  function initialize(
    address _lockCreator,
    uint _expirationDuration,
    address _tokenAddress,
    uint _keyPrice,
    uint _maxNumberOfKeys,
    string calldata _lockName
  ) external;

  // default role from OpenZeppelin
  function DEFAULT_ADMIN_ROLE()
    external
    view
    returns (bytes32 role);

  /**
   * @notice The version number of the current implementation on this network.
   * @return The current version number.
   */
  function publicLockVersion()
    external
    pure
    returns (uint16);

  /**
   * @dev Called by lock manager to withdraw all funds from the lock
   * @param _tokenAddress specifies the token address to withdraw or 0 for ETH. This is usually
   * the same as `tokenAddress` in MixinFunds.
   * @param _recipient specifies the address that will receive the tokens
   * @param _amount specifies the max amount to withdraw, which may be reduced when
   * considering the available balance. Set to 0 or MAX_UINT to withdraw everything.
   * -- however be wary of draining funds as it breaks the `cancelAndRefund` and `expireAndRefundFor` use cases.
   */
  function withdraw(
    address _tokenAddress,
    address payable _recipient,
    uint _amount
  ) external;

  /**
   * A function which lets a Lock manager of the lock to change the price for future purchases.
   * @dev Throws if called by other than a Lock manager
   * @dev Throws if lock has been disabled
   * @dev Throws if _tokenAddress is not a valid token
   * @param _keyPrice The new price to set for keys
   * @param _tokenAddress The address of the erc20 token to use for pricing the keys,
   * or 0 to use ETH
   */
  function updateKeyPricing(
    uint _keyPrice,
    address _tokenAddress
  ) external;

  /**
   * Update the main key properties for the entire lock:
   *
   * - default duration of each key
   * - the maximum number of keys the lock can edit
   * - the maximum number of keys a single address can hold
   *
   * @notice keys previously bought are unaffected by this changes in expiration duration (i.e.
   * existing keys timestamps are not recalculated/updated)
   * @param _newExpirationDuration the new amount of time for each key purchased or type(uint).max for a non-expiring key
   * @param _maxKeysPerAcccount the maximum amount of key a single user can own
   * @param _maxNumberOfKeys uint the maximum number of keys
   * @dev _maxNumberOfKeys Can't be smaller than the existing supply
   */
  function updateLockConfig(
    uint _newExpirationDuration,
    uint _maxNumberOfKeys,
    uint _maxKeysPerAcccount
  ) external;

  /**
   * Checks if the user has a non-expired key.
   * @param _user The address of the key owner
   */
  function getHasValidKey(
    address _user
  ) external view returns (bool);

  /**
   * @dev Returns the key's ExpirationTimestamp field for a given owner.
   * @param _tokenId the id of the key
   * @dev Returns 0 if the owner has never owned a key for this lock
   */
  function keyExpirationTimestampFor(
    uint _tokenId
  ) external view returns (uint timestamp);

  /**
   * Public function which returns the total number of unique owners (both expired
   * and valid).  This may be larger than totalSupply.
   */
  function numberOfOwners() external view returns (uint);

  /**
   * Allows the Lock owner to assign
   * @param _lockName a descriptive name for this Lock.
   * @param _lockSymbol a Symbol for this Lock (default to KEY).
   * @param _baseTokenURI the baseTokenURI for this Lock
   */
  function setLockMetadata(
    string calldata _lockName,
    string calldata _lockSymbol,
    string calldata _baseTokenURI
  ) external;

  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string memory);

  /**  @notice A distinct Uniform Resource Identifier (URI) for a given asset.
   * @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
   *  3986. The URI may point to a JSON file that conforms to the "ERC721
   *  Metadata JSON Schema".
   * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
   * @param _tokenId The tokenID we're inquiring about
   * @return String representing the URI for the requested token
   */
  function tokenURI(
    uint256 _tokenId
  ) external view returns (string memory);

  /**
   * Allows a Lock manager to add or remove an event hook
   * @param _onKeyPurchaseHook Hook called when the `purchase` function is called
   * @param _onKeyCancelHook Hook called when the internal `_cancelAndRefund` function is called
   * @param _onValidKeyHook Hook called to determine if the contract should overide the status for a given address
   * @param _onTokenURIHook Hook called to generate a data URI used for NFT metadata
   * @param _onKeyTransferHook Hook called when a key is transfered
   * @param _onKeyExtendHook Hook called when a key is extended or renewed
   * @param _onKeyGrantHook Hook called when a key is granted
   */
  function setEventHooks(
    address _onKeyPurchaseHook,
    address _onKeyCancelHook,
    address _onValidKeyHook,
    address _onTokenURIHook,
    address _onKeyTransferHook,
    address _onKeyExtendHook,
    address _onKeyGrantHook
  ) external;

  /**
   * Allows a Lock manager to give a collection of users a key with no charge.
   * Each key may be assigned a different expiration date.
   * @dev Throws if called by other than a Lock manager
   * @param _recipients An array of receiving addresses
   * @param _expirationTimestamps An array of expiration Timestamps for the keys being granted
   * @return the ids of the granted tokens
   */
  function grantKeys(
    address[] calldata _recipients,
    uint[] calldata _expirationTimestamps,
    address[] calldata _keyManagers
  ) external returns (uint256[] memory);

  /**
   * Allows the Lock owner to extend an existing keys with no charge.
   * @param _tokenId The id of the token to extend
   * @param _duration The duration in secondes to add ot the key
   * @dev set `_duration` to 0 to use the default duration of the lock
   */
  function grantKeyExtension(
    uint _tokenId,
    uint _duration
  ) external;

  /**
   * @dev Purchase function
   * @param _values array of tokens amount to pay for this purchase >= the current keyPrice - any applicable discount
   * (_values is ignored when using ETH)
   * @param _recipients array of addresses of the recipients of the purchased key
   * @param _referrers array of addresses of the users making the referral
   * @param _keyManagers optional array of addresses to grant managing rights to a specific address on creation
   * @param _data array of arbitrary data populated by the front-end which initiated the sale
   * @notice when called for an existing and non-expired key, the `_keyManager` param will be ignored
   * @dev Setting _value to keyPrice exactly doubles as a security feature. That way if the lock owner increases the
   * price while my transaction is pending I can't be charged more than I expected (only applicable to ERC-20 when more
   * than keyPrice is approved for spending).
   * @return tokenIds the ids of the created tokens
   */
  function purchase(
    uint256[] calldata _values,
    address[] calldata _recipients,
    address[] calldata _referrers,
    address[] calldata _keyManagers,
    bytes[] calldata _data
  ) external payable returns (uint256[] memory tokenIds);

  /**
   * @dev Extend function
   * @param _value the number of tokens to pay for this purchase >= the current keyPrice - any applicable discount
   * (_value is ignored when using ETH)
   * @param _tokenId the id of the key to extend
   * @param _referrer address of the user making the referral
   * @param _data arbitrary data populated by the front-end which initiated the sale
   * @dev Throws if lock is disabled or key does not exist for _recipient. Throws if _recipient == address(0).
   */
  function extend(
    uint _value,
    uint _tokenId,
    address _referrer,
    bytes calldata _data
  ) external payable;

  /**
   * Returns the percentage of the keyPrice to be sent to the referrer (in basis points)
   * @param _referrer the address of the referrer
   * @return referrerFee the percentage of the keyPrice to be sent to the referrer (in basis points)
   */
  function referrerFees(
    address _referrer
  ) external view returns (uint referrerFee);

  /**
   * Set a specific percentage of the keyPrice to be sent to the referrer while purchasing,
   * extending or renewing a key.
   * @param _referrer the address of the referrer
   * @param _feeBasisPoint the percentage of the price to be used for this
   * specific referrer (in basis points)
   * @dev To send a fixed percentage of the key price to all referrers, sett a percentage to `address(0)`
   */
  function setReferrerFee(
    address _referrer,
    uint _feeBasisPoint
  ) external;

  /**
   * Merge existing keys
   * @param _tokenIdFrom the id of the token to substract time from
   * @param _tokenIdTo the id of the destination token  to add time
   * @param _amount the amount of time to transfer (in seconds)
   */
  function mergeKeys(
    uint _tokenIdFrom,
    uint _tokenIdTo,
    uint _amount
  ) external;

  /**
   * Deactivate an existing key
   * @param _tokenId the id of token to burn
   * @notice the key will be expired and ownership records will be destroyed
   */
  function burn(uint _tokenId) external;

  /**
   * @param _gasRefundValue price in wei or token in smallest price unit
   * @dev Set the value to be refunded to the sender on purchase
   */
  function setGasRefundValue(
    uint256 _gasRefundValue
  ) external;

  /**
   * _gasRefundValue price in wei or token in smallest price unit
   * @dev Returns the value/price to be refunded to the sender on purchase
   */
  function gasRefundValue()
    external
    view
    returns (uint256 _gasRefundValue);

  /**
   * @notice returns the minimum price paid for a purchase with these params.
   * @dev this considers any discount from Unlock or the OnKeyPurchase hook.
   */
  function purchasePriceFor(
    address _recipient,
    address _referrer,
    bytes calldata _data
  ) external view returns (uint);

  /**
   * Allow a Lock manager to change the transfer fee.
   * @dev Throws if called by other than a Lock manager
   * @param _transferFeeBasisPoints The new transfer fee in basis-points(bps).
   * Ex: 200 bps = 2%
   */
  function updateTransferFee(
    uint _transferFeeBasisPoints
  ) external;

  /**
   * Determines how much of a fee would need to be paid in order to
   * transfer to another account.  This is pro-rated so the fee goes
   * down overtime.
   * @dev Throws if _tokenId does not have a valid key
   * @param _tokenId The id of the key check the transfer fee for.
   * @param _time The amount of time to calculate the fee for.
   * @return The transfer fee in seconds.
   */
  function getTransferFee(
    uint _tokenId,
    uint _time
  ) external view returns (uint);

  /**
   * @dev Invoked by a Lock manager to expire the user's key
   * and perform a refund and cancellation of the key
   * @param _tokenId The key id we wish to refund to
   * @param _amount The amount to refund to the key-owner
   * @dev Throws if called by other than a Lock manager
   * @dev Throws if _keyOwner does not have a valid key
   */
  function expireAndRefundFor(
    uint _tokenId,
    uint _amount
  ) external;

  /**
   * @dev allows the key manager to expire a given tokenId
   * and send a refund to the keyOwner based on the amount of time remaining.
   * @param _tokenId The id of the key to cancel.
   * @notice cancel is enabled with a 10% penalty by default on all Locks.
   */
  function cancelAndRefund(uint _tokenId) external;

  /**
   * Allow a Lock manager to change the refund penalty.
   * @dev Throws if called by other than a Lock manager
   * @param _freeTrialLength The new duration of free trials for this lock
   * @param _refundPenaltyBasisPoints The new refund penaly in basis-points(bps)
   */
  function updateRefundPenalty(
    uint _freeTrialLength,
    uint _refundPenaltyBasisPoints
  ) external;

  /**
   * @dev Determines how much of a refund a key owner would receive if they issued
   * @param _tokenId the id of the token to get the refund value for.
   * @notice Due to the time required to mine a tx, the actual refund amount will be lower
   * than what the user reads from this call.
   * @return refund the amount of tokens refunded
   */
  function getCancelAndRefundValue(
    uint _tokenId
  ) external view returns (uint refund);

  function addLockManager(address account) external;

  function isLockManager(
    address account
  ) external view returns (bool);

  /**
   * Returns the address of the `onKeyPurchaseHook` hook.
   * @return hookAddress address of the hook
   */
  function onKeyPurchaseHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onKeyCancelHook` hook.
   * @return hookAddress address of the hook
   */
  function onKeyCancelHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onValidKeyHook` hook.
   * @return hookAddress address of the hook
   */
  function onValidKeyHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onTokenURIHook` hook.
   * @return hookAddress address of the hook
   */
  function onTokenURIHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onKeyTransferHook` hook.
   * @return hookAddress address of the hook
   */
  function onKeyTransferHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onKeyExtendHook` hook.
   * @return hookAddress the address ok the hook
   */
  function onKeyExtendHook()
    external
    view
    returns (address hookAddress);

  /**
   * Returns the address of the `onKeyGrantHook` hook.
   * @return hookAddress the address ok the hook
   */
  function onKeyGrantHook()
    external
    view
    returns (address hookAddress);

  function renounceLockManager() external;

  /**
   * @return the maximum number of key allowed for a single address
   */
  function maxKeysPerAddress() external view returns (uint);

  function expirationDuration()
    external
    view
    returns (uint256);

  function freeTrialLength()
    external
    view
    returns (uint256);

  function keyPrice() external view returns (uint256);

  function maxNumberOfKeys()
    external
    view
    returns (uint256);

  function refundPenaltyBasisPoints()
    external
    view
    returns (uint256);

  function tokenAddress() external view returns (address);

  function transferFeeBasisPoints()
    external
    view
    returns (uint256);

  function unlockProtocol() external view returns (address);

  function keyManagerOf(
    uint
  ) external view returns (address);

  ///===================================================================

  /**
   * @notice Allows the key owner to safely share their key (parent key) by
   * transferring a portion of the remaining time to a new key (child key).
   * @dev Throws if key is not valid.
   * @dev Throws if `_to` is the zero address
   * @param _to The recipient of the shared key
   * @param _tokenId the key to share
   * @param _timeShared The amount of time shared
   * checks if `_to` is a smart contract (code size > 0). If so, it calls
   * `onERC721Received` on `_to` and throws if the return value is not
   * `bytes4(keccak256('onERC721Received(address,address,uint,bytes)'))`.
   * @dev Emit Transfer event
   */
  function shareKey(
    address _to,
    uint _tokenId,
    uint _timeShared
  ) external;

  /**
   * @notice Update transfer and cancel rights for a given key
   * @param _tokenId The id of the key to assign rights for
   * @param _keyManager The address to assign the rights to for the given key
   */
  function setKeyManagerOf(
    uint _tokenId,
    address _keyManager
  ) external;

  /**
   * Check if a certain key is valid
   * @param _tokenId the id of the key to check validity
   * @notice this makes use of the onValidKeyHook if it is set
   */
  function isValidKey(
    uint _tokenId
  ) external view returns (bool);

  /**
   * Returns the number of keys owned by `_keyOwner` (expired or not)
   * @param _keyOwner address for which we are retrieving the total number of keys
   * @return numberOfKeys total number of keys owned by the address
   */
  function totalKeys(
    address _keyOwner
  ) external view returns (uint numberOfKeys);

  /// @notice A descriptive name for a collection of NFTs in this contract
  function name()
    external
    view
    returns (string memory _name);

  ///===================================================================

  /// From ERC165.sol
  function supportsInterface(
    bytes4 interfaceId
  ) external view returns (bool);

  ///===================================================================

  /// From ERC-721
  /**
   * In the specific case of a Lock, `balanceOf` returns only the tokens with a valid expiration timerange
   * @return balance The number of valid keys owned by `_keyOwner`
   */
  function balanceOf(
    address _owner
  ) external view returns (uint256 balance);

  /**
   * @dev Returns the owner of the NFT specified by `tokenId`.
   */
  function ownerOf(
    uint256 tokenId
  ) external view returns (address _owner);

  /**
   * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
   * another (`to`).
   *
   * Requirements:
   * - `from`, `to` cannot be zero.
   * - `tokenId` must be owned by `from`.
   * - If the caller is not `from`, it must be have been allowed to move this
   * NFT by either {approve} or {setApprovalForAll}.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  ) external;

  /**
   * an ERC721-like function to transfer a token from one account to another.
   * @param from the owner of token to transfer
   * @param to the address that will receive the token
   * @param tokenId the id of the token
   * @dev Requirements: if the caller is not `from`, it must be approved to move this token by
   * either {approve} or {setApprovalForAll}.
   * The key manager will be reset to address zero after the transfer
   */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  ) external;

  /**
   * Lending a key allows you to transfer the token while retaining the
   * ownerships right by setting yourself as a key manager first.
   * @param from the owner of token to transfer
   * @param to the address that will receive the token
   * @param tokenId the id of the token
   * @notice This function can only be called by 1) the key owner when no key manager is set or 2) the key manager.
   * After calling the function, the `_recipent` will be the new owner, and the sender of the tx
   * will become the key manager.
   */
  function lendKey(
    address from,
    address to,
    uint tokenId
  ) external;

  /**
   * Unlend is called when you have lent a key and want to claim its full ownership back.
   * @param _recipient the address that will receive the token ownership
   * @param _tokenId the id of the token
   * @dev Only the key manager of the token can call this function
   */
  function unlendKey(
    address _recipient,
    uint _tokenId
  ) external;

  function approve(address to, uint256 tokenId) external;

  /**
   * @notice Get the approved address for a single NFT
   * @dev Throws if `_tokenId` is not a valid NFT.
   * @param _tokenId The NFT to find the approved address for
   * @return operator The approved address for this NFT, or the zero address if there is none
   */
  function getApproved(
    uint256 _tokenId
  ) external view returns (address operator);

  /**
   * @dev Sets or unsets the approval of a given operator
   * An operator is allowed to transfer all tokens of the sender on their behalf
   * @param _operator operator address to set the approval
   * @param _approved representing the status of the approval to be set
   * @notice disabled when transfers are disabled
   */
  function setApprovalForAll(
    address _operator,
    bool _approved
  ) external;

  /**
   * @dev Tells whether an operator is approved by a given keyManager
   * @param _owner owner address which you want to query the approval of
   * @param _operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(
    address _owner,
    address _operator
  ) external view returns (bool);

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes calldata data
  ) external;

  /**
   * Returns the total number of keys, including non-valid ones
   * @return _totalKeysCreated the total number of keys, valid or not
   */
  function totalSupply() external view returns (uint256 _totalKeysCreated);

  function tokenOfOwnerByIndex(
    address _owner,
    uint256 index
  ) external view returns (uint256 tokenId);

  function tokenByIndex(
    uint256 index
  ) external view returns (uint256);

  /**
   * Innherited from Open Zeppelin AccessControl.sol
   */
  function getRoleAdmin(
    bytes32 role
  ) external view returns (bytes32);

  function grantRole(
    bytes32 role,
    address account
  ) external;

  function revokeRole(
    bytes32 role,
    address account
  ) external;

  function renounceRole(
    bytes32 role,
    address account
  ) external;

  function hasRole(
    bytes32 role,
    address account
  ) external view returns (bool);

  /** `owner()` is provided as an helper to mimick the `Ownable` contract ABI.
   * The `Ownable` logic is used by many 3rd party services to determine
   * contract ownership - e.g. who is allowed to edit metadata on Opensea.
   *
   * @notice This logic is NOT used internally by the Unlock Protocol and is made
   * available only as a convenience helper.
   */
  function owner() external view returns (address owner);

  function setOwner(address account) external;

  function isOwner(
    address account
  ) external view returns (bool isOwner);

  /**
   * Migrate data from the previous single owner => key mapping to
   * the new data structure w multiple tokens.
   * @param _calldata an ABI-encoded representation of the params (v10: the number of records to migrate as `uint`)
   * @dev when all record schemas are sucessfully upgraded, this function will update the `schemaVersion`
   * variable to the latest/current lock version
   */
  function migrate(bytes calldata _calldata) external;

  /**
   * Returns the version number of the data schema currently used by the lock
   * @notice if this is different from `publicLockVersion`, then the ability to purchase, grant
   * or extend keys is disabled.
   * @dev will return 0 if no ;igration has ever been run
   */
  function schemaVersion() external view returns (uint);

  /**
   * Set the schema version to the latest
   * @notice only lock manager call call this
   */
  function updateSchemaVersion() external;

  /**
   * Renew a given token
   * @notice only works for non-free, expiring, ERC20 locks
   * @param _tokenId the ID fo the token to renew
   * @param _referrer the address of the person to be granted UDT
   */
  function renewMembershipFor(
    uint _tokenId,
    address _referrer
  ) external;

  /**
   * @dev helper to check if a key is currently renewable 
   * it will revert if the pricing or duration of the lock have been modified 
   * unfavorably since the key was bought(price increase or duration decrease).
   * It will also revert if a lock is not renewable or if the key is not ready for renewal yet 
   * (at least 90% expired).
   * @param tokenId the id of the token to check
   * @param referrer the address where to send the referrer fee
   * @return true if the terms has changed
   */
  function isRenewable(uint256 tokenId, address referrer) external view returns (bool);
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

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


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
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) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            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) {
        unchecked {
            // 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) {
        unchecked {
            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) {
        unchecked {
            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) {
        return a + b;
    }

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

    /**
     * @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.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        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) {
        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) {
        unchecked {
            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.
     *
     * 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) {
        unchecked {
            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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

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

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

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

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

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

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

// File: contracts/RFStakePool.sol




pragma solidity ^0.8.19;







contract RavenFundStaking is ReentrancyGuard {
    using SafeMath for uint256;

    IERC20 public stakingToken;
    address public rewardsProvider;
    address public teamWallet;
    address public owner;
    Lockers[] public lockSubNFT;

    struct Lockers {
        IPublicLockV13 instance;
        IERC721 nft;
    }

    uint256 public maxStakeAmount = 0;
    uint256 public minClaimAmount = 15_000 ether;
    uint256 public stakeWaitTime = 12 hours;
    uint256 public claimInterval = 24 hours;
    uint256 public timeElapsedFactor = 7 days;
    uint256 public rewardResetInterval = 15 days;
    uint256 public malusNoSubscription = 70;
    uint256 public totalDistributed = 0;

    bool public enableClaim = false;
    bool public enableStake = false;
    bool public activateSendTeam = true;

    struct StakerInfo {
        uint256 amountStaked;
        uint256 lastStakeTime;
        uint256 lastClaimTime;
        uint256 rewardsEarned;
        uint256 rewardsClaimed;
        uint256 lastRewardUpdateTime;
        uint256 keyArray;
    }

    uint256 public totalStakedAmount;

    struct Funds {
        uint256 amount;
        uint256 depositTime;
    }

    Funds[] public fundDeposits;
    uint256 public consolidatedFunds = 0;

    mapping(address => StakerInfo) public stakers;
    address[] public stakerAddresses;

    constructor(address _stakingToken, address _rewardsProvider, address _teamWallet) {
        stakingToken = IERC20(_stakingToken);
        rewardsProvider = _rewardsProvider;
        teamWallet = _teamWallet;
        owner = msg.sender;
    }

    modifier onlyRewardsProvider() {
        require(msg.sender == rewardsProvider || msg.sender == owner || msg.sender == teamWallet, "Not the rewards provider");
        _;
    }

    function stake(uint256 amount) external nonReentrant {
        require(enableStake, "Stake not enabled.");
        StakerInfo storage staker = stakers[msg.sender];
        if (maxStakeAmount > 0) {
            require(staker.amountStaked + amount <= maxStakeAmount, "Max stake amount reached");
        }

        if (staker.lastRewardUpdateTime == 0) {
            staker.lastRewardUpdateTime = block.timestamp;
        }

        if (staker.keyArray == 0){
            stakerAddresses.push(msg.sender);
            staker.keyArray = stakerAddresses.length;
        }

        uint256 allowance = stakingToken.allowance(msg.sender, address(this));
        require(allowance >= amount, "Allowance is not sufficient to stake tokens");

        staker.lastStakeTime = block.timestamp;
        staker.amountStaked = staker.amountStaked.add(amount);
        totalStakedAmount = totalStakedAmount.add(amount);

        require(stakingToken.transferFrom(msg.sender, address(this), amount), "Token transfer failed");
    }

    function withdraw(uint256 amount) external nonReentrant {
        StakerInfo storage staker = stakers[msg.sender];

        require(amount > 0, "Amount must be greater than 0");
        require(staker.amountStaked >= amount, "Insufficient staked amount");

        staker.amountStaked = staker.amountStaked.sub(amount);
        totalStakedAmount = totalStakedAmount.sub(amount);

        if (staker.amountStaked <= 0) {
            uint256 reward = staker.rewardsEarned;
            staker.rewardsEarned = 0;
            staker.lastClaimTime = block.timestamp;
            uint256 contractBalance = address(this).balance;
            if (reward > 0 && contractBalance >= reward && activateSendTeam){
                calibrateFundArray(reward);

                payable(teamWallet).transfer(reward);
            }
        }

        require(stakingToken.transfer(msg.sender, amount), "Token transfer failed");
    }

    function canClaim(address stakerAddress) public view returns (bool) {
        StakerInfo storage staker = stakers[stakerAddress];
        uint256 reward = previewStakerRewards(stakerAddress);
        uint256 contractBalance = address(this).balance;
        return enableClaim && reward > 0 && contractBalance >= reward && (staker.amountStaked >= minClaimAmount) && (block.timestamp > staker.lastStakeTime + stakeWaitTime) && (block.timestamp > staker.lastClaimTime + claimInterval);
    }

    function reasonClaim(address stakerAddress) public view returns (string memory) {
        StakerInfo storage staker = stakers[stakerAddress];
        uint256 reward = previewStakerRewards(stakerAddress);
        uint256 contractBalance = address(this).balance;
        if (!enableClaim){
            return "Claim not enabled, please wait a moment.";
        }
        if (staker.amountStaked < minClaimAmount) {
            return string(abi.encodePacked("To be eligible, you have to stake a minimum $RAVEN of ", Strings.toString(minClaimAmount.div(1 ether))));
        }
        if (block.timestamp <= staker.lastStakeTime + stakeWaitTime) {
            return Strings.toString(staker.lastStakeTime + stakeWaitTime);
        }
        if (block.timestamp <= staker.lastClaimTime + claimInterval) {
            return Strings.toString(staker.lastClaimTime + claimInterval);
        }
        if (reward <= 0){
            return "You don't have any reward to claim for the moment.";
        }
        if (contractBalance < reward) {
            return "Please wait new funds to claim your reward.";
        }
        return "You can claim !";
    }

    function claim() external nonReentrant {
        require(enableClaim, "Claim not enabled.");
        StakerInfo storage staker = stakers[msg.sender];
        require(staker.amountStaked >= minClaimAmount, "Not enough tokens staked to claim.");
        require(block.timestamp > staker.lastStakeTime + stakeWaitTime, "Need to wait after staking");
        require(block.timestamp > staker.lastClaimTime + claimInterval, "Already claimed recently");

        updateStakerRewards(msg.sender);

        uint256 reward = staker.rewardsEarned;
        require(reward > 0, "No rewards available");

        uint256 contractBalance = address(this).balance;
        require(contractBalance >= reward, "Not enough ETH in the contract");

        calibrateFundArray(reward);
        staker.rewardsEarned = 0;
        staker.lastClaimTime = block.timestamp;
        staker.rewardsClaimed = staker.rewardsClaimed.add(reward);
        totalDistributed = totalDistributed.add(reward);

        payable(msg.sender).transfer(reward);
    }

    function previewStakerRewards(address stakerAddress) public view returns (uint256) {
        StakerInfo storage staker = stakers[stakerAddress];

        if (staker.amountStaked < minClaimAmount || totalStakedAmount <= 0 || timeElapsedFactor <= 0) {
            return staker.rewardsEarned;
        }

        uint256 totalReward = 0;
        for(uint256 i = 0; i < fundDeposits.length; i++) {
            if (fundDeposits[i].amount == 0) {
                continue;
            }
            uint256 referenceTime = max(staker.lastRewardUpdateTime, fundDeposits[i].depositTime);
            uint256 timeElapsed = block.timestamp.sub(referenceTime);
            
            uint256 timeFactor;
            if(timeElapsed >= timeElapsedFactor) {
                timeFactor = 1 ether;
            } else {
                timeFactor = timeElapsed.mul(1 ether).div(timeElapsedFactor);
            }
            
            uint256 stakerShare = staker.amountStaked.mul(1 ether).div(totalStakedAmount);
            uint256 rewardFromThisDeposit = fundDeposits[i].amount.mul(stakerShare).div(1 ether);
            rewardFromThisDeposit = rewardFromThisDeposit.mul(timeFactor).div(1 ether);

            if (!ownsActiveNFT(stakerAddress)) {
                rewardFromThisDeposit = rewardFromThisDeposit.mul(malusNoSubscription).div(100);
            }

            totalReward = totalReward.add(rewardFromThisDeposit);
        }
        // Then add rewards from consolidated funds
        uint256 stakerShareFromConsolidated = staker.amountStaked.mul(1 ether).div(totalStakedAmount);
        uint256 rewardFromConsolidated = consolidatedFunds.mul(stakerShareFromConsolidated).div(1 ether);
        if (!ownsActiveNFT(stakerAddress)) {
            rewardFromConsolidated = rewardFromConsolidated.mul(malusNoSubscription).div(100);
        }

        totalReward = totalReward.add(rewardFromConsolidated);

        return staker.rewardsEarned.add(totalReward);
    }

    function updateStakerRewards(address stakerAddress) internal {
        StakerInfo storage staker = stakers[stakerAddress];

        if (staker.amountStaked < minClaimAmount || totalStakedAmount <= 0 || timeElapsedFactor <= 0) {
            staker.lastRewardUpdateTime = block.timestamp;
            return;
        }

        uint256 totalReward = 0;
        for(uint256 i = 0; i < fundDeposits.length; i++) {
            if (fundDeposits[i].amount == 0) {
                continue;
            }
            uint256 referenceTime = max(staker.lastRewardUpdateTime, fundDeposits[i].depositTime);
            uint256 timeElapsed = block.timestamp.sub(referenceTime);
            
            uint256 timeFactor;
            if(timeElapsed >= timeElapsedFactor) {
                timeFactor = 1 ether;
            } else {
                timeFactor = timeElapsed.mul(1 ether).div(timeElapsedFactor);
            }
            
            uint256 stakerShare = staker.amountStaked.mul(1 ether).div(totalStakedAmount);
            uint256 rewardFromThisDeposit = fundDeposits[i].amount.mul(stakerShare).div(1 ether);
            rewardFromThisDeposit = rewardFromThisDeposit.mul(timeFactor).div(1 ether);

            if (!ownsActiveNFT(stakerAddress)) {
                rewardFromThisDeposit = rewardFromThisDeposit.mul(malusNoSubscription).div(100);
            }

            totalReward = totalReward.add(rewardFromThisDeposit);
        }
        // Then add rewards from consolidated funds
        uint256 stakerShareFromConsolidated = staker.amountStaked.mul(1 ether).div(totalStakedAmount);
        uint256 rewardFromConsolidated = consolidatedFunds.mul(stakerShareFromConsolidated).div(1 ether);
        if (!ownsActiveNFT(stakerAddress)) {
            rewardFromConsolidated = rewardFromConsolidated.mul(malusNoSubscription).div(100);
        }
        totalReward = totalReward.add(rewardFromConsolidated);
        staker.rewardsEarned = staker.rewardsEarned.add(totalReward);
        staker.lastRewardUpdateTime = block.timestamp;
    }

    function consolidateFunds() private {
        Funds[] memory newFundDeposits = new Funds[](fundDeposits.length);

        uint256 count = 0;
        for (uint256 i = 0; i < fundDeposits.length; i++) {
            uint256 timeElapsed = block.timestamp.sub(fundDeposits[i].depositTime);
            if (timeElapsed >= timeElapsedFactor) {
                consolidatedFunds = consolidatedFunds.add(fundDeposits[i].amount);
            } else {
                newFundDeposits[count] = fundDeposits[i];
                count++;
            }
        }

        if (count > 0) {
            if (fundDeposits.length != count) {
                while (fundDeposits.length > count) {
                    fundDeposits.pop();
                }
                
                for (uint256 i = 0; i < count; i++) {
                    fundDeposits[i] = newFundDeposits[i];
                }
            }
        } else {
            delete fundDeposits;
        }
    }

    function getTotalAvailableRewards() public view returns (uint256) {
        uint256 totalAvailable = consolidatedFunds;

        for (uint256 i = 0; i < fundDeposits.length; i++) {
            totalAvailable = totalAvailable.add(fundDeposits[i].amount);
        }

        return totalAvailable;
    }

    function depositETH() external payable onlyRewardsProvider {
        fundDeposits.push(Funds({
            amount: msg.value,
            depositTime: block.timestamp
        }));

        consolidateFunds();
    }

    function withdrawFunds() external onlyRewardsProvider {
        uint256 balance = address(this).balance;
        require(balance > 0, "No funds to withdraw");
        payable(msg.sender).transfer(balance);

        delete fundDeposits;
        consolidatedFunds = 0;
    }

    function unClaim(uint256 indexStart, uint256 indexStop) external onlyRewardsProvider {
        uint256 iStart = indexStart;
        uint256 iEnd = stakerAddresses.length;
        if (indexStop > 0 && indexStop > indexStart){
            iEnd = indexStop;
        }
        uint256 totalReward = 0;
        for (uint256 i = iStart; i < iEnd; i++) {
            StakerInfo storage staker = stakers[stakerAddresses[i]];
            if (block.timestamp - staker.lastClaimTime > rewardResetInterval && staker.rewardsEarned > 0) {
                totalReward = totalReward.add(staker.rewardsEarned);
                staker.rewardsEarned = 0;
                staker.lastClaimTime = block.timestamp;
                staker.lastRewardUpdateTime = block.timestamp;
            }
        }
        uint256 balance = address(this).balance;
        if (totalReward > 0 && balance >= totalReward && activateSendTeam){
            calibrateFundArray(totalReward);
            payable(teamWallet).transfer(totalReward);
        }
    }

    function getStakersArray() public view returns (address[] memory) {
        return stakerAddresses;
    }

    function getFundDepositsArray() public view returns (Funds[] memory) {
        return fundDeposits;
    }

    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    function calibrateFundArray(uint256 amount) private {
        uint256 rewardLeftToClaim = amount;
        for (uint256 i = 0; i < fundDeposits.length && rewardLeftToClaim > 0; i++) {
            if (fundDeposits[i].amount == 0) {
                continue;
            }
            if (fundDeposits[i].amount <= rewardLeftToClaim) {
                rewardLeftToClaim = rewardLeftToClaim.sub(fundDeposits[i].amount);
                delete fundDeposits[i];
            } else {
                fundDeposits[i].amount = fundDeposits[i].amount.sub(rewardLeftToClaim);
                rewardLeftToClaim = 0;
            }
        }
        if (rewardLeftToClaim > 0 && consolidatedFunds > 0) {
            if (consolidatedFunds <= rewardLeftToClaim) {
                rewardLeftToClaim = rewardLeftToClaim.sub(consolidatedFunds);
                consolidatedFunds = 0;
            } else {
                consolidatedFunds = consolidatedFunds.sub(rewardLeftToClaim);
                rewardLeftToClaim = 0;
            }
        }
    }

    function ownsActiveNFT(address _user) public view returns (bool) {
        for (uint256 i = 0; i < lockSubNFT.length; i++) {
            if (lockSubNFT[i].instance.getHasValidKey(_user)) {
                return true;
            }
        }
        return false;
    }

    function ownsActiveNFTList(address _user) public view returns (address[] memory) {
        uint256 activeCount = 0;
        for (uint256 i = 0; i < lockSubNFT.length; i++) {
            if (lockSubNFT[i].instance.getHasValidKey(_user)) {
                activeCount++;
            }
        }
        address[] memory activeLockersAddress = new address[](activeCount);

        uint256 j = 0;
        for (uint256 i = 0; i < lockSubNFT.length; i++) {
            if (lockSubNFT[i].instance.getHasValidKey(_user)) {
                activeLockersAddress[j] = address(lockSubNFT[i].nft);
                j++;
            }
        }

        return activeLockersAddress;
    }

    function cleanLockers() external onlyRewardsProvider {
        delete lockSubNFT;
    }

    function setSubscriptionLockers(address[] calldata _lockers) external onlyRewardsProvider {
        for (uint i = 0; i < _lockers.length; i++) {
            address currentLocker = _lockers[i];
            Lockers memory lock;
            lock.instance = IPublicLockV13(currentLocker);
            lock.nft = IERC721(currentLocker);
            lockSubNFT.push(lock);
        }
    }

    function enableContract(bool _c, bool _s) external onlyRewardsProvider {
        enableClaim = _c;
        enableStake = _s;
    }

    function setTotalStakedAmount(uint256 _amount) external onlyRewardsProvider {
        totalStakedAmount = _amount;
    }

    function setRewardsProvider(address _provider) external onlyRewardsProvider {
        rewardsProvider = _provider;
    }

    function setOwner(address _owner) external onlyRewardsProvider {
        owner = _owner;
    }

    function setMaxStakeAmount(uint256 _amount) external onlyRewardsProvider {
        maxStakeAmount = _amount;
    }

    function setMinClaimAmount(uint256 _amount) external onlyRewardsProvider {
        minClaimAmount = _amount;
    }

    function setStakeWaitTime(uint256 _time) external onlyRewardsProvider {
        stakeWaitTime = _time;
    }

    function setClaimInterval(uint256 _interval) external onlyRewardsProvider {
        claimInterval = _interval;
    }

    function setTimeElapsedFactor(uint256 _time) external onlyRewardsProvider {
        timeElapsedFactor = _time;
    }

    function setMalusNoSubscription(uint256 _malus) external onlyRewardsProvider {
        malusNoSubscription = _malus;
    }

    function setRewardResetInterval(uint256 _reset) external onlyRewardsProvider {
        rewardResetInterval = _reset;
    }

    function setTotalDistributed(uint256 _t) external onlyRewardsProvider {
        totalDistributed = _t;
    }

    function setActivateSendTeam(bool _a) external onlyRewardsProvider {
        activateSendTeam = _a;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_stakingToken","type":"address"},{"internalType":"address","name":"_rewardsProvider","type":"address"},{"internalType":"address","name":"_teamWallet","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"activateSendTeam","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cleanLockers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"consolidatedFunds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"enableClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_c","type":"bool"},{"internalType":"bool","name":"_s","type":"bool"}],"name":"enableContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableStake","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fundDeposits","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"depositTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFundDepositsArray","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"depositTime","type":"uint256"}],"internalType":"struct RavenFundStaking.Funds[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakersArray","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAvailableRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockSubNFT","outputs":[{"internalType":"contract IPublicLockV13","name":"instance","type":"address"},{"internalType":"contract IERC721","name":"nft","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"malusNoSubscription","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxStakeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minClaimAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"ownsActiveNFT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"ownsActiveNFTList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"previewStakerRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakerAddress","type":"address"}],"name":"reasonClaim","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardResetInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_a","type":"bool"}],"name":"setActivateSendTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_interval","type":"uint256"}],"name":"setClaimInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_malus","type":"uint256"}],"name":"setMalusNoSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setMaxStakeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setMinClaimAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reset","type":"uint256"}],"name":"setRewardResetInterval","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"}],"name":"setRewardsProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"setStakeWaitTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_lockers","type":"address[]"}],"name":"setSubscriptionLockers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_time","type":"uint256"}],"name":"setTimeElapsedFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_t","type":"uint256"}],"name":"setTotalDistributed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setTotalStakedAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeWaitTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakerAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"stakers","outputs":[{"internalType":"uint256","name":"amountStaked","type":"uint256"},{"internalType":"uint256","name":"lastStakeTime","type":"uint256"},{"internalType":"uint256","name":"lastClaimTime","type":"uint256"},{"internalType":"uint256","name":"rewardsEarned","type":"uint256"},{"internalType":"uint256","name":"rewardsClaimed","type":"uint256"},{"internalType":"uint256","name":"lastRewardUpdateTime","type":"uint256"},{"internalType":"uint256","name":"keyArray","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeElapsedFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"indexStart","type":"uint256"},{"internalType":"uint256","name":"indexStop","type":"uint256"}],"name":"unClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600681905569032d26d12e980b60000060075561a8c06008556201518060095562093a80600a556213c680600b556046600c55600d819055600e805462ffffff1916620100001790556011553480156200005f57600080fd5b5060405162003278380380620032788339810160408190526200008291620000f4565b6001600081905580546001600160a01b039485166001600160a01b031991821617909155600280549385169382169390931790925560038054919093169082161790915560048054909116331790556200013e565b80516001600160a01b0381168114620000ef57600080fd5b919050565b6000806000606084860312156200010a57600080fd5b6200011584620000d7565b92506200012560208501620000d7565b91506200013560408501620000d7565b90509250925092565b61312a806200014e6000396000f3fe6080604052600436106102c95760003560e01c80638bd917fa11610175578063d244448c116100dc578063eec7810411610095578063f2d57adf1161006f578063f2d57adf146108d2578063f6326fb3146108f2578063fe4ce8d4146108fa578063ffebfd9a1461092f57600080fd5b8063eec7810414610892578063eef09740146108a7578063efca2eed146108bc57600080fd5b8063d244448c146107dc578063dcc2a55e146107fc578063e527f4801461081c578063e8f2f7f514610832578063ec3fe6b414610852578063ecc9747e1461087257600080fd5b8063a48bf0d11161012e578063a48bf0d11461072e578063a694fc3a1461074e578063adc25bde1461076e578063bf3506c114610784578063c44719a7146107a4578063c51af512146107c657600080fd5b80638bd917fa146105e15780638da5cb5b146106215780639168ae7214610641578063922fc248146106ce57806394f3177b146106ee578063a17936031461070e57600080fd5b80633ea0b6b311610234578063567e98f9116101ed5780635fa505f3116101c75780635fa505f31461056b5780636ad0530e1461058b57806372f702f3146105ab57806389a4b4b6146105cb57600080fd5b8063567e98f91461051f57806359927044146105355780635d80ca321461055557600080fd5b80633ea0b6b31461047f57806342d1456e1461049f578063459598a2146104b5578063485e670f146104d55780634ba3cef9146104f55780634e71d92d1461050a57600080fd5b806324600fc31161028657806324600fc3146103b557806328dae6e3146103ca5780632aea6f5d146103e45780632d7672111461041c5780632e1a7d4d146104495780633bbd1ed21461046957600080fd5b806302023e67146102ce5780630499de60146102f057806307ffd0f2146103245780630b433a12146103445780630d7731ad1461036857806313af403514610395575b600080fd5b3480156102da57600080fd5b506102ee6102e9366004612c97565b61094f565b005b3480156102fc57600080fd5b50600e5461030f90610100900460ff1681565b60405190151581526020015b60405180910390f35b34801561033057600080fd5b506102ee61033f366004612cbe565b6109b1565b34801561035057600080fd5b5061035a60095481565b60405190815260200161031b565b34801561037457600080fd5b50610388610383366004612ce2565b610a21565b60405161031b9190612d2f565b3480156103a157600080fd5b506102ee6103b0366004612ce2565b610bae565b3480156103c157600080fd5b506102ee610c24565b3480156103d657600080fd5b50600e5461030f9060ff1681565b3480156103f057600080fd5b50600254610404906001600160a01b031681565b6040516001600160a01b03909116815260200161031b565b34801561042857600080fd5b5061043c610437366004612ce2565b610cff565b60405161031b9190612d62565b34801561045557600080fd5b506102ee610464366004612c97565b610f39565b34801561047557600080fd5b5061035a60115481565b34801561048b57600080fd5b50600e5461030f9062010000900460ff1681565b3480156104ab57600080fd5b5061035a60085481565b3480156104c157600080fd5b506104046104d0366004612c97565b61115b565b3480156104e157600080fd5b506102ee6104f0366004612c97565b611185565b34801561050157600080fd5b5061043c6111de565b34801561051657600080fd5b506102ee611240565b34801561052b57600080fd5b5061035a600f5481565b34801561054157600080fd5b50600354610404906001600160a01b031681565b34801561056157600080fd5b5061035a60065481565b34801561057757600080fd5b506102ee610586366004612ce2565b6114d6565b34801561059757600080fd5b506102ee6105a6366004612daf565b61154c565b3480156105b757600080fd5b50600154610404906001600160a01b031681565b3480156105d757600080fd5b5061035a600a5481565b3480156105ed57600080fd5b506106016105fc366004612c97565b61168a565b604080516001600160a01b0393841681529290911660208301520161031b565b34801561062d57600080fd5b50600454610404906001600160a01b031681565b34801561064d57600080fd5b5061069961065c366004612ce2565b6012602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e00161031b565b3480156106da57600080fd5b506102ee6106e9366004612c97565b6116c3565b3480156106fa57600080fd5b506102ee610709366004612e24565b61171c565b34801561071a57600080fd5b506102ee610729366004612c97565b6118b1565b34801561073a57600080fd5b5061030f610749366004612ce2565b61190a565b34801561075a57600080fd5b506102ee610769366004612c97565b6119d0565b34801561077a57600080fd5b5061035a60075481565b34801561079057600080fd5b5061030f61079f366004612ce2565b611cc8565b3480156107b057600080fd5b506107b9611d5c565b60405161031b9190612e46565b3480156107d257600080fd5b5061035a600c5481565b3480156107e857600080fd5b506102ee6107f7366004612c97565b611dcf565b34801561080857600080fd5b506102ee610817366004612c97565b611e28565b34801561082857600080fd5b5061035a600b5481565b34801561083e57600080fd5b5061035a61084d366004612ce2565b611e81565b34801561085e57600080fd5b506102ee61086d366004612c97565b6120d5565b34801561087e57600080fd5b506102ee61088d366004612c97565b61212e565b34801561089e57600080fd5b506102ee612187565b3480156108b357600080fd5b5061035a6121e7565b3480156108c857600080fd5b5061035a600d5481565b3480156108de57600080fd5b506102ee6108ed366004612c97565b612241565b6102ee61229a565b34801561090657600080fd5b5061091a610915366004612c97565b61236d565b6040805192835260208301919091520161031b565b34801561093b57600080fd5b506102ee61094a366004612e95565b61239b565b6002546001600160a01b031633148061097257506004546001600160a01b031633145b8061098757506003546001600160a01b031633145b6109ac5760405162461bcd60e51b81526004016109a390612ece565b60405180910390fd5b600d55565b6002546001600160a01b03163314806109d457506004546001600160a01b031633145b806109e957506003546001600160a01b031633145b610a055760405162461bcd60e51b81526004016109a390612ece565b600e8054911515620100000262ff000019909216919091179055565b6001600160a01b0381166000908152601260205260408120606091610a4584611e81565b600e54909150479060ff16610a76576040518060600160405280602881526020016130cd6028913995945050505050565b60075483541015610ac857600754610a9f90610a9a90670de0b6b3a7640000612413565b612428565b604051602001610aaf9190612f05565b6040516020818303038152906040529350505050919050565b6008548360010154610ada9190612f7f565b4211610afe57610af56008548460010154610a9a9190612f7f565b95945050505050565b6009548360020154610b109190612f7f565b4211610b2b57610af56009548460020154610a9a9190612f7f565b60008211610b55576040518060600160405280603281526020016130706032913995945050505050565b81811015610b7f576040518060600160405280602b81526020016130a2602b913995945050505050565b505060408051808201909152600f81526e596f752063616e20636c61696d202160881b60208201529392505050565b6002546001600160a01b0316331480610bd157506004546001600160a01b031633145b80610be657506003546001600160a01b031633145b610c025760405162461bcd60e51b81526004016109a390612ece565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331480610c4757506004546001600160a01b031633145b80610c5c57506003546001600160a01b031633145b610c785760405162461bcd60e51b81526004016109a390612ece565b4780610cbd5760405162461bcd60e51b81526020600482015260146024820152734e6f2066756e647320746f20776974686472617760601b60448201526064016109a3565b604051339082156108fc029083906000818181858888f19350505050158015610cea573d6000803e3d6000fd5b50610cf760106000612c0a565b506000601155565b60606000805b600554811015610dc35760058181548110610d2257610d22612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03868116600483015290911690636d8ea5b490602401602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9e9190612fa8565b15610db15781610dad81612fc5565b9250505b80610dbb81612fc5565b915050610d05565b5060008167ffffffffffffffff811115610ddf57610ddf612fde565b604051908082528060200260200182016040528015610e08578160200160208202803683370190505b5090506000805b600554811015610f2f5760058181548110610e2c57610e2c612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03888116600483015290911690636d8ea5b490602401602060405180830381865afa158015610e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea89190612fa8565b15610f1d5760058181548110610ec057610ec0612f92565b906000526020600020906002020160010160009054906101000a90046001600160a01b0316838381518110610ef757610ef7612f92565b6001600160a01b039092166020928302919091019091015281610f1981612fc5565b9250505b80610f2781612fc5565b915050610e0f565b5090949350505050565b610f416124bb565b33600090815260126020526040902081610f9d5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016109a3565b8054821115610fee5760405162461bcd60e51b815260206004820152601a60248201527f496e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016109a3565b8054610ffa9083612514565b8155600f546110099083612514565b600f5580546110945760038101805460009091554260028301554781158015906110335750818110155b80156110475750600e5462010000900460ff165b156110915761105582612520565b6003546040516001600160a01b039091169083156108fc029084906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b505b50505b60015460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612fa8565b61114d5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016109a3565b506111586001600055565b50565b6013818154811061116b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6002546001600160a01b03163314806111a857506004546001600160a01b031633145b806111bd57506003546001600160a01b031633145b6111d95760405162461bcd60e51b81526004016109a390612ece565b600a55565b6060601380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611218575b5050505050905090565b6112486124bb565b600e5460ff1661128f5760405162461bcd60e51b815260206004820152601260248201527121b630b4b6903737ba1032b730b13632b21760711b60448201526064016109a3565b336000908152601260205260409020600754815410156112fc5760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f75676820746f6b656e73207374616b656420746f20636c6169604482015261369760f11b60648201526084016109a3565b600854816001015461130e9190612f7f565b421161135c5760405162461bcd60e51b815260206004820152601a60248201527f4e65656420746f2077616974206166746572207374616b696e6700000000000060448201526064016109a3565b600954816002015461136e9190612f7f565b42116113bc5760405162461bcd60e51b815260206004820152601860248201527f416c726561647920636c61696d656420726563656e746c79000000000000000060448201526064016109a3565b6113c5336126a6565b60038101548061140e5760405162461bcd60e51b81526020600482015260146024820152734e6f207265776172647320617661696c61626c6560601b60448201526064016109a3565b478181101561145f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682045544820696e2074686520636f6e7472616374000060448201526064016109a3565b61146882612520565b60006003840155426002840155600483015461148490836128d1565b6004840155600d5461149690836128d1565b600d55604051339083156108fc029084906000818181858888f193505050501580156114c6573d6000803e3d6000fd5b505050506114d46001600055565b565b6002546001600160a01b03163314806114f957506004546001600160a01b031633145b8061150e57506003546001600160a01b031633145b61152a5760405162461bcd60e51b81526004016109a390612ece565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633148061156f57506004546001600160a01b031633145b8061158457506003546001600160a01b031633145b6115a05760405162461bcd60e51b81526004016109a390612ece565b60005b818110156116855760008383838181106115bf576115bf612f92565b90506020020160208101906115d49190612ce2565b604080518082019091526001600160a01b039182168082526020820190815260058054600181018255600091909152915160029092027f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0810180549385166001600160a01b031994851617905590517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db19091018054919093169116179055508061167d81612fc5565b9150506115a3565b505050565b6005818154811061169a57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692501682565b6002546001600160a01b03163314806116e657506004546001600160a01b031633145b806116fb57506003546001600160a01b031633145b6117175760405162461bcd60e51b81526004016109a390612ece565b600755565b6002546001600160a01b031633148061173f57506004546001600160a01b031633145b8061175457506003546001600160a01b031633145b6117705760405162461bcd60e51b81526004016109a390612ece565b6013548290821580159061178357508383115b1561178b5750815b6000825b8281101561183a57600060126000601384815481106117b0576117b0612f92565b60009182526020808320909101546001600160a01b031683528201929092526040019020600b546002820154919250906117ea9042612ff4565b1180156117fb575060008160030154115b156118275760038101546118109084906128d1565b600060038301554260028301819055600583015592505b508061183281612fc5565b91505061178f565b5047811580159061184b5750818110155b801561185f5750600e5462010000900460ff165b156118a95761186d82612520565b6003546040516001600160a01b039091169083156108fc029084906000818181858888f193505050501580156118a7573d6000803e3d6000fd5b505b505050505050565b6002546001600160a01b03163314806118d457506004546001600160a01b031633145b806118e957506003546001600160a01b031633145b6119055760405162461bcd60e51b81526004016109a390612ece565b600b55565b6000805b6005548110156119c7576005818154811061192b5761192b612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03858116600483015290911690636d8ea5b490602401602060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a79190612fa8565b156119b55750600192915050565b806119bf81612fc5565b91505061190e565b50600092915050565b6119d86124bb565b600e54610100900460ff16611a245760405162461bcd60e51b815260206004820152601260248201527129ba30b5b2903737ba1032b730b13632b21760711b60448201526064016109a3565b33600090815260126020526040902060065415611a99576006548154611a4b908490612f7f565b1115611a995760405162461bcd60e51b815260206004820152601860248201527f4d6178207374616b6520616d6f756e742072656163686564000000000000000060448201526064016109a3565b8060050154600003611aac574260058201555b8060060154600003611b00576013805460018101825560008290527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b031916331790555460068201555b600154604051636eb1769f60e11b81523360048201523060248201526000916001600160a01b03169063dd62ed3e90604401602060405180830381865afa158015611b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b739190613007565b905082811015611bd95760405162461bcd60e51b815260206004820152602b60248201527f416c6c6f77616e6365206973206e6f742073756666696369656e7420746f207360448201526a74616b6520746f6b656e7360a81b60648201526084016109a3565b4260018301558154611beb90846128d1565b8255600f54611bfa90846128d1565b600f556001546040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c789190612fa8565b611cbc5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016109a3565b50506111586001600055565b6001600160a01b038116600090815260126020526040812081611cea84611e81565b600e54909150479060ff168015611d015750600082115b8015611d0d5750818110155b8015611d1c5750600754835410155b8015611d3857506008548360010154611d359190612f7f565b42115b8015610af557506009548360020154611d519190612f7f565b421195945050505050565b60606010805480602002602001604051908101604052809291908181526020016000905b82821015611dc657838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611d80565b50505050905090565b6002546001600160a01b0316331480611df257506004546001600160a01b031633145b80611e0757506003546001600160a01b031633145b611e235760405162461bcd60e51b81526004016109a390612ece565b600c55565b6002546001600160a01b0316331480611e4b57506004546001600160a01b031633145b80611e6057506003546001600160a01b031633145b611e7c5760405162461bcd60e51b81526004016109a390612ece565b600655565b6001600160a01b038116600090815260126020526040812060075481541080611eaa5750600f54155b80611eb55750600a54155b15611ec4576003015492915050565b6000805b60105481101561203f5760108181548110611ee557611ee5612f92565b60009182526020909120600290910201541561202d576000611f2f846005015460108481548110611f1857611f18612f92565b9060005260206000209060020201600101546128dd565b90506000611f3d4283612514565b90506000600a548210611f595750670de0b6b3a7640000611f7b565b600a54611f7890611f7284670de0b6b3a76400006128f3565b90612413565b90505b600f548654600091611f9991611f7290670de0b6b3a76400006128f3565b90506000611fd7670de0b6b3a7640000611f728460108a81548110611fc057611fc0612f92565b6000918252602090912060029091020154906128f3565b9050611fef670de0b6b3a7640000611f7283866128f3565b9050611ffa8a61190a565b61201b576120186064611f72600c54846128f390919063ffffffff16565b90505b61202587826128d1565b965050505050505b8061203781612fc5565b915050611ec8565b50600f54825460009161205e91611f7290670de0b6b3a76400006128f3565b90506000612083670de0b6b3a7640000611f72846011546128f390919063ffffffff16565b905061208e8661190a565b6120af576120ac6064611f72600c54846128f390919063ffffffff16565b90505b6120b983826128d1565b60038501549093506120cb90846128d1565b9695505050505050565b6002546001600160a01b03163314806120f857506004546001600160a01b031633145b8061210d57506003546001600160a01b031633145b6121295760405162461bcd60e51b81526004016109a390612ece565b600855565b6002546001600160a01b031633148061215157506004546001600160a01b031633145b8061216657506003546001600160a01b031633145b6121825760405162461bcd60e51b81526004016109a390612ece565b600f55565b6002546001600160a01b03163314806121aa57506004546001600160a01b031633145b806121bf57506003546001600160a01b031633145b6121db5760405162461bcd60e51b81526004016109a390612ece565b6114d460056000612c2b565b601154600090815b60105481101561223b576122276010828154811061220f5761220f612f92565b600091825260209091206002909102015483906128d1565b91508061223381612fc5565b9150506121ef565b50919050565b6002546001600160a01b031633148061226457506004546001600160a01b031633145b8061227957506003546001600160a01b031633145b6122955760405162461bcd60e51b81526004016109a390612ece565b600955565b6002546001600160a01b03163314806122bd57506004546001600160a01b031633145b806122d257506003546001600160a01b031633145b6122ee5760405162461bcd60e51b81526004016109a390612ece565b6040805180820190915234815242602082019081526010805460018101825560009190915291517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672600290930292830155517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae673909101556114d46128ff565b6010818154811061237d57600080fd5b60009182526020909120600290910201805460019091015490915082565b6002546001600160a01b03163314806123be57506004546001600160a01b031633145b806123d357506003546001600160a01b031633145b6123ef5760405162461bcd60e51b81526004016109a390612ece565b600e805461ffff191692151561ff0019169290921761010091151591909102179055565b600061241f8284613020565b90505b92915050565b6060600061243583612b32565b600101905060008167ffffffffffffffff81111561245557612455612fde565b6040519080825280601f01601f19166020018201604052801561247f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461248957509392505050565b60026000540361250d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109a3565b6002600055565b600061241f8284612ff4565b8060005b601054811080156125355750600082115b15612655576010818154811061254d5761254d612f92565b60009182526020909120600290910201541561264357816010828154811061257757612577612f92565b906000526020600020906002020160000154116125ec576125bc601082815481106125a4576125a4612f92565b60009182526020909120600290910201548390612514565b9150601081815481106125d1576125d1612f92565b60009182526020822060029091020181815560010155612643565b61261a826010838154811061260357612603612f92565b600091825260209091206002909102015490612514565b6010828154811061262d5761262d612f92565b6000918252602082206002909102019190915591505b8061264d81612fc5565b915050612524565b5060008111801561266857506000601154115b156126a257806011541161268e57601154612684908290612514565b5050600060115550565b60115461269b9082612514565b6011555060005b5050565b6001600160a01b0381166000908152601260205260409020600754815410806126cf5750600f54155b806126da5750600a54155b156126e9574260059091015550565b6000805b601054811015612830576010818154811061270a5761270a612f92565b60009182526020909120600290910201541561281e57600061273d846005015460108481548110611f1857611f18612f92565b9050600061274b4283612514565b90506000600a5482106127675750670de0b6b3a7640000612783565b600a5461278090611f7284670de0b6b3a76400006128f3565b90505b600f5486546000916127a191611f7290670de0b6b3a76400006128f3565b905060006127c8670de0b6b3a7640000611f728460108a81548110611fc057611fc0612f92565b90506127e0670de0b6b3a7640000611f7283866128f3565b90506127eb8961190a565b61280c576128096064611f72600c54846128f390919063ffffffff16565b90505b61281687826128d1565b965050505050505b8061282881612fc5565b9150506126ed565b50600f54825460009161284f91611f7290670de0b6b3a76400006128f3565b90506000612874670de0b6b3a7640000611f72846011546128f390919063ffffffff16565b905061287f8561190a565b6128a05761289d6064611f72600c54846128f390919063ffffffff16565b90505b6128aa83826128d1565b60038501549093506128bc90846128d1565b60038501555050426005909201919091555050565b600061241f8284612f7f565b60008183116128ec578161241f565b5090919050565b600061241f8284613042565b60105460009067ffffffffffffffff81111561291d5761291d612fde565b60405190808252806020026020018201604052801561296257816020015b604080518082019091526000808252602082015281526020019060019003908161293b5790505b5090506000805b601054811015612a6e5760006129ac6010838154811061298b5761298b612f92565b9060005260206000209060020201600101544261251490919063ffffffff16565b9050600a5481106129ef576129e7601083815481106129cd576129cd612f92565b6000918252602090912060029091020154601154906128d1565b601155612a5b565b60108281548110612a0257612a02612f92565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050848481518110612a4157612a41612f92565b60200260200101819052508280612a5790612fc5565b9350505b5080612a6681612fc5565b915050612969565b508015612b265760105481146126a2575b601054811015612abd576010805480612a9a57612a9a613059565b600082815260208120600260001990930192830201818155600101559055612a7f565b60005b8181101561168557828181518110612ada57612ada612f92565b602002602001015160108281548110612af557612af5612f92565b6000918252602091829020835160029092020190815591015160019091015580612b1e81612fc5565b915050612ac0565b6126a260106000612c0a565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612b715772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612b9d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612bbb57662386f26fc10000830492506010015b6305f5e1008310612bd3576305f5e100830492506008015b6127108310612be757612710830492506004015b60648310612bf9576064830492506002015b600a83106124225760010192915050565b50805460008255600202906000526020600020908101906111589190612c4c565b50805460008255600202906000526020600020908101906111589190612c6b565b5b80821115612c675760008082556001820155600201612c4d565b5090565b5b80821115612c675780546001600160a01b031990811682556001820180549091169055600201612c6c565b600060208284031215612ca957600080fd5b5035919050565b801515811461115857600080fd5b600060208284031215612cd057600080fd5b8135612cdb81612cb0565b9392505050565b600060208284031215612cf457600080fd5b81356001600160a01b0381168114612cdb57600080fd5b60005b83811015612d26578181015183820152602001612d0e565b50506000910152565b6020815260008251806020840152612d4e816040850160208701612d0b565b601f01601f19169190910160400192915050565b6020808252825182820181905260009190848201906040850190845b81811015612da35783516001600160a01b031683529284019291840191600101612d7e565b50909695505050505050565b60008060208385031215612dc257600080fd5b823567ffffffffffffffff80821115612dda57600080fd5b818501915085601f830112612dee57600080fd5b813581811115612dfd57600080fd5b8660208260051b8501011115612e1257600080fd5b60209290920196919550909350505050565b60008060408385031215612e3757600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015612e8857815180518552860151868501529284019290850190600101612e63565b5091979650505050505050565b60008060408385031215612ea857600080fd5b8235612eb381612cb0565b91506020830135612ec381612cb0565b809150509250929050565b60208082526018908201527f4e6f742074686520726577617264732070726f76696465720000000000000000604082015260600190565b7f546f20626520656c696769626c652c20796f75206861766520746f207374616b81527503290309036b4b734b6bab690122920ab22a71037b3160551b602082015260008251612f5c816036850160208701612d0b565b9190910160360192915050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561242257612422612f69565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612fba57600080fd5b8151612cdb81612cb0565b600060018201612fd757612fd7612f69565b5060010190565b634e487b7160e01b600052604160045260246000fd5b8181038181111561242257612422612f69565b60006020828403121561301957600080fd5b5051919050565b60008261303d57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761242257612422612f69565b634e487b7160e01b600052603160045260246000fdfe596f7520646f6e2774206861766520616e792072657761726420746f20636c61696d20666f7220746865206d6f6d656e742e506c656173652077616974206e65772066756e647320746f20636c61696d20796f7572207265776172642e436c61696d206e6f7420656e61626c65642c20706c6561736520776169742061206d6f6d656e742ea2646970667358221220463e61b072c33ed4a9a28e4c1105f37aaf3388e461b4c09d9521770877557b3b64736f6c6343000813003300000000000000000000000043af0944b34ad466dcea7fc8f77aafc6a4ec70fa0000000000000000000000002604ac3e76d34728e2d8b2878ebaaa1936989b000000000000000000000000008892c1843e632b9649e0cc8ad09e26c0198f7e30

Deployed Bytecode

0x6080604052600436106102c95760003560e01c80638bd917fa11610175578063d244448c116100dc578063eec7810411610095578063f2d57adf1161006f578063f2d57adf146108d2578063f6326fb3146108f2578063fe4ce8d4146108fa578063ffebfd9a1461092f57600080fd5b8063eec7810414610892578063eef09740146108a7578063efca2eed146108bc57600080fd5b8063d244448c146107dc578063dcc2a55e146107fc578063e527f4801461081c578063e8f2f7f514610832578063ec3fe6b414610852578063ecc9747e1461087257600080fd5b8063a48bf0d11161012e578063a48bf0d11461072e578063a694fc3a1461074e578063adc25bde1461076e578063bf3506c114610784578063c44719a7146107a4578063c51af512146107c657600080fd5b80638bd917fa146105e15780638da5cb5b146106215780639168ae7214610641578063922fc248146106ce57806394f3177b146106ee578063a17936031461070e57600080fd5b80633ea0b6b311610234578063567e98f9116101ed5780635fa505f3116101c75780635fa505f31461056b5780636ad0530e1461058b57806372f702f3146105ab57806389a4b4b6146105cb57600080fd5b8063567e98f91461051f57806359927044146105355780635d80ca321461055557600080fd5b80633ea0b6b31461047f57806342d1456e1461049f578063459598a2146104b5578063485e670f146104d55780634ba3cef9146104f55780634e71d92d1461050a57600080fd5b806324600fc31161028657806324600fc3146103b557806328dae6e3146103ca5780632aea6f5d146103e45780632d7672111461041c5780632e1a7d4d146104495780633bbd1ed21461046957600080fd5b806302023e67146102ce5780630499de60146102f057806307ffd0f2146103245780630b433a12146103445780630d7731ad1461036857806313af403514610395575b600080fd5b3480156102da57600080fd5b506102ee6102e9366004612c97565b61094f565b005b3480156102fc57600080fd5b50600e5461030f90610100900460ff1681565b60405190151581526020015b60405180910390f35b34801561033057600080fd5b506102ee61033f366004612cbe565b6109b1565b34801561035057600080fd5b5061035a60095481565b60405190815260200161031b565b34801561037457600080fd5b50610388610383366004612ce2565b610a21565b60405161031b9190612d2f565b3480156103a157600080fd5b506102ee6103b0366004612ce2565b610bae565b3480156103c157600080fd5b506102ee610c24565b3480156103d657600080fd5b50600e5461030f9060ff1681565b3480156103f057600080fd5b50600254610404906001600160a01b031681565b6040516001600160a01b03909116815260200161031b565b34801561042857600080fd5b5061043c610437366004612ce2565b610cff565b60405161031b9190612d62565b34801561045557600080fd5b506102ee610464366004612c97565b610f39565b34801561047557600080fd5b5061035a60115481565b34801561048b57600080fd5b50600e5461030f9062010000900460ff1681565b3480156104ab57600080fd5b5061035a60085481565b3480156104c157600080fd5b506104046104d0366004612c97565b61115b565b3480156104e157600080fd5b506102ee6104f0366004612c97565b611185565b34801561050157600080fd5b5061043c6111de565b34801561051657600080fd5b506102ee611240565b34801561052b57600080fd5b5061035a600f5481565b34801561054157600080fd5b50600354610404906001600160a01b031681565b34801561056157600080fd5b5061035a60065481565b34801561057757600080fd5b506102ee610586366004612ce2565b6114d6565b34801561059757600080fd5b506102ee6105a6366004612daf565b61154c565b3480156105b757600080fd5b50600154610404906001600160a01b031681565b3480156105d757600080fd5b5061035a600a5481565b3480156105ed57600080fd5b506106016105fc366004612c97565b61168a565b604080516001600160a01b0393841681529290911660208301520161031b565b34801561062d57600080fd5b50600454610404906001600160a01b031681565b34801561064d57600080fd5b5061069961065c366004612ce2565b6012602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154949593949293919290919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e00161031b565b3480156106da57600080fd5b506102ee6106e9366004612c97565b6116c3565b3480156106fa57600080fd5b506102ee610709366004612e24565b61171c565b34801561071a57600080fd5b506102ee610729366004612c97565b6118b1565b34801561073a57600080fd5b5061030f610749366004612ce2565b61190a565b34801561075a57600080fd5b506102ee610769366004612c97565b6119d0565b34801561077a57600080fd5b5061035a60075481565b34801561079057600080fd5b5061030f61079f366004612ce2565b611cc8565b3480156107b057600080fd5b506107b9611d5c565b60405161031b9190612e46565b3480156107d257600080fd5b5061035a600c5481565b3480156107e857600080fd5b506102ee6107f7366004612c97565b611dcf565b34801561080857600080fd5b506102ee610817366004612c97565b611e28565b34801561082857600080fd5b5061035a600b5481565b34801561083e57600080fd5b5061035a61084d366004612ce2565b611e81565b34801561085e57600080fd5b506102ee61086d366004612c97565b6120d5565b34801561087e57600080fd5b506102ee61088d366004612c97565b61212e565b34801561089e57600080fd5b506102ee612187565b3480156108b357600080fd5b5061035a6121e7565b3480156108c857600080fd5b5061035a600d5481565b3480156108de57600080fd5b506102ee6108ed366004612c97565b612241565b6102ee61229a565b34801561090657600080fd5b5061091a610915366004612c97565b61236d565b6040805192835260208301919091520161031b565b34801561093b57600080fd5b506102ee61094a366004612e95565b61239b565b6002546001600160a01b031633148061097257506004546001600160a01b031633145b8061098757506003546001600160a01b031633145b6109ac5760405162461bcd60e51b81526004016109a390612ece565b60405180910390fd5b600d55565b6002546001600160a01b03163314806109d457506004546001600160a01b031633145b806109e957506003546001600160a01b031633145b610a055760405162461bcd60e51b81526004016109a390612ece565b600e8054911515620100000262ff000019909216919091179055565b6001600160a01b0381166000908152601260205260408120606091610a4584611e81565b600e54909150479060ff16610a76576040518060600160405280602881526020016130cd6028913995945050505050565b60075483541015610ac857600754610a9f90610a9a90670de0b6b3a7640000612413565b612428565b604051602001610aaf9190612f05565b6040516020818303038152906040529350505050919050565b6008548360010154610ada9190612f7f565b4211610afe57610af56008548460010154610a9a9190612f7f565b95945050505050565b6009548360020154610b109190612f7f565b4211610b2b57610af56009548460020154610a9a9190612f7f565b60008211610b55576040518060600160405280603281526020016130706032913995945050505050565b81811015610b7f576040518060600160405280602b81526020016130a2602b913995945050505050565b505060408051808201909152600f81526e596f752063616e20636c61696d202160881b60208201529392505050565b6002546001600160a01b0316331480610bd157506004546001600160a01b031633145b80610be657506003546001600160a01b031633145b610c025760405162461bcd60e51b81526004016109a390612ece565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b0316331480610c4757506004546001600160a01b031633145b80610c5c57506003546001600160a01b031633145b610c785760405162461bcd60e51b81526004016109a390612ece565b4780610cbd5760405162461bcd60e51b81526020600482015260146024820152734e6f2066756e647320746f20776974686472617760601b60448201526064016109a3565b604051339082156108fc029083906000818181858888f19350505050158015610cea573d6000803e3d6000fd5b50610cf760106000612c0a565b506000601155565b60606000805b600554811015610dc35760058181548110610d2257610d22612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03868116600483015290911690636d8ea5b490602401602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9e9190612fa8565b15610db15781610dad81612fc5565b9250505b80610dbb81612fc5565b915050610d05565b5060008167ffffffffffffffff811115610ddf57610ddf612fde565b604051908082528060200260200182016040528015610e08578160200160208202803683370190505b5090506000805b600554811015610f2f5760058181548110610e2c57610e2c612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03888116600483015290911690636d8ea5b490602401602060405180830381865afa158015610e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea89190612fa8565b15610f1d5760058181548110610ec057610ec0612f92565b906000526020600020906002020160010160009054906101000a90046001600160a01b0316838381518110610ef757610ef7612f92565b6001600160a01b039092166020928302919091019091015281610f1981612fc5565b9250505b80610f2781612fc5565b915050610e0f565b5090949350505050565b610f416124bb565b33600090815260126020526040902081610f9d5760405162461bcd60e51b815260206004820152601d60248201527f416d6f756e74206d7573742062652067726561746572207468616e203000000060448201526064016109a3565b8054821115610fee5760405162461bcd60e51b815260206004820152601a60248201527f496e73756666696369656e74207374616b656420616d6f756e7400000000000060448201526064016109a3565b8054610ffa9083612514565b8155600f546110099083612514565b600f5580546110945760038101805460009091554260028301554781158015906110335750818110155b80156110475750600e5462010000900460ff165b156110915761105582612520565b6003546040516001600160a01b039091169083156108fc029084906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b505b50505b60015460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156110e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111099190612fa8565b61114d5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016109a3565b506111586001600055565b50565b6013818154811061116b57600080fd5b6000918252602090912001546001600160a01b0316905081565b6002546001600160a01b03163314806111a857506004546001600160a01b031633145b806111bd57506003546001600160a01b031633145b6111d95760405162461bcd60e51b81526004016109a390612ece565b600a55565b6060601380548060200260200160405190810160405280929190818152602001828054801561123657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611218575b5050505050905090565b6112486124bb565b600e5460ff1661128f5760405162461bcd60e51b815260206004820152601260248201527121b630b4b6903737ba1032b730b13632b21760711b60448201526064016109a3565b336000908152601260205260409020600754815410156112fc5760405162461bcd60e51b815260206004820152602260248201527f4e6f7420656e6f75676820746f6b656e73207374616b656420746f20636c6169604482015261369760f11b60648201526084016109a3565b600854816001015461130e9190612f7f565b421161135c5760405162461bcd60e51b815260206004820152601a60248201527f4e65656420746f2077616974206166746572207374616b696e6700000000000060448201526064016109a3565b600954816002015461136e9190612f7f565b42116113bc5760405162461bcd60e51b815260206004820152601860248201527f416c726561647920636c61696d656420726563656e746c79000000000000000060448201526064016109a3565b6113c5336126a6565b60038101548061140e5760405162461bcd60e51b81526020600482015260146024820152734e6f207265776172647320617661696c61626c6560601b60448201526064016109a3565b478181101561145f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f7420656e6f7567682045544820696e2074686520636f6e7472616374000060448201526064016109a3565b61146882612520565b60006003840155426002840155600483015461148490836128d1565b6004840155600d5461149690836128d1565b600d55604051339083156108fc029084906000818181858888f193505050501580156114c6573d6000803e3d6000fd5b505050506114d46001600055565b565b6002546001600160a01b03163314806114f957506004546001600160a01b031633145b8061150e57506003546001600160a01b031633145b61152a5760405162461bcd60e51b81526004016109a390612ece565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031633148061156f57506004546001600160a01b031633145b8061158457506003546001600160a01b031633145b6115a05760405162461bcd60e51b81526004016109a390612ece565b60005b818110156116855760008383838181106115bf576115bf612f92565b90506020020160208101906115d49190612ce2565b604080518082019091526001600160a01b039182168082526020820190815260058054600181018255600091909152915160029092027f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0810180549385166001600160a01b031994851617905590517f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db19091018054919093169116179055508061167d81612fc5565b9150506115a3565b505050565b6005818154811061169a57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b0391821692501682565b6002546001600160a01b03163314806116e657506004546001600160a01b031633145b806116fb57506003546001600160a01b031633145b6117175760405162461bcd60e51b81526004016109a390612ece565b600755565b6002546001600160a01b031633148061173f57506004546001600160a01b031633145b8061175457506003546001600160a01b031633145b6117705760405162461bcd60e51b81526004016109a390612ece565b6013548290821580159061178357508383115b1561178b5750815b6000825b8281101561183a57600060126000601384815481106117b0576117b0612f92565b60009182526020808320909101546001600160a01b031683528201929092526040019020600b546002820154919250906117ea9042612ff4565b1180156117fb575060008160030154115b156118275760038101546118109084906128d1565b600060038301554260028301819055600583015592505b508061183281612fc5565b91505061178f565b5047811580159061184b5750818110155b801561185f5750600e5462010000900460ff165b156118a95761186d82612520565b6003546040516001600160a01b039091169083156108fc029084906000818181858888f193505050501580156118a7573d6000803e3d6000fd5b505b505050505050565b6002546001600160a01b03163314806118d457506004546001600160a01b031633145b806118e957506003546001600160a01b031633145b6119055760405162461bcd60e51b81526004016109a390612ece565b600b55565b6000805b6005548110156119c7576005818154811061192b5761192b612f92565b6000918252602090912060029091020154604051631b63a96d60e21b81526001600160a01b03858116600483015290911690636d8ea5b490602401602060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119a79190612fa8565b156119b55750600192915050565b806119bf81612fc5565b91505061190e565b50600092915050565b6119d86124bb565b600e54610100900460ff16611a245760405162461bcd60e51b815260206004820152601260248201527129ba30b5b2903737ba1032b730b13632b21760711b60448201526064016109a3565b33600090815260126020526040902060065415611a99576006548154611a4b908490612f7f565b1115611a995760405162461bcd60e51b815260206004820152601860248201527f4d6178207374616b6520616d6f756e742072656163686564000000000000000060448201526064016109a3565b8060050154600003611aac574260058201555b8060060154600003611b00576013805460018101825560008290527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b031916331790555460068201555b600154604051636eb1769f60e11b81523360048201523060248201526000916001600160a01b03169063dd62ed3e90604401602060405180830381865afa158015611b4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b739190613007565b905082811015611bd95760405162461bcd60e51b815260206004820152602b60248201527f416c6c6f77616e6365206973206e6f742073756666696369656e7420746f207360448201526a74616b6520746f6b656e7360a81b60648201526084016109a3565b4260018301558154611beb90846128d1565b8255600f54611bfa90846128d1565b600f556001546040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015611c54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c789190612fa8565b611cbc5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016109a3565b50506111586001600055565b6001600160a01b038116600090815260126020526040812081611cea84611e81565b600e54909150479060ff168015611d015750600082115b8015611d0d5750818110155b8015611d1c5750600754835410155b8015611d3857506008548360010154611d359190612f7f565b42115b8015610af557506009548360020154611d519190612f7f565b421195945050505050565b60606010805480602002602001604051908101604052809291908181526020016000905b82821015611dc657838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611d80565b50505050905090565b6002546001600160a01b0316331480611df257506004546001600160a01b031633145b80611e0757506003546001600160a01b031633145b611e235760405162461bcd60e51b81526004016109a390612ece565b600c55565b6002546001600160a01b0316331480611e4b57506004546001600160a01b031633145b80611e6057506003546001600160a01b031633145b611e7c5760405162461bcd60e51b81526004016109a390612ece565b600655565b6001600160a01b038116600090815260126020526040812060075481541080611eaa5750600f54155b80611eb55750600a54155b15611ec4576003015492915050565b6000805b60105481101561203f5760108181548110611ee557611ee5612f92565b60009182526020909120600290910201541561202d576000611f2f846005015460108481548110611f1857611f18612f92565b9060005260206000209060020201600101546128dd565b90506000611f3d4283612514565b90506000600a548210611f595750670de0b6b3a7640000611f7b565b600a54611f7890611f7284670de0b6b3a76400006128f3565b90612413565b90505b600f548654600091611f9991611f7290670de0b6b3a76400006128f3565b90506000611fd7670de0b6b3a7640000611f728460108a81548110611fc057611fc0612f92565b6000918252602090912060029091020154906128f3565b9050611fef670de0b6b3a7640000611f7283866128f3565b9050611ffa8a61190a565b61201b576120186064611f72600c54846128f390919063ffffffff16565b90505b61202587826128d1565b965050505050505b8061203781612fc5565b915050611ec8565b50600f54825460009161205e91611f7290670de0b6b3a76400006128f3565b90506000612083670de0b6b3a7640000611f72846011546128f390919063ffffffff16565b905061208e8661190a565b6120af576120ac6064611f72600c54846128f390919063ffffffff16565b90505b6120b983826128d1565b60038501549093506120cb90846128d1565b9695505050505050565b6002546001600160a01b03163314806120f857506004546001600160a01b031633145b8061210d57506003546001600160a01b031633145b6121295760405162461bcd60e51b81526004016109a390612ece565b600855565b6002546001600160a01b031633148061215157506004546001600160a01b031633145b8061216657506003546001600160a01b031633145b6121825760405162461bcd60e51b81526004016109a390612ece565b600f55565b6002546001600160a01b03163314806121aa57506004546001600160a01b031633145b806121bf57506003546001600160a01b031633145b6121db5760405162461bcd60e51b81526004016109a390612ece565b6114d460056000612c2b565b601154600090815b60105481101561223b576122276010828154811061220f5761220f612f92565b600091825260209091206002909102015483906128d1565b91508061223381612fc5565b9150506121ef565b50919050565b6002546001600160a01b031633148061226457506004546001600160a01b031633145b8061227957506003546001600160a01b031633145b6122955760405162461bcd60e51b81526004016109a390612ece565b600955565b6002546001600160a01b03163314806122bd57506004546001600160a01b031633145b806122d257506003546001600160a01b031633145b6122ee5760405162461bcd60e51b81526004016109a390612ece565b6040805180820190915234815242602082019081526010805460018101825560009190915291517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672600290930292830155517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae673909101556114d46128ff565b6010818154811061237d57600080fd5b60009182526020909120600290910201805460019091015490915082565b6002546001600160a01b03163314806123be57506004546001600160a01b031633145b806123d357506003546001600160a01b031633145b6123ef5760405162461bcd60e51b81526004016109a390612ece565b600e805461ffff191692151561ff0019169290921761010091151591909102179055565b600061241f8284613020565b90505b92915050565b6060600061243583612b32565b600101905060008167ffffffffffffffff81111561245557612455612fde565b6040519080825280601f01601f19166020018201604052801561247f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461248957509392505050565b60026000540361250d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016109a3565b6002600055565b600061241f8284612ff4565b8060005b601054811080156125355750600082115b15612655576010818154811061254d5761254d612f92565b60009182526020909120600290910201541561264357816010828154811061257757612577612f92565b906000526020600020906002020160000154116125ec576125bc601082815481106125a4576125a4612f92565b60009182526020909120600290910201548390612514565b9150601081815481106125d1576125d1612f92565b60009182526020822060029091020181815560010155612643565b61261a826010838154811061260357612603612f92565b600091825260209091206002909102015490612514565b6010828154811061262d5761262d612f92565b6000918252602082206002909102019190915591505b8061264d81612fc5565b915050612524565b5060008111801561266857506000601154115b156126a257806011541161268e57601154612684908290612514565b5050600060115550565b60115461269b9082612514565b6011555060005b5050565b6001600160a01b0381166000908152601260205260409020600754815410806126cf5750600f54155b806126da5750600a54155b156126e9574260059091015550565b6000805b601054811015612830576010818154811061270a5761270a612f92565b60009182526020909120600290910201541561281e57600061273d846005015460108481548110611f1857611f18612f92565b9050600061274b4283612514565b90506000600a5482106127675750670de0b6b3a7640000612783565b600a5461278090611f7284670de0b6b3a76400006128f3565b90505b600f5486546000916127a191611f7290670de0b6b3a76400006128f3565b905060006127c8670de0b6b3a7640000611f728460108a81548110611fc057611fc0612f92565b90506127e0670de0b6b3a7640000611f7283866128f3565b90506127eb8961190a565b61280c576128096064611f72600c54846128f390919063ffffffff16565b90505b61281687826128d1565b965050505050505b8061282881612fc5565b9150506126ed565b50600f54825460009161284f91611f7290670de0b6b3a76400006128f3565b90506000612874670de0b6b3a7640000611f72846011546128f390919063ffffffff16565b905061287f8561190a565b6128a05761289d6064611f72600c54846128f390919063ffffffff16565b90505b6128aa83826128d1565b60038501549093506128bc90846128d1565b60038501555050426005909201919091555050565b600061241f8284612f7f565b60008183116128ec578161241f565b5090919050565b600061241f8284613042565b60105460009067ffffffffffffffff81111561291d5761291d612fde565b60405190808252806020026020018201604052801561296257816020015b604080518082019091526000808252602082015281526020019060019003908161293b5790505b5090506000805b601054811015612a6e5760006129ac6010838154811061298b5761298b612f92565b9060005260206000209060020201600101544261251490919063ffffffff16565b9050600a5481106129ef576129e7601083815481106129cd576129cd612f92565b6000918252602090912060029091020154601154906128d1565b601155612a5b565b60108281548110612a0257612a02612f92565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050848481518110612a4157612a41612f92565b60200260200101819052508280612a5790612fc5565b9350505b5080612a6681612fc5565b915050612969565b508015612b265760105481146126a2575b601054811015612abd576010805480612a9a57612a9a613059565b600082815260208120600260001990930192830201818155600101559055612a7f565b60005b8181101561168557828181518110612ada57612ada612f92565b602002602001015160108281548110612af557612af5612f92565b6000918252602091829020835160029092020190815591015160019091015580612b1e81612fc5565b915050612ac0565b6126a260106000612c0a565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310612b715772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310612b9d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612bbb57662386f26fc10000830492506010015b6305f5e1008310612bd3576305f5e100830492506008015b6127108310612be757612710830492506004015b60648310612bf9576064830492506002015b600a83106124225760010192915050565b50805460008255600202906000526020600020908101906111589190612c4c565b50805460008255600202906000526020600020908101906111589190612c6b565b5b80821115612c675760008082556001820155600201612c4d565b5090565b5b80821115612c675780546001600160a01b031990811682556001820180549091169055600201612c6c565b600060208284031215612ca957600080fd5b5035919050565b801515811461115857600080fd5b600060208284031215612cd057600080fd5b8135612cdb81612cb0565b9392505050565b600060208284031215612cf457600080fd5b81356001600160a01b0381168114612cdb57600080fd5b60005b83811015612d26578181015183820152602001612d0e565b50506000910152565b6020815260008251806020840152612d4e816040850160208701612d0b565b601f01601f19169190910160400192915050565b6020808252825182820181905260009190848201906040850190845b81811015612da35783516001600160a01b031683529284019291840191600101612d7e565b50909695505050505050565b60008060208385031215612dc257600080fd5b823567ffffffffffffffff80821115612dda57600080fd5b818501915085601f830112612dee57600080fd5b813581811115612dfd57600080fd5b8660208260051b8501011115612e1257600080fd5b60209290920196919550909350505050565b60008060408385031215612e3757600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015612e8857815180518552860151868501529284019290850190600101612e63565b5091979650505050505050565b60008060408385031215612ea857600080fd5b8235612eb381612cb0565b91506020830135612ec381612cb0565b809150509250929050565b60208082526018908201527f4e6f742074686520726577617264732070726f76696465720000000000000000604082015260600190565b7f546f20626520656c696769626c652c20796f75206861766520746f207374616b81527503290309036b4b734b6bab690122920ab22a71037b3160551b602082015260008251612f5c816036850160208701612d0b565b9190910160360192915050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561242257612422612f69565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612fba57600080fd5b8151612cdb81612cb0565b600060018201612fd757612fd7612f69565b5060010190565b634e487b7160e01b600052604160045260246000fd5b8181038181111561242257612422612f69565b60006020828403121561301957600080fd5b5051919050565b60008261303d57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761242257612422612f69565b634e487b7160e01b600052603160045260246000fdfe596f7520646f6e2774206861766520616e792072657761726420746f20636c61696d20666f7220746865206d6f6d656e742e506c656173652077616974206e65772066756e647320746f20636c61696d20796f7572207265776172642e436c61696d206e6f7420656e61626c65642c20706c6561736520776169742061206d6f6d656e742ea2646970667358221220463e61b072c33ed4a9a28e4c1105f37aaf3388e461b4c09d9521770877557b3b64736f6c63430008130033

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

00000000000000000000000043af0944b34ad466dcea7fc8f77aafc6a4ec70fa0000000000000000000000002604ac3e76d34728e2d8b2878ebaaa1936989b000000000000000000000000008892c1843e632b9649e0cc8ad09e26c0198f7e30

-----Decoded View---------------
Arg [0] : _stakingToken (address): 0x43aF0944b34ad466DceA7FC8f77AAfc6a4Ec70fa
Arg [1] : _rewardsProvider (address): 0x2604ac3e76d34728e2d8b2878EBAAA1936989B00
Arg [2] : _teamWallet (address): 0x8892C1843e632B9649e0cC8AD09E26c0198f7e30

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000043af0944b34ad466dcea7fc8f77aafc6a4ec70fa
Arg [1] : 0000000000000000000000002604ac3e76d34728e2d8b2878ebaaa1936989b00
Arg [2] : 0000000000000000000000008892c1843e632b9649e0cc8ad09e26c0198f7e30


Deployed Bytecode Sourcemap

61706:18035:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79513:110;;;;;;;;;;-1:-1:-1;79513:110:0;;;;;:::i;:::-;;:::i;:::-;;62455:31;;;;;;;;;;-1:-1:-1;62455:31:0;;;;;;;;;;;;;;364:14:1;;357:22;339:41;;327:2;312:18;62455:31:0;;;;;;;;79631:107;;;;;;;;;;-1:-1:-1;79631:107:0;;;;;:::i;:::-;;:::i;62182:39::-;;;;;;;;;;;;;;;;;;;906:25:1;;;894:2;879:18;62182:39:0;760:177:1;66027:1172:0;;;;;;;;;;-1:-1:-1;66027:1172:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;78527:96::-;;;;;;;;;;-1:-1:-1;78527:96:0;;;;;:::i;:::-;;:::i;73905:279::-;;;;;;;;;;;;;:::i;62417:31::-;;;;;;;;;;-1:-1:-1;62417:31:0;;;;;;;;61826:30;;;;;;;;;;-1:-1:-1;61826:30:0;;;;-1:-1:-1;;;;;61826:30:0;;;;;;-1:-1:-1;;;;;2053:32:1;;;2035:51;;2023:2;2008:18;61826:30:0;1889:203:1;76931:691:0;;;;;;;;;;-1:-1:-1;76931:691:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;64582:936::-;;;;;;;;;;-1:-1:-1;64582:936:0;;;;;:::i;:::-;;:::i;62956:36::-;;;;;;;;;;;;;;;;62493:35;;;;;;;;;;-1:-1:-1;62493:35:0;;;;;;;;;;;62136:39;;;;;;;;;;;;;;;;63053:32;;;;;;;;;;-1:-1:-1;63053:32:0;;;;;:::i;:::-;;:::i;79123:118::-;;;;;;;;;;-1:-1:-1;79123:118:0;;;;;:::i;:::-;;:::i;75240:107::-;;;;;;;;;;;;;:::i;67207:1044::-;;;;;;;;;;;;;:::i;62797:32::-;;;;;;;;;;;;;;;;61863:25;;;;;;;;;;-1:-1:-1;61863:25:0;;;;-1:-1:-1;;;;;61863:25:0;;;62045:33;;;;;;;;;;;;;;;;78397:122;;;;;;;;;;-1:-1:-1;78397:122:0;;;;;:::i;:::-;;:::i;77727:391::-;;;;;;;;;;-1:-1:-1;77727:391:0;;;;;:::i;:::-;;:::i;61793:26::-;;;;;;;;;;-1:-1:-1;61793:26:0;;;;-1:-1:-1;;;;;61793:26:0;;;62228:41;;;;;;;;;;;;;;;;61922:27;;;;;;;;;;-1:-1:-1;61922:27:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3872:15:1;;;3854:34;;3924:15;;;;3919:2;3904:18;;3897:43;3789:18;61922:27:0;3603:343:1;61895:20:0;;;;;;;;;;-1:-1:-1;61895:20:0;;;;-1:-1:-1;;;;;61895:20:0;;;63001:45;;;;;;;;;;-1:-1:-1;63001:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4266:25:1;;;4322:2;4307:18;;4300:34;;;;4350:18;;;4343:34;;;;4408:2;4393:18;;4386:34;;;;4451:3;4436:19;;4429:35;4495:3;4480:19;;4473:35;4539:3;4524:19;;4517:35;4253:3;4238:19;63001:45:0;3951:607:1;78755:116:0;;;;;;;;;;-1:-1:-1;78755:116:0;;;;;:::i;:::-;;:::i;74192:1040::-;;;;;;;;;;-1:-1:-1;74192:1040:0;;;;;:::i;:::-;;:::i;79381:124::-;;;;;;;;;;-1:-1:-1;79381:124:0;;;;;:::i;:::-;;:::i;76647:276::-;;;;;;;;;;-1:-1:-1;76647:276:0;;;;;:::i;:::-;;:::i;63535:1039::-;;;;;;;;;;-1:-1:-1;63535:1039:0;;;;;:::i;:::-;;:::i;62085:44::-;;;;;;;;;;;;;;;;65526:493;;;;;;;;;;-1:-1:-1;65526:493:0;;;;;:::i;:::-;;:::i;75355:107::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;62327:39::-;;;;;;;;;;;;;;;;79249:124;;;;;;;;;;-1:-1:-1;79249:124:0;;;;;:::i;:::-;;:::i;78631:116::-;;;;;;;;;;-1:-1:-1;78631:116:0;;;;;:::i;:::-;;:::i;62276:44::-;;;;;;;;;;;;;;;;68259:2002;;;;;;;;;;-1:-1:-1;68259:2002:0;;;;;:::i;:::-;;:::i;78879:110::-;;;;;;;;;;-1:-1:-1;78879:110:0;;;;;:::i;:::-;;:::i;78267:122::-;;;;;;;;;;-1:-1:-1;78267:122:0;;;;;:::i;:::-;;:::i;77630:89::-;;;;;;;;;;;;;:::i;73359:309::-;;;;;;;;;;;;;:::i;62373:35::-;;;;;;;;;;;;;;;;78997:118;;;;;;;;;;-1:-1:-1;78997:118:0;;;;;:::i;:::-;;:::i;73676:221::-;;;:::i;62922:27::-;;;;;;;;;;-1:-1:-1;62922:27:0;;;;;:::i;:::-;;:::i;:::-;;;;5779:25:1;;;5835:2;5820:18;;5813:34;;;;5752:18;62922:27:0;5605:248:1;78126:133:0;;;;;;;;;;-1:-1:-1;78126:133:0;;;;;:::i;:::-;;:::i;79513:110::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;;;;;;;;;79594:16:::1;:21:::0;79513:110::o;79631:107::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;79709:16:::1;:21:::0;;;::::1;;::::0;::::1;-1:-1:-1::0;;79709:21:0;;::::1;::::0;;;::::1;::::0;;79631:107::o;66027:1172::-;-1:-1:-1;;;;;66146:22:0;;66118:25;66146:22;;;:7;:22;;;;;66092:13;;66196:35;66154:13;66196:20;:35::i;:::-;66305:11;;66179:52;;-1:-1:-1;66268:21:0;;66305:11;;66300:93;;66332:49;;;;;;;;;;;;;;;;;;66027:1172;-1:-1:-1;;;;;66027:1172:0:o;66300:93::-;66429:14;;66407:19;;:36;66403:205;;;66566:14;;66549:45;;66566:27;;66585:7;66566:18;:27::i;:::-;66549:16;:45::i;:::-;66474:121;;;;;;;;:::i;:::-;;;;;;;;;;;;;66460:136;;;;;66027:1172;;;:::o;66403:205::-;66664:13;;66641:6;:20;;;:36;;;;:::i;:::-;66622:15;:55;66618:149;;66701:54;66741:13;;66718:6;:20;;;:36;;;;:::i;66701:54::-;66694:61;66027:1172;-1:-1:-1;;;;;66027:1172:0:o;66618:149::-;66823:13;;66800:6;:20;;;:36;;;;:::i;:::-;66781:15;:55;66777:149;;66860:54;66900:13;;66877:6;:20;;;:36;;;;:::i;66777:149::-;66950:1;66940:6;:11;66936:102;;66967:59;;;;;;;;;;;;;;;;;;66027:1172;-1:-1:-1;;;;;66027:1172:0:o;66936:102::-;67070:6;67052:15;:24;67048:109;;;67093:52;;;;;;;;;;;;;;;;;;66027:1172;-1:-1:-1;;;;;66027:1172:0:o;67048:109::-;-1:-1:-1;;67167:24:0;;;;;;;;;;;;-1:-1:-1;;;67167:24:0;;;;;66027:1172;-1:-1:-1;;;66027:1172:0:o;78527:96::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78601:5:::1;:14:::0;;-1:-1:-1;;;;;;78601:14:0::1;-1:-1:-1::0;;;;;78601:14:0;;;::::1;::::0;;;::::1;::::0;;78527:96::o;73905:279::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;73988:21:::1;74028:11:::0;74020:44:::1;;;::::0;-1:-1:-1;;;74020:44:0;;7578:2:1;74020:44:0::1;::::0;::::1;7560:21:1::0;7617:2;7597:18;;;7590:30;-1:-1:-1;;;7636:18:1;;;7629:50;7696:18;;74020:44:0::1;7376:344:1::0;74020:44:0::1;74075:37;::::0;74083:10:::1;::::0;74075:37;::::1;;;::::0;74104:7;;74075:37:::1;::::0;;;74104:7;74083:10;74075:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;74125:19:0::1;74132:12;;74125:19;:::i;:::-;-1:-1:-1::0;74175:1:0::1;74155:17;:21:::0;73905:279::o;76931:691::-;76994:16;77023:19;77062:9;77057:172;77081:10;:17;77077:21;;77057:172;;;77124:10;77135:1;77124:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;:44;;-1:-1:-1;;;77124:44:0;;-1:-1:-1;;;;;2053:32:1;;;77124:44:0;;;2035:51:1;77124:22:0;;;;:37;;2008:18:1;;77124:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77120:98;;;77189:13;;;;:::i;:::-;;;;77120:98;77100:3;;;;:::i;:::-;;;;77057:172;;;;77239:37;77293:11;77279:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77279:26:0;;77239:66;;77318:9;77347;77342:233;77366:10;:17;77362:21;;77342:233;;;77409:10;77420:1;77409:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;:44;;-1:-1:-1;;;77409:44:0;;-1:-1:-1;;;;;2053:32:1;;;77409:44:0;;;2035:51:1;77409:22:0;;;;:37;;2008:18:1;;77409:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77405:159;;;77508:10;77519:1;77508:13;;;;;;;;:::i;:::-;;;;;;;;;;;:17;;;;;;;;;;-1:-1:-1;;;;;77508:17:0;77474:20;77495:1;77474:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;77474:52:0;;;:23;;;;;;;;;;;:52;77545:3;;;;:::i;:::-;;;;77405:159;77385:3;;;;:::i;:::-;;;;77342:233;;;-1:-1:-1;77594:20:0;;76931:691;-1:-1:-1;;;;76931:691:0:o;64582:936::-;45034:21;:19;:21::i;:::-;64685:10:::1;64649:25;64677:19:::0;;;:7:::1;:19;::::0;;;;64717:10;64709:52:::1;;;::::0;-1:-1:-1;;;64709:52:0;;8581:2:1;64709:52:0::1;::::0;::::1;8563:21:1::0;8620:2;8600:18;;;8593:30;8659:31;8639:18;;;8632:59;8708:18;;64709:52:0::1;8379:353:1::0;64709:52:0::1;64780:19:::0;;:29;-1:-1:-1;64780:29:0::1;64772:68;;;::::0;-1:-1:-1;;;64772:68:0;;8939:2:1;64772:68:0::1;::::0;::::1;8921:21:1::0;8978:2;8958:18;;;8951:30;9017:28;8997:18;;;8990:56;9063:18;;64772:68:0::1;8737:350:1::0;64772:68:0::1;64875:19:::0;;:31:::1;::::0;64899:6;64875:23:::1;:31::i;:::-;64853:53:::0;;64937:17:::1;::::0;:29:::1;::::0;64959:6;64937:21:::1;:29::i;:::-;64917:17;:49:::0;64983:19;;64979:444:::1;;65041:20;::::0;::::1;::::0;;65024:14:::1;65076:24:::0;;;65138:15:::1;65115:20;::::0;::::1;:38:::0;65194:21:::1;65234:10:::0;;;;;:39:::1;;;65267:6;65248:15;:25;;65234:39;:59;;;;-1:-1:-1::0;65277:16:0::1;::::0;;;::::1;;;65234:59;65230:182;;;65313:26;65332:6;65313:18;:26::i;:::-;65368:10;::::0;65360:36:::1;::::0;-1:-1:-1;;;;;65368:10:0;;::::1;::::0;65360:36;::::1;;;::::0;65389:6;;65368:10:::1;65360:36:::0;65368:10;65360:36;65389:6;65368:10;65360:36;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;65230:182;65009:414;;64979:444;65443:12;::::0;:41:::1;::::0;-1:-1:-1;;;65443:41:0;;65465:10:::1;65443:41;::::0;::::1;9266:51:1::0;9333:18;;;9326:34;;;-1:-1:-1;;;;;65443:12:0;;::::1;::::0;:21:::1;::::0;9239:18:1;;65443:41:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65435:75;;;::::0;-1:-1:-1;;;65435:75:0;;9573:2:1;65435:75:0::1;::::0;::::1;9555:21:1::0;9612:2;9592:18;;;9585:30;-1:-1:-1;;;9631:18:1;;;9624:51;9692:18;;65435:75:0::1;9371:345:1::0;65435:75:0::1;64638:880;45078:20:::0;44472:1;45598:7;:22;45415:213;45078:20;64582:936;:::o;63053:32::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63053:32:0;;-1:-1:-1;63053:32:0;:::o;79123:118::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;79208:17:::1;:25:::0;79123:118::o;75240:107::-;75288:16;75324:15;75317:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;75317:22:0;;;;;;;;;;;;;;;;;;;;;;;75240:107;:::o;67207:1044::-;45034:21;:19;:21::i;:::-;67265:11:::1;::::0;::::1;;67257:42;;;::::0;-1:-1:-1;;;67257:42:0;;9923:2:1;67257:42:0::1;::::0;::::1;9905:21:1::0;9962:2;9942:18;;;9935:30;-1:-1:-1;;;9981:18:1;;;9974:48;10039:18;;67257:42:0::1;9721:342:1::0;67257:42:0::1;67346:10;67310:25;67338:19:::0;;;:7:::1;:19;::::0;;;;67399:14:::1;::::0;67376:19;;:37:::1;;67368:84;;;::::0;-1:-1:-1;;;67368:84:0;;10270:2:1;67368:84:0::1;::::0;::::1;10252:21:1::0;10309:2;10289:18;;;10282:30;10348:34;10328:18;;;10321:62;-1:-1:-1;;;10399:18:1;;;10392:32;10441:19;;67368:84:0::1;10068:398:1::0;67368:84:0::1;67512:13;;67489:6;:20;;;:36;;;;:::i;:::-;67471:15;:54;67463:93;;;::::0;-1:-1:-1;;;67463:93:0;;10673:2:1;67463:93:0::1;::::0;::::1;10655:21:1::0;10712:2;10692:18;;;10685:30;10751:28;10731:18;;;10724:56;10797:18;;67463:93:0::1;10471:350:1::0;67463:93:0::1;67616:13;;67593:6;:20;;;:36;;;;:::i;:::-;67575:15;:54;67567:91;;;::::0;-1:-1:-1;;;67567:91:0;;11028:2:1;67567:91:0::1;::::0;::::1;11010:21:1::0;11067:2;11047:18;;;11040:30;11106:26;11086:18;;;11079:54;11150:18;;67567:91:0::1;10826:348:1::0;67567:91:0::1;67671:31;67691:10;67671:19;:31::i;:::-;67732:20;::::0;::::1;::::0;67771:10;67763:43:::1;;;::::0;-1:-1:-1;;;67763:43:0;;11381:2:1;67763:43:0::1;::::0;::::1;11363:21:1::0;11420:2;11400:18;;;11393:30;-1:-1:-1;;;11439:18:1;;;11432:50;11499:18;;67763:43:0::1;11179:344:1::0;67763:43:0::1;67845:21;67885:25:::0;;::::1;;67877:68;;;::::0;-1:-1:-1;;;67877:68:0;;11730:2:1;67877:68:0::1;::::0;::::1;11712:21:1::0;11769:2;11749:18;;;11742:30;11808:32;11788:18;;;11781:60;11858:18;;67877:68:0::1;11528:354:1::0;67877:68:0::1;67958:26;67977:6;67958:18;:26::i;:::-;68018:1;67995:20;::::0;::::1;:24:::0;68053:15:::1;68030:20;::::0;::::1;:38:::0;68103:21:::1;::::0;::::1;::::0;:33:::1;::::0;68129:6;68103:25:::1;:33::i;:::-;68079:21;::::0;::::1;:57:::0;68166:16:::1;::::0;:28:::1;::::0;68187:6;68166:20:::1;:28::i;:::-;68147:16;:47:::0;68207:36:::1;::::0;68215:10:::1;::::0;68207:36;::::1;;;::::0;68236:6;;68207:36:::1;::::0;;;68236:6;68215:10;68207:36;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;67246:1005;;;45078:20:::0;44472:1;45598:7;:22;45415:213;45078:20;67207:1044::o;78397:122::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78484:15:::1;:27:::0;;-1:-1:-1;;;;;;78484:27:0::1;-1:-1:-1::0;;;;;78484:27:0;;;::::1;::::0;;;::::1;::::0;;78397:122::o;77727:391::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;77833:6:::1;77828:283;77845:19:::0;;::::1;77828:283;;;77886:21;77910:8;;77919:1;77910:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;;;;;;;;;;77970:45:0;;::::1;::::0;;;-1:-1:-1;;;78030:33:0;;;78078:10:::1;:21:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;78078:21:0;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;-1:-1:-1::0;;;;;;78078:21:0;;::::1;;::::0;;;;;;;;;;;;;::::1;::::0;::::1;;::::0;;-1:-1:-1;77866:3:0;::::1;::::0;::::1;:::i;:::-;;;;77828:283;;;;77727:391:::0;;:::o;61922:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61922:27:0;;;;-1:-1:-1;61922:27:0;;:::o;78755:116::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78839:14:::1;:24:::0;78755:116::o;74192:1040::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;74341:15:::1;:22:::0;74305:10;;74378:13;;;;;:39:::1;;;74407:10;74395:9;:22;74378:39;74374:87;;;-1:-1:-1::0;74440:9:0;74374:87:::1;74471:19;74522:6:::0;74505:480:::1;74534:4;74530:1;:8;74505:480;;;74560:25;74588:7;:27;74596:15;74612:1;74596:18;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;74596:18:0::1;74588:27:::0;;;::::1;::::0;;;;;;;;74675:19:::1;::::0;74652:20:::1;::::0;::::1;::::0;74588:27;;-1:-1:-1;74675:19:0;74634:38:::1;::::0;:15:::1;:38;:::i;:::-;:60;:88;;;;;74721:1;74698:6;:20;;;:24;74634:88;74630:344;;;74773:20;::::0;::::1;::::0;74757:37:::1;::::0;:11;;:15:::1;:37::i;:::-;74836:1;74813:20;::::0;::::1;:24:::0;74879:15:::1;74856:20;::::0;::::1;:38:::0;;;74913:27:::1;::::0;::::1;:45:::0;74743:51;-1:-1:-1;74630:344:0::1;-1:-1:-1::0;74540:3:0;::::1;::::0;::::1;:::i;:::-;;;;74505:480;;;-1:-1:-1::0;75013:21:0::1;75049:15:::0;;;;;:41:::1;;;75079:11;75068:7;:22;;75049:41;:61;;;;-1:-1:-1::0;75094:16:0::1;::::0;;;::::1;;;75049:61;75045:180;;;75126:31;75145:11;75126:18;:31::i;:::-;75180:10;::::0;75172:41:::1;::::0;-1:-1:-1;;;;;75180:10:0;;::::1;::::0;75172:41;::::1;;;::::0;75201:11;;75180:10:::1;75172:41:::0;75180:10;75172:41;75201:11;75180:10;75172:41;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;75045:180;74277:955;;;;74192:1040:::0;;:::o;79381:124::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;79469:19:::1;:28:::0;79381:124::o;76647:276::-;76706:4;;76723:170;76747:10;:17;76743:21;;76723:170;;;76790:10;76801:1;76790:13;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;:44;;-1:-1:-1;;;76790:44:0;;-1:-1:-1;;;;;2053:32:1;;;76790:44:0;;;2035:51:1;76790:22:0;;;;:37;;2008:18:1;;76790:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76786:96;;;-1:-1:-1;76862:4:0;;76647:276;-1:-1:-1;;76647:276:0:o;76786:96::-;76766:3;;;;:::i;:::-;;;;76723:170;;;-1:-1:-1;76910:5:0;;76647:276;-1:-1:-1;;76647:276:0:o;63535:1039::-;45034:21;:19;:21::i;:::-;63607:11:::1;::::0;::::1;::::0;::::1;;;63599:42;;;::::0;-1:-1:-1;;;63599:42:0;;12222:2:1;63599:42:0::1;::::0;::::1;12204:21:1::0;12261:2;12241:18;;;12234:30;-1:-1:-1;;;12280:18:1;;;12273:48;12338:18;;63599:42:0::1;12020:342:1::0;63599:42:0::1;63688:10;63652:25;63680:19:::0;;;:7:::1;:19;::::0;;;;63714:14:::1;::::0;:18;63710:134:::1;;63789:14;::::0;63757:19;;:28:::1;::::0;63779:6;;63757:28:::1;:::i;:::-;:46;;63749:83;;;::::0;-1:-1:-1;;;63749:83:0;;12569:2:1;63749:83:0::1;::::0;::::1;12551:21:1::0;12608:2;12588:18;;;12581:30;12647:26;12627:18;;;12620:54;12691:18;;63749:83:0::1;12367:348:1::0;63749:83:0::1;63860:6;:27;;;63891:1;63860:32:::0;63856:110:::1;;63939:15;63909:27;::::0;::::1;:45:::0;63856:110:::1;63982:6;:15;;;64001:1;63982:20:::0;63978:139:::1;;64018:15;:32:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;64018:32:0;;;;::::1;::::0;;-1:-1:-1;;;;;;64018:32:0::1;64039:10;64018:32;::::0;;64083:22;64065:15:::1;::::0;::::1;:40:::0;63978:139:::1;64149:12;::::0;:49:::1;::::0;-1:-1:-1;;;64149:49:0;;64172:10:::1;64149:49;::::0;::::1;3854:34:1::0;64192:4:0::1;3904:18:1::0;;;3897:43;64129:17:0::1;::::0;-1:-1:-1;;;;;64149:12:0::1;::::0;:22:::1;::::0;3789:18:1;;64149:49:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64129:69;;64230:6;64217:9;:19;;64209:75;;;::::0;-1:-1:-1;;;64209:75:0;;13420:2:1;64209:75:0::1;::::0;::::1;13402:21:1::0;13459:2;13439:18;;;13432:30;13498:34;13478:18;;;13471:62;-1:-1:-1;;;13549:18:1;;;13542:41;13600:19;;64209:75:0::1;13218:407:1::0;64209:75:0::1;64320:15;64297:20;::::0;::::1;:38:::0;64368:19;;:31:::1;::::0;64392:6;64368:23:::1;:31::i;:::-;64346:53:::0;;64430:17:::1;::::0;:29:::1;::::0;64452:6;64430:21:::1;:29::i;:::-;64410:17;:49:::0;64480:12:::1;::::0;:60:::1;::::0;-1:-1:-1;;;64480:60:0;;64506:10:::1;64480:60;::::0;::::1;13870:34:1::0;64526:4:0::1;13920:18:1::0;;;13913:43;13972:18;;;13965:34;;;-1:-1:-1;;;;;64480:12:0;;::::1;::::0;:25:::1;::::0;13805:18:1;;64480:60:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64472:94;;;::::0;-1:-1:-1;;;64472:94:0;;9573:2:1;64472:94:0::1;::::0;::::1;9555:21:1::0;9612:2;9592:18;;;9585:30;-1:-1:-1;;;9631:18:1;;;9624:51;9692:18;;64472:94:0::1;9371:345:1::0;64472:94:0::1;63588:986;;45078:20:::0;44472:1;45598:7;:22;45415:213;65526:493;-1:-1:-1;;;;;65633:22:0;;65588:4;65633:22;;;:7;:22;;;;;65588:4;65683:35;65641:13;65683:20;:35::i;:::-;65794:11;;65666:52;;-1:-1:-1;65755:21:0;;65794:11;;:25;;;;;65818:1;65809:6;:10;65794:25;:54;;;;;65842:6;65823:15;:25;;65794:54;:97;;;;-1:-1:-1;65876:14:0;;65853:19;;:37;;65794:97;:157;;;;;65937:13;;65914:6;:20;;;:36;;;;:::i;:::-;65896:15;:54;65794:157;:217;;;;;65997:13;;65974:6;:20;;;:36;;;;:::i;:::-;65956:15;:54;65787:224;65526:493;-1:-1:-1;;;;;65526:493:0:o;75355:107::-;75408:14;75442:12;75435:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75355:107;:::o;79249:124::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;79337:19:::1;:28:::0;79249:124::o;78631:116::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78715:14:::1;:24:::0;78631:116::o;68259:2002::-;-1:-1:-1;;;;;68381:22:0;;68333:7;68381:22;;;:7;:22;;;;;68442:14;;68420:19;;:36;;:62;;-1:-1:-1;68460:17:0;;:22;68420:62;:88;;;-1:-1:-1;68486:17:0;;:22;68420:88;68416:148;;;68532:20;;;;68259:2002;-1:-1:-1;;68259:2002:0:o;68416:148::-;68576:19;68614:9;68610:1104;68633:12;:19;68629:23;;68610:1104;;;68678:12;68691:1;68678:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;68674:76;68726:8;68674:76;68764:21;68788:61;68792:6;:27;;;68821:12;68834:1;68821:15;;;;;;;;:::i;:::-;;;;;;;;;;;:27;;;68788:3;:61::i;:::-;68764:85;-1:-1:-1;68864:19:0;68886:34;:15;68764:85;68886:19;:34::i;:::-;68864:56;;68949:18;69000:17;;68985:11;:32;68982:193;;-1:-1:-1;69051:7:0;68982:193;;;69141:17;;69112:47;;:24;:11;69128:7;69112:15;:24::i;:::-;:28;;:47::i;:::-;69099:60;;68982:193;69262:17;;69225:19;;69203;;69225:55;;:32;;69249:7;69225:23;:32::i;:55::-;69203:77;;69295:29;69327:52;69371:7;69327:39;69354:11;69327:12;69340:1;69327:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;;:26;:39::i;:52::-;69295:84;-1:-1:-1;69418:50:0;69460:7;69418:37;69295:84;69444:10;69418:25;:37::i;:50::-;69394:74;;69490:28;69504:13;69490;:28::i;:::-;69485:149;;69563:55;69614:3;69563:46;69589:19;;69563:21;:25;;:46;;;;:::i;:55::-;69539:79;;69485:149;69664:38;:11;69680:21;69664:15;:38::i;:::-;69650:52;;68659:1055;;;;;68610:1104;68654:3;;;;:::i;:::-;;;;68610:1104;;;-1:-1:-1;69852:17:0;;69815:19;;69777:35;;69815:55;;:32;;69839:7;69815:23;:32::i;:55::-;69777:93;;69881:30;69914:63;69969:7;69914:50;69936:27;69914:17;;:21;;:50;;;;:::i;:63::-;69881:96;;69993:28;70007:13;69993;:28::i;:::-;69988:143;;70063:56;70115:3;70063:47;70090:19;;70063:22;:26;;:47;;;;:::i;:56::-;70038:81;;69988:143;70157:39;:11;70173:22;70157:15;:39::i;:::-;70216:20;;;;70143:53;;-1:-1:-1;70216:37:0;;70143:53;70216:24;:37::i;:::-;70209:44;68259:2002;-1:-1:-1;;;;;;68259:2002:0:o;78879:110::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78960:13:::1;:21:::0;78879:110::o;78267:122::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78354:17:::1;:27:::0;78267:122::o;77630:89::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;77694:17:::1;77701:10;;77694:17;:::i;73359:309::-:0;73461:17;;73416:7;;;73491:136;73515:12;:19;73511:23;;73491:136;;;73573:42;73592:12;73605:1;73592:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;73573:14;;:18;:42::i;:::-;73556:59;-1:-1:-1;73536:3:0;;;;:::i;:::-;;;;73491:136;;;-1:-1:-1;73646:14:0;73359:309;-1:-1:-1;73359:309:0:o;78997:118::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;79082:13:::1;:25:::0;78997:118::o;73676:221::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;73764:93:::1;::::0;;;;::::1;::::0;;;73793:9:::1;73764:93:::0;;73830:15:::1;73764:93;::::0;::::1;::::0;;;73746:12:::1;:112:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;73746:112:0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;73871:18:::1;:16;:18::i;62922:27::-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62922:27:0;:::o;78126:133::-;63412:15;;-1:-1:-1;;;;;63412:15:0;63398:10;:29;;:52;;-1:-1:-1;63445:5:0;;-1:-1:-1;;;;;63445:5:0;63431:10;:19;63398:52;:80;;;-1:-1:-1;63468:10:0;;-1:-1:-1;;;;;63468:10:0;63454;:24;63398:80;63390:117;;;;-1:-1:-1;;;63390:117:0;;;;;;;:::i;:::-;78208:11:::1;:16:::0;;-1:-1:-1;;78235:16:0;78208;::::1;;-1:-1:-1::0;;78235:16:0;;;;;78208::::1;78235::::0;::::1;;::::0;;;::::1;;::::0;;78126:133::o;49942:98::-;50000:7;50027:5;50031:1;50027;:5;:::i;:::-;50020:12;;49942:98;;;;;:::o;15202:716::-;15258:13;15309:14;15326:17;15337:5;15326:10;:17::i;:::-;15346:1;15326:21;15309:38;;15362:20;15396:6;15385:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15385:18:0;-1:-1:-1;15362:41:0;-1:-1:-1;15527:28:0;;;15543:2;15527:28;15584:288;-1:-1:-1;;15616:5:0;-1:-1:-1;;;15753:2:0;15742:14;;15737:30;15616:5;15724:44;15814:2;15805:11;;;-1:-1:-1;15835:21:0;15584:288;15835:21;-1:-1:-1;15893:6:0;15202:716;-1:-1:-1;;;15202:716:0:o;45114:293::-;44516:1;45248:7;;:19;45240:63;;;;-1:-1:-1;;;45240:63:0;;14566:2:1;45240:63:0;;;14548:21:1;14605:2;14585:18;;;14578:30;14644:33;14624:18;;;14617:61;14695:18;;45240:63:0;14364:355:1;45240:63:0;44516:1;45381:7;:18;45114:293::o;49186:98::-;49244:7;49271:5;49275:1;49271;:5;:::i;75584:1055::-;75675:6;75647:25;75692:532;75716:12;:19;75712:23;;:48;;;;;75759:1;75739:17;:21;75712:48;75692:532;;;75786:12;75799:1;75786:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;75782:76;75834:8;75782:76;75902:17;75876:12;75889:1;75876:15;;;;;;;;:::i;:::-;;;;;;;;;;;:22;;;:43;75872:341;;75960:45;75982:12;75995:1;75982:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;75960:17;;:21;:45::i;:::-;75940:65;;76031:12;76044:1;76031:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;76024:22;;;;;;75872:341;;;76112:45;76139:17;76112:12;76125:1;76112:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;;:26;:45::i;:::-;76087:12;76100:1;76087:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;:70;;;;:15;-1:-1:-1;75872:341:0;75762:3;;;;:::i;:::-;;;;75692:532;;;;76258:1;76238:17;:21;:46;;;;;76283:1;76263:17;;:21;76238:46;76234:398;;;76326:17;76305;;:38;76301:320;;76406:17;;76384:40;;:17;;:21;:40::i;:::-;-1:-1:-1;;76463:1:0;76443:17;:21;-1:-1:-1;75584:1055:0:o;76301:320::-;76525:17;;:40;;76547:17;76525:21;:40::i;:::-;76505:17;:60;-1:-1:-1;76604:1:0;76301:320;75636:1003;75584:1055;:::o;70269:2087::-;-1:-1:-1;;;;;70369:22:0;;70341:25;70369:22;;;:7;:22;;;;;70430:14;;70408:19;;:36;;:62;;-1:-1:-1;70448:17:0;;:22;70408:62;:88;;;-1:-1:-1;70474:17:0;;:22;70408:88;70404:187;;;70543:15;70513:27;;;;:45;-1:-1:-1;70269:2087:0:o;70404:187::-;70603:19;70641:9;70637:1104;70660:12;:19;70656:23;;70637:1104;;;70705:12;70718:1;70705:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;70701:76;70753:8;70701:76;70791:21;70815:61;70819:6;:27;;;70848:12;70861:1;70848:15;;;;;;;;:::i;70815:61::-;70791:85;-1:-1:-1;70891:19:0;70913:34;:15;70791:85;70913:19;:34::i;:::-;70891:56;;70976:18;71027:17;;71012:11;:32;71009:193;;-1:-1:-1;71078:7:0;71009:193;;;71168:17;;71139:47;;:24;:11;71155:7;71139:15;:24::i;:47::-;71126:60;;71009:193;71289:17;;71252:19;;71230;;71252:55;;:32;;71276:7;71252:23;:32::i;:55::-;71230:77;;71322:29;71354:52;71398:7;71354:39;71381:11;71354:12;71367:1;71354:15;;;;;;;;:::i;:52::-;71322:84;-1:-1:-1;71445:50:0;71487:7;71445:37;71322:84;71471:10;71445:25;:37::i;:50::-;71421:74;;71517:28;71531:13;71517;:28::i;:::-;71512:149;;71590:55;71641:3;71590:46;71616:19;;71590:21;:25;;:46;;;;:::i;:55::-;71566:79;;71512:149;71691:38;:11;71707:21;71691:15;:38::i;:::-;71677:52;;70686:1055;;;;;70637:1104;70681:3;;;;:::i;:::-;;;;70637:1104;;;-1:-1:-1;71879:17:0;;71842:19;;71804:35;;71842:55;;:32;;71866:7;71842:23;:32::i;:55::-;71804:93;;71908:30;71941:63;71996:7;71941:50;71963:27;71941:17;;:21;;:50;;;;:::i;:63::-;71908:96;;72020:28;72034:13;72020;:28::i;:::-;72015:143;;72090:56;72142:3;72090:47;72117:19;;72090:22;:26;;:47;;;;:::i;:56::-;72065:81;;72015:143;72182:39;:11;72198:22;72182:15;:39::i;:::-;72255:20;;;;72168:53;;-1:-1:-1;72255:37:0;;72168:53;72255:24;:37::i;:::-;72232:20;;;:60;-1:-1:-1;;72333:15:0;72303:27;;;;:45;;;;-1:-1:-1;;70269:2087:0:o;48805:98::-;48863:7;48890:5;48894:1;48890;:5;:::i;75470:106::-;75528:7;75559:1;75555;:5;:13;;75567:1;75555:13;;;-1:-1:-1;75563:1:0;;75470:106;-1:-1:-1;75470:106:0:o;49543:98::-;49601:7;49628:5;49632:1;49628;:5;:::i;72364:987::-;72456:12;:19;72411:30;;72444:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;72444:32:0;;;;;;;;;;;;;;;;72411:65;;72489:13;72522:9;72517:406;72541:12;:19;72537:23;;72517:406;;;72582:19;72604:48;72624:12;72637:1;72624:15;;;;;;;;:::i;:::-;;;;;;;;;;;:27;;;72604:15;:19;;:48;;;;:::i;:::-;72582:70;;72686:17;;72671:11;:32;72667:245;;72744:45;72766:12;72779:1;72766:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;:22;72744:17;;;:21;:45::i;:::-;72724:17;:65;72667:245;;;72855:12;72868:1;72855:15;;;;;;;;:::i;:::-;;;;;;;;;;;72830:40;;;;;;;;;;;;;;;;;;;;;;;;;:15;72846:5;72830:22;;;;;;;;:::i;:::-;;;;;;:40;;;;72889:7;;;;;:::i;:::-;;;;72667:245;-1:-1:-1;72562:3:0;;;;:::i;:::-;;;;72517:406;;;-1:-1:-1;72939:9:0;;72935:409;;72969:12;:19;:28;;72965:316;;73018:97;73025:12;:19;:27;-1:-1:-1;73018:97:0;;;73077:12;:18;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;73077:18:0;;;;;;;;;;;;;;;73018:97;;;73156:9;73151:115;73175:5;73171:1;:9;73151:115;;;73228:15;73244:1;73228:18;;;;;;;;:::i;:::-;;;;;;;73210:12;73223:1;73210:15;;;;;;;;:::i;:::-;;;;;;;;;;:36;;:15;;;;;:36;;;;;;;;;;;73182:3;;;;:::i;:::-;;;;73151:115;;72935:409;73313:19;73320:12;;73313:19;:::i;12036:948::-;12089:7;;-1:-1:-1;;;12167:17:0;;12163:106;;-1:-1:-1;;;12205:17:0;;;-1:-1:-1;12251:2:0;12241:12;12163:106;12296:8;12287:5;:17;12283:106;;12334:8;12325:17;;;-1:-1:-1;12371:2:0;12361:12;12283:106;12416:8;12407:5;:17;12403:106;;12454:8;12445:17;;;-1:-1:-1;12491:2:0;12481:12;12403:106;12536:7;12527:5;:16;12523:103;;12573:7;12564:16;;;-1:-1:-1;12609:1:0;12599:11;12523:103;12653:7;12644:5;:16;12640:103;;12690:7;12681:16;;;-1:-1:-1;12726:1:0;12716:11;12640:103;12770:7;12761:5;:16;12757:103;;12807:7;12798:16;;;-1:-1:-1;12843:1:0;12833:11;12757:103;12887:7;12878:5;:16;12874:68;;12925:1;12915:11;12970:6;12036:948;-1:-1:-1;;12036:948:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:180:1;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;391:118::-;477:5;470:13;463:21;456:5;453:32;443:60;;499:1;496;489:12;514:241;570:6;623:2;611:9;602:7;598:23;594:32;591:52;;;639:1;636;629:12;591:52;678:9;665:23;697:28;719:5;697:28;:::i;:::-;744:5;514:241;-1:-1:-1;;;514:241:1:o;942:286::-;1001:6;1054:2;1042:9;1033:7;1029:23;1025:32;1022:52;;;1070:1;1067;1060:12;1022:52;1096:23;;-1:-1:-1;;;;;1148:31:1;;1138:42;;1128:70;;1194:1;1191;1184:12;1233:250;1318:1;1328:113;1342:6;1339:1;1336:13;1328:113;;;1418:11;;;1412:18;1399:11;;;1392:39;1364:2;1357:10;1328:113;;;-1:-1:-1;;1475:1:1;1457:16;;1450:27;1233:250::o;1488:396::-;1637:2;1626:9;1619:21;1600:4;1669:6;1663:13;1712:6;1707:2;1696:9;1692:18;1685:34;1728:79;1800:6;1795:2;1784:9;1780:18;1775:2;1767:6;1763:15;1728:79;:::i;:::-;1868:2;1847:15;-1:-1:-1;;1843:29:1;1828:45;;;;1875:2;1824:54;;1488:396;-1:-1:-1;;1488:396:1:o;2097:658::-;2268:2;2320:21;;;2390:13;;2293:18;;;2412:22;;;2239:4;;2268:2;2491:15;;;;2465:2;2450:18;;;2239:4;2534:195;2548:6;2545:1;2542:13;2534:195;;;2613:13;;-1:-1:-1;;;;;2609:39:1;2597:52;;2704:15;;;;2669:12;;;;2645:1;2563:9;2534:195;;;-1:-1:-1;2746:3:1;;2097:658;-1:-1:-1;;;;;;2097:658:1:o;2760:615::-;2846:6;2854;2907:2;2895:9;2886:7;2882:23;2878:32;2875:52;;;2923:1;2920;2913:12;2875:52;2963:9;2950:23;2992:18;3033:2;3025:6;3022:14;3019:34;;;3049:1;3046;3039:12;3019:34;3087:6;3076:9;3072:22;3062:32;;3132:7;3125:4;3121:2;3117:13;3113:27;3103:55;;3154:1;3151;3144:12;3103:55;3194:2;3181:16;3220:2;3212:6;3209:14;3206:34;;;3236:1;3233;3226:12;3206:34;3289:7;3284:2;3274:6;3271:1;3267:14;3263:2;3259:23;3255:32;3252:45;3249:65;;;3310:1;3307;3300:12;3249:65;3341:2;3333:11;;;;;3363:6;;-1:-1:-1;2760:615:1;;-1:-1:-1;;;;2760:615:1:o;4563:248::-;4631:6;4639;4692:2;4680:9;4671:7;4667:23;4663:32;4660:52;;;4708:1;4705;4698:12;4660:52;-1:-1:-1;;4731:23:1;;;4801:2;4786:18;;;4773:32;;-1:-1:-1;4563:248:1:o;4816:784::-;5033:2;5085:21;;;5155:13;;5058:18;;;5177:22;;;5004:4;;5033:2;5218;;5236:18;;;;5277:15;;;5004:4;5320:254;5334:6;5331:1;5328:13;5320:254;;;5393:13;;5431:9;;5419:22;;5481:11;;5475:18;5461:12;;;5454:40;5514:12;;;;5549:15;;;;5356:1;5349:9;5320:254;;;-1:-1:-1;5591:3:1;;4816:784;-1:-1:-1;;;;;;;4816:784:1:o;5858:376::-;5920:6;5928;5981:2;5969:9;5960:7;5956:23;5952:32;5949:52;;;5997:1;5994;5987:12;5949:52;6036:9;6023:23;6055:28;6077:5;6055:28;:::i;:::-;6102:5;-1:-1:-1;6159:2:1;6144:18;;6131:32;6172:30;6131:32;6172:30;:::i;:::-;6221:7;6211:17;;;5858:376;;;;;:::o;6239:348::-;6441:2;6423:21;;;6480:2;6460:18;;;6453:30;6519:26;6514:2;6499:18;;6492:54;6578:2;6563:18;;6239:348::o;6592:517::-;6854:34;6849:3;6842:47;-1:-1:-1;;;6914:2:1;6909:3;6905:12;6898:46;6824:3;6973:6;6967:13;6989:73;7055:6;7050:2;7045:3;7041:12;7036:2;7028:6;7024:15;6989:73;:::i;:::-;7082:16;;;;7100:2;7078:25;;6592:517;-1:-1:-1;;6592:517:1:o;7114:127::-;7175:10;7170:3;7166:20;7163:1;7156:31;7206:4;7203:1;7196:15;7230:4;7227:1;7220:15;7246:125;7311:9;;;7332:10;;;7329:36;;;7345:18;;:::i;7725:127::-;7786:10;7781:3;7777:20;7774:1;7767:31;7817:4;7814:1;7807:15;7841:4;7838:1;7831:15;7857:245;7924:6;7977:2;7965:9;7956:7;7952:23;7948:32;7945:52;;;7993:1;7990;7983:12;7945:52;8025:9;8019:16;8044:28;8066:5;8044:28;:::i;8107:135::-;8146:3;8167:17;;;8164:43;;8187:18;;:::i;:::-;-1:-1:-1;8234:1:1;8223:13;;8107:135::o;8247:127::-;8308:10;8303:3;8299:20;8296:1;8289:31;8339:4;8336:1;8329:15;8363:4;8360:1;8353:15;11887:128;11954:9;;;11975:11;;;11972:37;;;11989:18;;:::i;13029:184::-;13099:6;13152:2;13140:9;13131:7;13127:23;13123:32;13120:52;;;13168:1;13165;13158:12;13120:52;-1:-1:-1;13191:16:1;;13029:184;-1:-1:-1;13029:184:1:o;14142:217::-;14182:1;14208;14198:132;;14252:10;14247:3;14243:20;14240:1;14233:31;14287:4;14284:1;14277:15;14315:4;14312:1;14305:15;14198:132;-1:-1:-1;14344:9:1;;14142:217::o;14724:168::-;14797:9;;;14828;;14845:15;;;14839:22;;14825:37;14815:71;;14866:18;;:::i;14897:127::-;14958:10;14953:3;14949:20;14946:1;14939:31;14989:4;14986:1;14979:15;15013:4;15010:1;15003:15

Swarm Source

ipfs://463e61b072c33ed4a9a28e4c1105f37aaf3388e461b4c09d9521770877557b3b

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.