ETH Price: $2,419.57 (+0.02%)

Contract

0x48D93d8C45Fb25125F13cdd40529BbeaA97A6565
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit188263552023-12-20 9:53:59291 days ago1703066039IN
Liquid Collective: River Implementation v1.0.1
0.01 ETH0.0070942863.93032524
0x60806040177205482023-07-18 13:56:23445 days ago1689688583IN
 Create: RiverV1
0 ETH0.1597306329.83022803

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RiverV1

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 10 runs

Other Settings:
default evmVersion, BSL 1.1 license
File 1 of 60 : River.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "./interfaces/IAllowlist.1.sol";
import "./interfaces/IOperatorRegistry.1.sol";
import "./interfaces/IRiver.1.sol";
import "./interfaces/IWithdraw.1.sol";
import "./interfaces/IELFeeRecipient.1.sol";
import "./interfaces/ICoverageFund.1.sol";

import "./components/ConsensusLayerDepositManager.1.sol";
import "./components/UserDepositManager.1.sol";
import "./components/SharesManager.1.sol";
import "./components/OracleManager.1.sol";
import "./Initializable.sol";
import "./Administrable.sol";

import "./libraries/LibAllowlistMasks.sol";

import "./state/river/AllowlistAddress.sol";
import "./state/river/RedeemManagerAddress.sol";
import "./state/river/OperatorsRegistryAddress.sol";
import "./state/river/CollectorAddress.sol";
import "./state/river/ELFeeRecipientAddress.sol";
import "./state/river/CoverageFundAddress.sol";
import "./state/river/BalanceToRedeem.sol";
import "./state/river/GlobalFee.sol";
import "./state/river/MetadataURI.sol";
import "./state/river/LastConsensusLayerReport.sol";

/// @title River (v1)
/// @author Kiln
/// @notice This contract merges all the manager contracts and implements all the virtual methods stitching all components together
contract RiverV1 is
    ConsensusLayerDepositManagerV1,
    UserDepositManagerV1,
    SharesManagerV1,
    OracleManagerV1,
    Initializable,
    Administrable,
    IRiverV1
{
    /// @inheritdoc IRiverV1
    function initRiverV1(
        address _depositContractAddress,
        address _elFeeRecipientAddress,
        bytes32 _withdrawalCredentials,
        address _oracleAddress,
        address _systemAdministratorAddress,
        address _allowlistAddress,
        address _operatorRegistryAddress,
        address _collectorAddress,
        uint256 _globalFee
    ) external init(0) {
        _setAdmin(_systemAdministratorAddress);

        CollectorAddress.set(_collectorAddress);
        emit SetCollector(_collectorAddress);

        GlobalFee.set(_globalFee);
        emit SetGlobalFee(_globalFee);

        ELFeeRecipientAddress.set(_elFeeRecipientAddress);
        emit SetELFeeRecipient(_elFeeRecipientAddress);

        AllowlistAddress.set(_allowlistAddress);
        emit SetAllowlist(_allowlistAddress);

        OperatorsRegistryAddress.set(_operatorRegistryAddress);
        emit SetOperatorsRegistry(_operatorRegistryAddress);

        ConsensusLayerDepositManagerV1.initConsensusLayerDepositManagerV1(
            _depositContractAddress, _withdrawalCredentials
        );

        OracleManagerV1.initOracleManagerV1(_oracleAddress);
    }

    /// @inheritdoc IRiverV1
    function initRiverV1_1(
        address _redeemManager,
        uint64 _epochsPerFrame,
        uint64 _slotsPerEpoch,
        uint64 _secondsPerSlot,
        uint64 _genesisTime,
        uint64 _epochsToAssumedFinality,
        uint256 _annualAprUpperBound,
        uint256 _relativeLowerBound,
        uint128 _minDailyNetCommittableAmount_,
        uint128 _maxDailyRelativeCommittableAmount_
    ) external init(1) {
        RedeemManagerAddress.set(_redeemManager);
        emit SetRedeemManager(_redeemManager);

        _setDailyCommittableLimits(
            DailyCommittableLimits.DailyCommittableLimitsStruct({
                minDailyNetCommittableAmount: _minDailyNetCommittableAmount_,
                maxDailyRelativeCommittableAmount: _maxDailyRelativeCommittableAmount_
            })
        );

        initOracleManagerV1_1(
            _epochsPerFrame,
            _slotsPerEpoch,
            _secondsPerSlot,
            _genesisTime,
            _epochsToAssumedFinality,
            _annualAprUpperBound,
            _relativeLowerBound
        );

        _approve(address(this), _redeemManager, type(uint256).max);
    }

    /// @inheritdoc IRiverV1
    function initRiverV1_2() external init(2) {
        // force committed balance to a multiple of 32 ETH and
        // move extra funds back to the deposit buffer
        uint256 dustToUncommit = CommittedBalance.get() % DEPOSIT_SIZE;
        _setCommittedBalance(CommittedBalance.get() - dustToUncommit);
        _setBalanceToDeposit(BalanceToDeposit.get() + dustToUncommit);
    }

    /// @inheritdoc IRiverV1
    function getGlobalFee() external view returns (uint256) {
        return GlobalFee.get();
    }

    /// @inheritdoc IRiverV1
    function getAllowlist() external view returns (address) {
        return AllowlistAddress.get();
    }

    /// @inheritdoc IRiverV1
    function getCollector() external view returns (address) {
        return CollectorAddress.get();
    }

    /// @inheritdoc IRiverV1
    function getELFeeRecipient() external view returns (address) {
        return ELFeeRecipientAddress.get();
    }

    /// @inheritdoc IRiverV1
    function getCoverageFund() external view returns (address) {
        return CoverageFundAddress.get();
    }

    /// @inheritdoc IRiverV1
    function getRedeemManager() external view returns (address) {
        return RedeemManagerAddress.get();
    }

    /// @inheritdoc IRiverV1
    function getMetadataURI() external view returns (string memory) {
        return MetadataURI.get();
    }

    /// @inheritdoc IRiverV1
    function getDailyCommittableLimits()
        external
        view
        returns (DailyCommittableLimits.DailyCommittableLimitsStruct memory)
    {
        return DailyCommittableLimits.get();
    }

    /// @inheritdoc IRiverV1
    function setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl)
        external
        onlyAdmin
    {
        _setDailyCommittableLimits(_dcl);
    }

    /// @inheritdoc IRiverV1
    function getBalanceToRedeem() external view returns (uint256) {
        return BalanceToRedeem.get();
    }

    /// @inheritdoc IRiverV1
    function resolveRedeemRequests(uint32[] calldata _redeemRequestIds)
        external
        view
        returns (int64[] memory withdrawalEventIds)
    {
        return IRedeemManagerV1(RedeemManagerAddress.get()).resolveRedeemRequests(_redeemRequestIds);
    }

    /// @inheritdoc IRiverV1
    function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 _redeemRequestId) {
        IAllowlistV1(AllowlistAddress.get()).onlyAllowed(msg.sender, LibAllowlistMasks.REDEEM_MASK);
        _transfer(msg.sender, address(this), _lsETHAmount);
        return IRedeemManagerV1(RedeemManagerAddress.get()).requestRedeem(_lsETHAmount, _recipient);
    }

    /// @inheritdoc IRiverV1
    function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds)
        external
        returns (uint8[] memory claimStatuses)
    {
        return IRedeemManagerV1(RedeemManagerAddress.get()).claimRedeemRequests(
            _redeemRequestIds, _withdrawalEventIds, true, type(uint16).max
        );
    }

    /// @inheritdoc IRiverV1
    function setGlobalFee(uint256 _newFee) external onlyAdmin {
        GlobalFee.set(_newFee);
        emit SetGlobalFee(_newFee);
    }

    /// @inheritdoc IRiverV1
    function setAllowlist(address _newAllowlist) external onlyAdmin {
        AllowlistAddress.set(_newAllowlist);
        emit SetAllowlist(_newAllowlist);
    }

    /// @inheritdoc IRiverV1
    function setCollector(address _newCollector) external onlyAdmin {
        CollectorAddress.set(_newCollector);
        emit SetCollector(_newCollector);
    }

    /// @inheritdoc IRiverV1
    function setELFeeRecipient(address _newELFeeRecipient) external onlyAdmin {
        ELFeeRecipientAddress.set(_newELFeeRecipient);
        emit SetELFeeRecipient(_newELFeeRecipient);
    }

    /// @inheritdoc IRiverV1
    function setCoverageFund(address _newCoverageFund) external onlyAdmin {
        CoverageFundAddress.set(_newCoverageFund);
        emit SetCoverageFund(_newCoverageFund);
    }

    /// @inheritdoc IRiverV1
    function setMetadataURI(string memory _metadataURI) external onlyAdmin {
        LibSanitize._notEmptyString(_metadataURI);
        MetadataURI.set(_metadataURI);
        emit SetMetadataURI(_metadataURI);
    }

    /// @inheritdoc IRiverV1
    function getOperatorsRegistry() external view returns (address) {
        return OperatorsRegistryAddress.get();
    }

    /// @inheritdoc IRiverV1
    function sendELFees() external payable {
        if (msg.sender != ELFeeRecipientAddress.get()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
    }

    /// @inheritdoc IRiverV1
    function sendCLFunds() external payable {
        if (msg.sender != WithdrawalCredentials.getAddress()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
    }

    /// @inheritdoc IRiverV1
    function sendCoverageFunds() external payable {
        if (msg.sender != CoverageFundAddress.get()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
    }

    /// @inheritdoc IRiverV1
    function sendRedeemManagerExceedingFunds() external payable {
        if (msg.sender != RedeemManagerAddress.get()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
    }

    /// @notice Overridden handler to pass the system admin inside components
    /// @return The address of the admin
    function _getRiverAdmin()
        internal
        view
        override(OracleManagerV1, ConsensusLayerDepositManagerV1)
        returns (address)
    {
        return Administrable._getAdmin();
    }

    /// @notice Overridden handler called whenever a token transfer is triggered
    /// @param _from Token sender
    /// @param _to Token receiver
    function _onTransfer(address _from, address _to) internal view override {
        IAllowlistV1 allowlist = IAllowlistV1(AllowlistAddress.get());
        if (allowlist.isDenied(_from)) {
            revert Denied(_from);
        }
        if (allowlist.isDenied(_to)) {
            revert Denied(_to);
        }
    }

    /// @notice Overridden handler called whenever a user deposits ETH to the system. Mints the adequate amount of shares.
    /// @param _depositor User address that made the deposit
    /// @param _amount Amount of ETH deposited
    function _onDeposit(address _depositor, address _recipient, uint256 _amount) internal override {
        uint256 mintedShares = SharesManagerV1._mintShares(_depositor, _amount);
        IAllowlistV1 allowlist = IAllowlistV1(AllowlistAddress.get());
        if (_depositor == _recipient) {
            allowlist.onlyAllowed(_depositor, LibAllowlistMasks.DEPOSIT_MASK); // this call reverts if unauthorized or denied
        } else {
            allowlist.onlyAllowed(_depositor, LibAllowlistMasks.DEPOSIT_MASK); // this call reverts if unauthorized or denied
            if (allowlist.isDenied(_recipient)) {
                revert Denied(_recipient);
            }
            _transfer(_depositor, _recipient, mintedShares);
        }
    }

    /// @notice Overridden handler called whenever a deposit to the consensus layer is made. Should retrieve _requestedAmount or lower keys
    /// @param _requestedAmount Amount of keys required. Contract is expected to send _requestedAmount or lower.
    /// @return publicKeys Array of fundable public keys
    /// @return signatures Array of signatures linked to the public keys
    function _getNextValidators(uint256 _requestedAmount)
        internal
        override
        returns (bytes[] memory publicKeys, bytes[] memory signatures)
    {
        return IOperatorsRegistryV1(OperatorsRegistryAddress.get()).pickNextValidatorsToDeposit(_requestedAmount);
    }

    /// @notice Overridden handler to pull funds from the execution layer fee recipient to River and return the delta in the balance
    /// @param _max The maximum amount to pull from the execution layer fee recipient
    /// @return The amount pulled from the execution layer fee recipient
    function _pullELFees(uint256 _max) internal override returns (uint256) {
        address elFeeRecipient = ELFeeRecipientAddress.get();
        uint256 initialBalance = address(this).balance;
        IELFeeRecipientV1(payable(elFeeRecipient)).pullELFees(_max);
        uint256 collectedELFees = address(this).balance - initialBalance;
        if (collectedELFees > 0) {
            _setBalanceToDeposit(BalanceToDeposit.get() + collectedELFees);
        }
        emit PulledELFees(collectedELFees);
        return collectedELFees;
    }

    /// @notice Overridden handler to pull funds from the coverage fund to River and return the delta in the balance
    /// @param _max The maximum amount to pull from the coverage fund
    /// @return The amount pulled from the coverage fund
    function _pullCoverageFunds(uint256 _max) internal override returns (uint256) {
        address coverageFund = CoverageFundAddress.get();
        if (coverageFund == address(0)) {
            return 0;
        }
        uint256 initialBalance = address(this).balance;
        ICoverageFundV1(payable(coverageFund)).pullCoverageFunds(_max);
        uint256 collectedCoverageFunds = address(this).balance - initialBalance;
        if (collectedCoverageFunds > 0) {
            _setBalanceToDeposit(BalanceToDeposit.get() + collectedCoverageFunds);
        }
        emit PulledCoverageFunds(collectedCoverageFunds);
        return collectedCoverageFunds;
    }

    /// @notice Overridden handler called whenever the balance of ETH handled by the system increases. Computes the fees paid to the collector
    /// @param _amount Additional ETH received
    function _onEarnings(uint256 _amount) internal override {
        uint256 oldTotalSupply = _totalSupply();
        if (oldTotalSupply == 0) {
            revert ZeroMintedShares();
        }
        uint256 newTotalBalance = _assetBalance();
        uint256 globalFee = GlobalFee.get();
        uint256 numerator = _amount * oldTotalSupply * globalFee;
        uint256 denominator = (newTotalBalance * LibBasisPoints.BASIS_POINTS_MAX) - (_amount * globalFee);
        uint256 sharesToMint = denominator == 0 ? 0 : (numerator / denominator);

        if (sharesToMint > 0) {
            address collector = CollectorAddress.get();
            _mintRawShares(collector, sharesToMint);
            uint256 newTotalSupply = _totalSupply();
            uint256 oldTotalBalance = newTotalBalance - _amount;
            emit RewardsEarned(collector, oldTotalBalance, oldTotalSupply, newTotalBalance, newTotalSupply);
        }
    }

    /// @notice Overridden handler called whenever the total balance of ETH is requested
    /// @return The current total asset balance managed by River
    function _assetBalance() internal view override(SharesManagerV1, OracleManagerV1) returns (uint256) {
        IOracleManagerV1.StoredConsensusLayerReport storage storedReport = LastConsensusLayerReport.get();
        uint256 clValidatorCount = storedReport.validatorsCount;
        uint256 depositedValidatorCount = DepositedValidatorCount.get();
        if (clValidatorCount < depositedValidatorCount) {
            return storedReport.validatorsBalance + BalanceToDeposit.get() + CommittedBalance.get()
                + BalanceToRedeem.get()
                + (depositedValidatorCount - clValidatorCount) * ConsensusLayerDepositManagerV1.DEPOSIT_SIZE;
        } else {
            return
                storedReport.validatorsBalance + BalanceToDeposit.get() + CommittedBalance.get() + BalanceToRedeem.get();
        }
    }

    /// @notice Internal utility to set the daily committable limits
    /// @param _dcl The new daily committable limits
    function _setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl) internal {
        DailyCommittableLimits.set(_dcl);
        emit SetMaxDailyCommittableAmounts(_dcl.minDailyNetCommittableAmount, _dcl.maxDailyRelativeCommittableAmount);
    }

    /// @notice Sets the balance to deposit, but not yet committed
    /// @param _newBalanceToDeposit The new balance to deposit value
    function _setBalanceToDeposit(uint256 _newBalanceToDeposit) internal override(UserDepositManagerV1) {
        emit SetBalanceToDeposit(BalanceToDeposit.get(), _newBalanceToDeposit);
        BalanceToDeposit.set(_newBalanceToDeposit);
    }

    /// @notice Sets the balance to redeem, to be used to satisfy redeem requests on the redeem manager
    /// @param _newBalanceToRedeem The new balance to redeem value
    function _setBalanceToRedeem(uint256 _newBalanceToRedeem) internal {
        emit SetBalanceToRedeem(BalanceToRedeem.get(), _newBalanceToRedeem);
        BalanceToRedeem.set(_newBalanceToRedeem);
    }

    /// @notice Sets the committed balance, ready to be deposited to the consensus layer
    /// @param _newCommittedBalance The new committed balance value
    function _setCommittedBalance(uint256 _newCommittedBalance) internal override(ConsensusLayerDepositManagerV1) {
        emit SetBalanceCommittedToDeposit(CommittedBalance.get(), _newCommittedBalance);
        CommittedBalance.set(_newCommittedBalance);
    }

    /// @notice Pulls funds from the Withdraw contract, and adds funds to deposit and redeem balances
    /// @param _skimmedEthAmount The new amount of skimmed eth to pull
    /// @param _exitedEthAmount The new amount of exited eth to pull
    function _pullCLFunds(uint256 _skimmedEthAmount, uint256 _exitedEthAmount) internal override {
        uint256 currentBalance = address(this).balance;
        uint256 totalAmountToPull = _skimmedEthAmount + _exitedEthAmount;
        IWithdrawV1(WithdrawalCredentials.getAddress()).pullEth(totalAmountToPull);
        uint256 collectedCLFunds = address(this).balance - currentBalance;
        if (collectedCLFunds != _skimmedEthAmount + _exitedEthAmount) {
            revert InvalidPulledClFundsAmount(_skimmedEthAmount + _exitedEthAmount, collectedCLFunds);
        }
        if (_skimmedEthAmount > 0) {
            _setBalanceToDeposit(BalanceToDeposit.get() + _skimmedEthAmount);
        }
        if (_exitedEthAmount > 0) {
            _setBalanceToRedeem(BalanceToRedeem.get() + _exitedEthAmount);
        }
        emit PulledCLFunds(_skimmedEthAmount, _exitedEthAmount);
    }

    /// @notice Pulls funds from the redeem manager exceeding eth buffer
    /// @param _max The maximum amount to pull
    function _pullRedeemManagerExceedingEth(uint256 _max) internal override returns (uint256) {
        uint256 currentBalance = address(this).balance;
        IRedeemManagerV1(RedeemManagerAddress.get()).pullExceedingEth(_max);
        uint256 collectedExceedingEth = address(this).balance - currentBalance;
        if (collectedExceedingEth > 0) {
            _setBalanceToDeposit(BalanceToDeposit.get() + collectedExceedingEth);
        }
        emit PulledRedeemManagerExceedingEth(collectedExceedingEth);
        return collectedExceedingEth;
    }

    /// @notice Use the balance to redeem to report a withdrawal event on the redeem manager
    function _reportWithdrawToRedeemManager() internal override {
        IRedeemManagerV1 redeemManager_ = IRedeemManagerV1(RedeemManagerAddress.get());
        uint256 underlyingAssetBalance = _assetBalance();
        uint256 totalSupply = _totalSupply();

        if (underlyingAssetBalance > 0 && totalSupply > 0) {
            // we compute the redeem manager demands in eth and lsEth based on current conversion rate
            uint256 redeemManagerDemand = redeemManager_.getRedeemDemand();
            uint256 suppliedRedeemManagerDemand = redeemManagerDemand;
            uint256 suppliedRedeemManagerDemandInEth = _balanceFromShares(suppliedRedeemManagerDemand);
            uint256 availableBalanceToRedeem = BalanceToRedeem.get();

            // if demand is higher than available eth, we update demand values to use the available eth
            if (suppliedRedeemManagerDemandInEth > availableBalanceToRedeem) {
                suppliedRedeemManagerDemandInEth = availableBalanceToRedeem;
                suppliedRedeemManagerDemand = _sharesFromBalance(suppliedRedeemManagerDemandInEth);
            }

            emit ReportedRedeemManager(
                redeemManagerDemand, suppliedRedeemManagerDemand, suppliedRedeemManagerDemandInEth
            );

            if (suppliedRedeemManagerDemandInEth > 0) {
                // the available balance to redeem is updated
                _setBalanceToRedeem(availableBalanceToRedeem - suppliedRedeemManagerDemandInEth);

                // we burn the shares of the redeem manager associated with the amount of eth provided
                _burnRawShares(address(redeemManager_), suppliedRedeemManagerDemand);

                // perform a report withdraw call to the redeem manager
                redeemManager_.reportWithdraw{value: suppliedRedeemManagerDemandInEth}(suppliedRedeemManagerDemand);
            }
        }
    }

    /// @notice Requests exits of validators after possibly rebalancing deposit and redeem balances
    /// @param _exitingBalance The currently exiting funds, soon to be received on the execution layer
    /// @param _depositToRedeemRebalancingAllowed True if rebalancing from deposit to redeem is allowed
    function _requestExitsBasedOnRedeemDemandAfterRebalancings(
        uint256 _exitingBalance,
        uint32[] memory _stoppedValidatorCounts,
        bool _depositToRedeemRebalancingAllowed,
        bool _slashingContainmentModeEnabled
    ) internal override {
        IOperatorsRegistryV1(OperatorsRegistryAddress.get()).reportStoppedValidatorCounts(
            _stoppedValidatorCounts, DepositedValidatorCount.get()
        );

        if (_slashingContainmentModeEnabled) {
            return;
        }

        uint256 totalSupply = _totalSupply();
        if (totalSupply > 0) {
            uint256 availableBalanceToRedeem = BalanceToRedeem.get();
            uint256 availableBalanceToDeposit = BalanceToDeposit.get();
            uint256 redeemManagerDemandInEth =
                _balanceFromShares(IRedeemManagerV1(RedeemManagerAddress.get()).getRedeemDemand());

            // if after all rebalancings, the redeem manager demand is still higher than the balance to redeem and exiting eth, we compute
            // the amount of validators to exit in order to cover the remaining demand
            if (availableBalanceToRedeem + _exitingBalance < redeemManagerDemandInEth) {
                // if reblancing is enabled and the redeem manager demand is higher than exiting eth, we add eth for deposit buffer to redeem buffer
                if (_depositToRedeemRebalancingAllowed && availableBalanceToDeposit > 0) {
                    uint256 rebalancingAmount = LibUint256.min(
                        availableBalanceToDeposit, redeemManagerDemandInEth - _exitingBalance - availableBalanceToRedeem
                    );
                    if (rebalancingAmount > 0) {
                        availableBalanceToRedeem += rebalancingAmount;
                        _setBalanceToRedeem(availableBalanceToRedeem);
                        _setBalanceToDeposit(availableBalanceToDeposit - rebalancingAmount);
                    }
                }

                IOperatorsRegistryV1 or = IOperatorsRegistryV1(OperatorsRegistryAddress.get());

                (uint256 totalStoppedValidatorCount, uint256 totalRequestedExitsCount) =
                    or.getStoppedAndRequestedExitCounts();

                // what we are calling pre-exiting balance is the amount of eth that should soon enter the exiting balance
                // because exit requests have been made and operators might have a lag to process them
                // we take them into account to not exit too many validators
                uint256 preExitingBalance = (
                    totalRequestedExitsCount > totalStoppedValidatorCount
                        ? (totalRequestedExitsCount - totalStoppedValidatorCount)
                        : 0
                ) * DEPOSIT_SIZE;

                if (availableBalanceToRedeem + _exitingBalance + preExitingBalance < redeemManagerDemandInEth) {
                    uint256 validatorCountToExit = LibUint256.ceil(
                        redeemManagerDemandInEth - (availableBalanceToRedeem + _exitingBalance + preExitingBalance),
                        DEPOSIT_SIZE
                    );

                    or.demandValidatorExits(validatorCountToExit, DepositedValidatorCount.get());
                }
            }
        }
    }

    /// @notice Skims the redeem balance and sends remaining funds to the deposit balance
    function _skimExcessBalanceToRedeem() internal override {
        uint256 availableBalanceToRedeem = BalanceToRedeem.get();

        // if the available balance to redeem is not 0, it means that all the redeem requests are fulfilled, we should redirect funds for deposits
        if (availableBalanceToRedeem > 0) {
            _setBalanceToDeposit(BalanceToDeposit.get() + availableBalanceToRedeem);
            _setBalanceToRedeem(0);
        }
    }

    /// @notice Commits the deposit balance up to the allowed daily limit in batches of 32 ETH.
    /// @notice Committed funds are funds waiting to be deposited but that cannot be used to fund the redeem manager anymore
    /// @notice This two step process is required to prevent possible out of gas issues we would have from actually funding the validators at this point
    /// @param _period The period between current and last report
    function _commitBalanceToDeposit(uint256 _period) internal override {
        uint256 underlyingAssetBalance = _assetBalance();
        uint256 currentBalanceToDeposit = BalanceToDeposit.get();
        DailyCommittableLimits.DailyCommittableLimitsStruct memory dcl = DailyCommittableLimits.get();

        // we compute the max daily committable amount by taking the asset balance without the balance to deposit into account
        // this value is the daily maximum amount we can commit for deposits
        // we take the maximum value between a net amount and an amount relative to the asset balance
        // this ensures that the amount we can commit is not too low in the beginning and that it is not too high when volumes grow
        // the relative amount is computed from the committed and activated funds (on the CL or committed to be on the CL soon) and not
        // the deposit balance
        // this value is computed by subtracting the current balance to deposit from the underlying asset balance
        uint256 currentMaxDailyCommittableAmount = LibUint256.max(
            dcl.minDailyNetCommittableAmount,
            (uint256(dcl.maxDailyRelativeCommittableAmount) * (underlyingAssetBalance - currentBalanceToDeposit))
                / LibBasisPoints.BASIS_POINTS_MAX
        );
        // we adapt the value for the reporting period by using the asset balance as upper bound
        uint256 currentMaxCommittableAmount =
            LibUint256.min((currentMaxDailyCommittableAmount * _period) / 1 days, currentBalanceToDeposit);
        // we only commit multiples of 32 ETH
        currentMaxCommittableAmount = (currentMaxCommittableAmount / DEPOSIT_SIZE) * DEPOSIT_SIZE;

        if (currentMaxCommittableAmount > 0) {
            _setCommittedBalance(CommittedBalance.get() + currentMaxCommittableAmount);
            _setBalanceToDeposit(currentBalanceToDeposit - currentMaxCommittableAmount);
        }
    }
}

File 2 of 60 : Administrable.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "./interfaces/IAdministrable.sol";

import "./libraries/LibAdministrable.sol";
import "./libraries/LibSanitize.sol";

/// @title Administrable
/// @author Kiln
/// @notice This contract handles the administration of the contracts
abstract contract Administrable is IAdministrable {
    /// @notice Prevents unauthorized calls
    modifier onlyAdmin() {
        if (msg.sender != LibAdministrable._getAdmin()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
        _;
    }

    /// @notice Prevents unauthorized calls
    modifier onlyPendingAdmin() {
        if (msg.sender != LibAdministrable._getPendingAdmin()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
        _;
    }

    /// @inheritdoc IAdministrable
    function getAdmin() external view returns (address) {
        return LibAdministrable._getAdmin();
    }

    /// @inheritdoc IAdministrable
    function getPendingAdmin() external view returns (address) {
        return LibAdministrable._getPendingAdmin();
    }

    /// @inheritdoc IAdministrable
    function proposeAdmin(address _newAdmin) external onlyAdmin {
        _setPendingAdmin(_newAdmin);
    }

    /// @inheritdoc IAdministrable
    function acceptAdmin() external onlyPendingAdmin {
        _setAdmin(LibAdministrable._getPendingAdmin());
        _setPendingAdmin(address(0));
    }

    /// @notice Internal utility to set the admin address
    /// @param _admin Address to set as admin
    function _setAdmin(address _admin) internal {
        LibSanitize._notZeroAddress(_admin);
        LibAdministrable._setAdmin(_admin);
        emit SetAdmin(_admin);
    }

    /// @notice Internal utility to set the pending admin address
    /// @param _pendingAdmin Address to set as pending admin
    function _setPendingAdmin(address _pendingAdmin) internal {
        LibAdministrable._setPendingAdmin(_pendingAdmin);
        emit SetPendingAdmin(_pendingAdmin);
    }

    /// @notice Internal utility to retrieve the address of the current admin
    /// @return The address of admin
    function _getAdmin() internal view returns (address) {
        return LibAdministrable._getAdmin();
    }
}

File 3 of 60 : Initializable.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "./state/shared/Version.sol";

/// @title Initializable
/// @author Kiln
/// @notice This contract ensures that initializers are called only once per version
contract Initializable {
    /// @notice Disable initialization on implementations
    constructor() {
        Version.set(type(uint256).max);
        emit Initialize(type(uint256).max, msg.data);
    }

    /// @notice An error occured during the initialization
    /// @param version The version that was attempting to be initialized
    /// @param expectedVersion The version that was expected
    error InvalidInitialization(uint256 version, uint256 expectedVersion);

    /// @notice Emitted when the contract is properly initialized
    /// @param version New version of the contracts
    /// @param cdata Complete calldata that was used during the initialization
    event Initialize(uint256 version, bytes cdata);

    /// @notice Use this modifier on initializers along with a hard-coded version number
    /// @param _version Version to initialize
    modifier init(uint256 _version) {
        if (_version != Version.get()) {
            revert InvalidInitialization(_version, Version.get());
        }
        Version.set(_version + 1); // prevents reentrency on the called method
        _;
        emit Initialize(_version, msg.data);
    }
}

File 4 of 60 : ConsensusLayerDepositManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../interfaces/components/IConsensusLayerDepositManager.1.sol";
import "../interfaces/IDepositContract.sol";

import "../libraries/LibBytes.sol";
import "../libraries/LibUint256.sol";

import "../state/river/DepositContractAddress.sol";
import "../state/river/WithdrawalCredentials.sol";
import "../state/river/DepositedValidatorCount.sol";
import "../state/river/BalanceToDeposit.sol";
import "../state/river/CommittedBalance.sol";

/// @title Consensus Layer Deposit Manager (v1)
/// @author Kiln
/// @notice This contract handles the interactions with the official deposit contract, funding all validators
/// @notice Whenever a deposit to the consensus layer is requested, this contract computed the amount of keys
/// @notice that could be deposited depending on the amount available in the contract. It then tries to retrieve
/// @notice validator keys by calling its internal virtual method _getNextValidators. This method should be
/// @notice overridden by the implementing contract to provide [0; _keyCount] keys when invoked.
abstract contract ConsensusLayerDepositManagerV1 is IConsensusLayerDepositManagerV1 {
    /// @notice Size of a BLS Public key in bytes
    uint256 public constant PUBLIC_KEY_LENGTH = 48;
    /// @notice Size of a BLS Signature in bytes
    uint256 public constant SIGNATURE_LENGTH = 96;
    /// @notice Size of a deposit in ETH
    uint256 public constant DEPOSIT_SIZE = 32 ether;

    /// @notice Handler called to retrieve the internal River admin address
    /// @dev Must be Overridden
    function _getRiverAdmin() internal view virtual returns (address);

    /// @notice Handler called to change the committed balance to deposit
    /// @param newCommittedBalance The new committed balance value
    function _setCommittedBalance(uint256 newCommittedBalance) internal virtual;

    /// @notice Internal helper to retrieve validator keys ready to be funded
    /// @dev Must be overridden
    /// @param _keyCount The amount of keys (or less) to return.
    function _getNextValidators(uint256 _keyCount)
        internal
        virtual
        returns (bytes[] memory publicKeys, bytes[] memory signatures);

    /// @notice Initializer to set the deposit contract address and the withdrawal credentials to use
    /// @param _depositContractAddress The address of the deposit contract
    /// @param _withdrawalCredentials The withdrawal credentials to apply to all deposits
    function initConsensusLayerDepositManagerV1(address _depositContractAddress, bytes32 _withdrawalCredentials)
        internal
    {
        DepositContractAddress.set(_depositContractAddress);
        emit SetDepositContractAddress(_depositContractAddress);

        WithdrawalCredentials.set(_withdrawalCredentials);
        emit SetWithdrawalCredentials(_withdrawalCredentials);
    }

    /// @inheritdoc IConsensusLayerDepositManagerV1
    function getCommittedBalance() external view returns (uint256) {
        return CommittedBalance.get();
    }

    /// @inheritdoc IConsensusLayerDepositManagerV1
    function getBalanceToDeposit() external view returns (uint256) {
        return BalanceToDeposit.get();
    }

    /// @inheritdoc IConsensusLayerDepositManagerV1
    function getWithdrawalCredentials() external view returns (bytes32) {
        return WithdrawalCredentials.get();
    }

    /// @inheritdoc IConsensusLayerDepositManagerV1
    function getDepositedValidatorCount() external view returns (uint256) {
        return DepositedValidatorCount.get();
    }

    /// @inheritdoc IConsensusLayerDepositManagerV1
    function depositToConsensusLayer(uint256 _maxCount) external {
        uint256 committedBalance = CommittedBalance.get();
        uint256 keyToDepositCount = LibUint256.min(committedBalance / DEPOSIT_SIZE, _maxCount);

        if (keyToDepositCount == 0) {
            revert NotEnoughFunds();
        }

        // it's up to the internal overriden _getNextValidators method to provide two array of the same
        // size for the publicKeys and the signatures
        (bytes[] memory publicKeys, bytes[] memory signatures) = _getNextValidators(keyToDepositCount);

        uint256 receivedPublicKeyCount = publicKeys.length;

        if (receivedPublicKeyCount == 0) {
            revert NoAvailableValidatorKeys();
        }

        if (receivedPublicKeyCount > keyToDepositCount) {
            revert InvalidPublicKeyCount();
        }

        bytes32 withdrawalCredentials = WithdrawalCredentials.get();

        if (withdrawalCredentials == 0) {
            revert InvalidWithdrawalCredentials();
        }

        for (uint256 idx = 0; idx < receivedPublicKeyCount;) {
            _depositValidator(publicKeys[idx], signatures[idx], withdrawalCredentials);
            unchecked {
                ++idx;
            }
        }
        _setCommittedBalance(committedBalance - DEPOSIT_SIZE * receivedPublicKeyCount);
        uint256 currentDepositedValidatorCount = DepositedValidatorCount.get();
        DepositedValidatorCount.set(currentDepositedValidatorCount + receivedPublicKeyCount);
        emit SetDepositedValidatorCount(
            currentDepositedValidatorCount, currentDepositedValidatorCount + receivedPublicKeyCount
        );
    }

    /// @notice Deposits 32 ETH to the official Deposit contract
    /// @param _publicKey The public key of the validator
    /// @param _signature The signature provided by the operator
    /// @param _withdrawalCredentials The withdrawal credentials provided by River
    function _depositValidator(bytes memory _publicKey, bytes memory _signature, bytes32 _withdrawalCredentials)
        internal
    {
        if (_publicKey.length != PUBLIC_KEY_LENGTH) {
            revert InconsistentPublicKeys();
        }

        if (_signature.length != SIGNATURE_LENGTH) {
            revert InconsistentSignatures();
        }
        uint256 value = DEPOSIT_SIZE;

        uint256 depositAmount = value / 1 gwei;

        bytes32 pubkeyRoot = sha256(bytes.concat(_publicKey, bytes16(0)));
        bytes32 signatureRoot = sha256(
            bytes.concat(
                sha256(LibBytes.slice(_signature, 0, 64)),
                sha256(bytes.concat(LibBytes.slice(_signature, 64, SIGNATURE_LENGTH - 64), bytes32(0)))
            )
        );

        bytes32 depositDataRoot = sha256(
            bytes.concat(
                sha256(bytes.concat(pubkeyRoot, _withdrawalCredentials)),
                sha256(bytes.concat(bytes32(LibUint256.toLittleEndian64(depositAmount)), signatureRoot))
            )
        );

        uint256 targetBalance = address(this).balance - value;

        IDepositContract(DepositContractAddress.get()).deposit{value: value}(
            _publicKey, abi.encodePacked(_withdrawalCredentials), _signature, depositDataRoot
        );
        if (address(this).balance != targetBalance) {
            revert ErrorOnDeposit();
        }
    }
}

File 5 of 60 : OracleManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../interfaces/components/IOracleManager.1.sol";
import "../interfaces/IRedeemManager.1.sol";

import "../libraries/LibUint256.sol";

import "../state/river/LastConsensusLayerReport.sol";
import "../state/river/OracleAddress.sol";
import "../state/river/CLValidatorTotalBalance.sol";
import "../state/river/CLValidatorCount.sol";
import "../state/river/DepositedValidatorCount.sol";
import "../state/river/LastOracleRoundId.sol";

/// @title Oracle Manager (v1)
/// @author Kiln
/// @notice This contract handles the inputs provided by the oracle
/// @notice The Oracle contract is plugged to this contract and is in charge of pushing
/// @notice data whenever a new report has been deemed valid. The report consists in two
/// @notice values: the sum of all balances of all deposited validators and the count of
/// @notice validators that have been activated on the consensus layer.
abstract contract OracleManagerV1 is IOracleManagerV1 {
    uint256 internal constant ONE_YEAR = 365 days;
    /// @notice Size of a deposit in ETH
    uint256 public constant _DEPOSIT_SIZE = 32 ether;

    /// @notice Handler called if the delta between the last and new validator balance sum is positive
    /// @dev Must be overridden
    /// @param _profits The positive increase in the validator balance sum (staking rewards)
    function _onEarnings(uint256 _profits) internal virtual;

    /// @notice Handler called to pull the Execution layer fees from the recipient
    /// @dev Must be overridden
    /// @param _max The maximum amount to pull inside the system
    /// @return The amount pulled inside the system
    function _pullELFees(uint256 _max) internal virtual returns (uint256);

    /// @notice Handler called to pull the coverage funds
    /// @dev Must be overridden
    /// @param _max The maximum amount to pull inside the system
    /// @return The amount pulled inside the system
    function _pullCoverageFunds(uint256 _max) internal virtual returns (uint256);

    /// @notice Handler called to retrieve the system administrator address
    /// @dev Must be overridden
    /// @return The system administrator address
    function _getRiverAdmin() internal view virtual returns (address);

    /// @notice Overridden handler called whenever the total balance of ETH is requested
    /// @return The current total asset balance managed by River
    function _assetBalance() internal view virtual returns (uint256);

    /// @notice Pulls funds from the Withdraw contract, and adds funds to deposit and redeem balances
    /// @param _skimmedEthAmount The new amount of skimmed eth to pull
    /// @param _exitedEthAmount The new amount of exited eth to pull
    function _pullCLFunds(uint256 _skimmedEthAmount, uint256 _exitedEthAmount) internal virtual;

    /// @notice Pulls funds from the redeem manager exceeding eth buffer
    /// @param _max The maximum amount to pull
    /// @return The amount pulled
    function _pullRedeemManagerExceedingEth(uint256 _max) internal virtual returns (uint256);

    /// @notice Use the balance to redeem to report a withdrawal event on the redeem manager
    function _reportWithdrawToRedeemManager() internal virtual;

    /// @notice Requests exits of validators after possibly rebalancing deposit and redeem balances
    /// @param _exitingBalance The currently exiting funds, soon to be received on the execution layer
    /// @param _depositToRedeemRebalancingAllowed True if rebalancing from deposit to redeem is allowed
    function _requestExitsBasedOnRedeemDemandAfterRebalancings(
        uint256 _exitingBalance,
        uint32[] memory _stoppedValidatorCounts,
        bool _depositToRedeemRebalancingAllowed,
        bool _slashingContainmentModeEnabled
    ) internal virtual;

    /// @notice Skims the redeem balance and sends remaining funds to the deposit balance
    function _skimExcessBalanceToRedeem() internal virtual;

    /// @notice Commits the deposit balance up to the allowed daily limit
    /// @param _period The period between current and last report
    function _commitBalanceToDeposit(uint256 _period) internal virtual;

    /// @notice Prevents unauthorized calls
    modifier onlyAdmin_OMV1() {
        if (msg.sender != _getRiverAdmin()) {
            revert LibErrors.Unauthorized(msg.sender);
        }
        _;
    }

    /// @notice Set the initial oracle address
    /// @param _oracle Address of the oracle
    function initOracleManagerV1(address _oracle) internal {
        OracleAddress.set(_oracle);
        emit SetOracle(_oracle);
    }

    /// @notice Initializes version 1.1 of the oracle manager
    /// @param _epochsPerFrame The amounts of epochs in a frame
    /// @param _slotsPerEpoch The slots inside an epoch
    /// @param _secondsPerSlot The seconds inside a slot
    /// @param _genesisTime The genesis timestamp
    /// @param _epochsToAssumedFinality The number of epochs before an epoch is considered final on-chain
    /// @param _annualAprUpperBound The reporting upper bound
    /// @param _relativeLowerBound The reporting lower bound
    function initOracleManagerV1_1(
        uint64 _epochsPerFrame,
        uint64 _slotsPerEpoch,
        uint64 _secondsPerSlot,
        uint64 _genesisTime,
        uint64 _epochsToAssumedFinality,
        uint256 _annualAprUpperBound,
        uint256 _relativeLowerBound
    ) internal {
        CLSpec.set(
            CLSpec.CLSpecStruct({
                epochsPerFrame: _epochsPerFrame,
                slotsPerEpoch: _slotsPerEpoch,
                secondsPerSlot: _secondsPerSlot,
                genesisTime: _genesisTime,
                epochsToAssumedFinality: _epochsToAssumedFinality
            })
        );
        emit SetSpec(_epochsPerFrame, _slotsPerEpoch, _secondsPerSlot, _genesisTime, _epochsToAssumedFinality);
        ReportBounds.set(
            ReportBounds.ReportBoundsStruct({
                annualAprUpperBound: _annualAprUpperBound,
                relativeLowerBound: _relativeLowerBound
            })
        );
        emit SetBounds(_annualAprUpperBound, _relativeLowerBound);

        IOracleManagerV1.StoredConsensusLayerReport memory storedReport;
        storedReport.epoch = uint256(LastOracleRoundId.get());
        storedReport.validatorsBalance = CLValidatorTotalBalance.get();
        storedReport.validatorsSkimmedBalance = 0;
        storedReport.validatorsExitedBalance = 0;
        storedReport.validatorsExitingBalance = 0;
        storedReport.validatorsCount = uint32(CLValidatorCount.get());
        storedReport.rebalanceDepositToRedeemMode = false;
        storedReport.slashingContainmentMode = false;
        LastConsensusLayerReport.set(storedReport);
    }

    /// @inheritdoc IOracleManagerV1
    function getOracle() external view returns (address) {
        return OracleAddress.get();
    }

    /// @inheritdoc IOracleManagerV1
    function getCLValidatorTotalBalance() external view returns (uint256) {
        return LastConsensusLayerReport.get().validatorsBalance;
    }

    /// @inheritdoc IOracleManagerV1
    function getCLValidatorCount() external view returns (uint256) {
        return LastConsensusLayerReport.get().validatorsCount;
    }

    /// @inheritdoc IOracleManagerV1
    function getExpectedEpochId() external view returns (uint256) {
        CLSpec.CLSpecStruct memory cls = CLSpec.get();
        uint256 currentEpoch = _currentEpoch(cls);
        return LibUint256.max(
            LastConsensusLayerReport.get().epoch + cls.epochsPerFrame,
            currentEpoch - (currentEpoch % cls.epochsPerFrame)
        );
    }

    /// @inheritdoc IOracleManagerV1
    function isValidEpoch(uint256 _epoch) external view returns (bool) {
        return _isValidEpoch(CLSpec.get(), _epoch);
    }

    /// @inheritdoc IOracleManagerV1
    function getTime() external view returns (uint256) {
        return block.timestamp;
    }

    /// @inheritdoc IOracleManagerV1
    function getLastCompletedEpochId() external view returns (uint256) {
        return LastConsensusLayerReport.get().epoch;
    }

    /// @inheritdoc IOracleManagerV1
    function getCurrentEpochId() external view returns (uint256) {
        return _currentEpoch(CLSpec.get());
    }

    /// @inheritdoc IOracleManagerV1
    function getCLSpec() external view returns (CLSpec.CLSpecStruct memory) {
        return CLSpec.get();
    }

    /// @inheritdoc IOracleManagerV1
    function getCurrentFrame() external view returns (uint256 _startEpochId, uint256 _startTime, uint256 _endTime) {
        CLSpec.CLSpecStruct memory cls = CLSpec.get();
        uint256 currentEpoch = _currentEpoch(cls);
        _startEpochId = currentEpoch - (currentEpoch % cls.epochsPerFrame);
        _startTime = _startEpochId * cls.slotsPerEpoch * cls.secondsPerSlot;
        _endTime = (_startEpochId + cls.epochsPerFrame) * cls.slotsPerEpoch * cls.secondsPerSlot - 1;
    }

    /// @inheritdoc IOracleManagerV1
    function getFrameFirstEpochId(uint256 _epochId) external view returns (uint256) {
        return _epochId - (_epochId % CLSpec.get().epochsPerFrame);
    }

    /// @inheritdoc IOracleManagerV1
    function getReportBounds() external view returns (ReportBounds.ReportBoundsStruct memory) {
        return ReportBounds.get();
    }

    /// @inheritdoc IOracleManagerV1
    function getLastConsensusLayerReport() external view returns (IOracleManagerV1.StoredConsensusLayerReport memory) {
        return LastConsensusLayerReport.get();
    }

    /// @inheritdoc IOracleManagerV1
    function setOracle(address _oracleAddress) external onlyAdmin_OMV1 {
        OracleAddress.set(_oracleAddress);
        emit SetOracle(_oracleAddress);
    }

    /// @inheritdoc IOracleManagerV1
    function setCLSpec(CLSpec.CLSpecStruct calldata _newValue) external onlyAdmin_OMV1 {
        CLSpec.set(_newValue);
        emit SetSpec(
            _newValue.epochsPerFrame,
            _newValue.slotsPerEpoch,
            _newValue.secondsPerSlot,
            _newValue.genesisTime,
            _newValue.epochsToAssumedFinality
        );
    }

    /// @inheritdoc IOracleManagerV1
    function setReportBounds(ReportBounds.ReportBoundsStruct calldata _newValue) external onlyAdmin_OMV1 {
        ReportBounds.set(_newValue);
        emit SetBounds(_newValue.annualAprUpperBound, _newValue.relativeLowerBound);
    }

    /// @notice Structure holding internal variables used during reporting
    struct ConsensusLayerDataReportingVariables {
        uint256 preReportUnderlyingBalance;
        uint256 postReportUnderlyingBalance;
        uint256 lastReportExitedBalance;
        uint256 lastReportSkimmedBalance;
        uint256 exitedAmountIncrease;
        uint256 skimmedAmountIncrease;
        uint256 timeElapsedSinceLastReport;
        uint256 availableAmountToUpperBound;
        uint256 redeemManagerDemand;
        ConsensusLayerDataReportingTrace trace;
    }

    /// @inheritdoc IOracleManagerV1
    function setConsensusLayerData(IOracleManagerV1.ConsensusLayerReport calldata _report) external {
        // only the oracle is allowed to call this endpoint
        if (msg.sender != OracleAddress.get()) {
            revert LibErrors.Unauthorized(msg.sender);
        }

        CLSpec.CLSpecStruct memory cls = CLSpec.get();

        // we start by verifying that the reported epoch is valid based on the consensus layer spec
        if (!_isValidEpoch(cls, _report.epoch)) {
            revert InvalidEpoch(_report.epoch);
        }

        ConsensusLayerDataReportingVariables memory vars;

        {
            IOracleManagerV1.StoredConsensusLayerReport storage lastStoredReport = LastConsensusLayerReport.get();

            vars.lastReportExitedBalance = lastStoredReport.validatorsExitedBalance;

            // we ensure that the reported total exited balance is not decreasing
            if (_report.validatorsExitedBalance < vars.lastReportExitedBalance) {
                revert InvalidDecreasingValidatorsExitedBalance(
                    vars.lastReportExitedBalance, _report.validatorsExitedBalance
                );
            }

            // we compute the exited amount increase by taking the delta between reports
            vars.exitedAmountIncrease = _report.validatorsExitedBalance - vars.lastReportExitedBalance;

            vars.lastReportSkimmedBalance = lastStoredReport.validatorsSkimmedBalance;

            // we ensure that the reported total skimmed balance is not decreasing
            if (_report.validatorsSkimmedBalance < vars.lastReportSkimmedBalance) {
                revert InvalidDecreasingValidatorsSkimmedBalance(
                    vars.lastReportSkimmedBalance, _report.validatorsSkimmedBalance
                );
            }

            // we ensure that the reported validator count is not decreasing
            if (
                _report.validatorsCount > DepositedValidatorCount.get()
                    || _report.validatorsCount < lastStoredReport.validatorsCount
            ) {
                revert InvalidValidatorCountReport(
                    _report.validatorsCount, DepositedValidatorCount.get(), lastStoredReport.validatorsCount
                );
            }

            // we compute the new skimmed amount by taking the delta between reports
            vars.skimmedAmountIncrease = _report.validatorsSkimmedBalance - vars.lastReportSkimmedBalance;

            vars.timeElapsedSinceLastReport = _timeBetweenEpochs(cls, lastStoredReport.epoch, _report.epoch);
        }

        // we retrieve the current total underlying balance before any reporting data is applied to the system
        vars.preReportUnderlyingBalance = _assetBalance();

        // if we have new exited / skimmed eth available, we pull funds from the consensus layer recipient
        if (vars.exitedAmountIncrease + vars.skimmedAmountIncrease > 0) {
            // this method pulls and updates ethToDeposit / ethToRedeem accordingly
            _pullCLFunds(vars.skimmedAmountIncrease, vars.exitedAmountIncrease);
        }

        {
            // we update the system parameters, this will have an impact on how the total underlying balance is computed
            IOracleManagerV1.StoredConsensusLayerReport memory storedReport;

            storedReport.epoch = _report.epoch;
            storedReport.validatorsBalance = _report.validatorsBalance;
            storedReport.validatorsSkimmedBalance = _report.validatorsSkimmedBalance;
            storedReport.validatorsExitedBalance = _report.validatorsExitedBalance;
            storedReport.validatorsExitingBalance = _report.validatorsExitingBalance;
            storedReport.validatorsCount = _report.validatorsCount;
            storedReport.rebalanceDepositToRedeemMode = _report.rebalanceDepositToRedeemMode;
            storedReport.slashingContainmentMode = _report.slashingContainmentMode;
            LastConsensusLayerReport.set(storedReport);
        }

        ReportBounds.ReportBoundsStruct memory rb = ReportBounds.get();

        // we compute the maximum allowed increase in balance based on the pre report value
        uint256 maxIncrease = _maxIncrease(rb, vars.preReportUnderlyingBalance, vars.timeElapsedSinceLastReport);

        // we retrieve the new total underlying balance after system parameters are changed
        vars.postReportUnderlyingBalance = _assetBalance();

        // we can now compute the earned rewards from the consensus layer balances
        // in order to properly account for the balance increase, we compare the sums of current balances, skimmed balance and exited balances
        // we also synthetically increase the current balance by 32 eth per new activated validator, this way we have no discrepency due
        // to currently activating funds that were not yet accounted in the consensus layer balances
        if (vars.postReportUnderlyingBalance >= vars.preReportUnderlyingBalance) {
            // if this happens, we revert and the reporting process is cancelled
            if (vars.postReportUnderlyingBalance > vars.preReportUnderlyingBalance + maxIncrease) {
                revert TotalValidatorBalanceIncreaseOutOfBound(
                    vars.preReportUnderlyingBalance,
                    vars.postReportUnderlyingBalance,
                    vars.timeElapsedSinceLastReport,
                    rb.annualAprUpperBound
                );
            }

            // we update the rewards based on the balance delta
            vars.trace.rewards = vars.postReportUnderlyingBalance - vars.preReportUnderlyingBalance;

            // we update the available amount to upper bound (the amount of eth we can still pull and stay below the upper reporting bound)
            vars.availableAmountToUpperBound = maxIncrease - vars.trace.rewards;
        } else {
            // otherwise if the balance has decreased, we verify that we are not exceeding the lower reporting bound

            // we compute the maximum allowed decrease in balance
            uint256 maxDecrease = _maxDecrease(rb, vars.preReportUnderlyingBalance);

            // we verify that the bound is not crossed
            if (
                vars.postReportUnderlyingBalance
                    < vars.preReportUnderlyingBalance - LibUint256.min(maxDecrease, vars.preReportUnderlyingBalance)
            ) {
                revert TotalValidatorBalanceDecreaseOutOfBound(
                    vars.preReportUnderlyingBalance,
                    vars.postReportUnderlyingBalance,
                    vars.timeElapsedSinceLastReport,
                    rb.relativeLowerBound
                );
            }

            // we update the available amount to upper bound to be equal to the maximum allowed increase plus the negative delta due to the loss
            vars.availableAmountToUpperBound =
                maxIncrease + (vars.preReportUnderlyingBalance - vars.postReportUnderlyingBalance);
        }

        // if we have available amount to upper bound after the reporting values are applied
        if (vars.availableAmountToUpperBound > 0) {
            // we pull the funds from the execution layer fee recipient
            vars.trace.pulledELFees = _pullELFees(vars.availableAmountToUpperBound);
            // we update the rewards
            vars.trace.rewards += vars.trace.pulledELFees;
            // we update the available amount accordingly
            vars.availableAmountToUpperBound -= vars.trace.pulledELFees;
        }

        // if we have available amount to upper bound after the execution layer fees are pulled
        if (vars.availableAmountToUpperBound > 0) {
            // we pull the funds from the exceeding eth buffer of the redeem manager
            vars.trace.pulledRedeemManagerExceedingEthBuffer =
                _pullRedeemManagerExceedingEth(vars.availableAmountToUpperBound);
            // we update the available amount accordingly
            vars.availableAmountToUpperBound -= vars.trace.pulledRedeemManagerExceedingEthBuffer;
        }

        // if we have available amount to upper bound after pulling the exceeding eth buffer, we attempt to pull coverage funds
        if (vars.availableAmountToUpperBound > 0) {
            // we pull the funds from the coverage recipient
            vars.trace.pulledCoverageFunds = _pullCoverageFunds(vars.availableAmountToUpperBound);
            // we do not update the rewards as coverage is not considered rewards
            // we do not update the available amount as there are no more pulling actions to perform afterwards
        }

        // if our rewards are not null, we dispatch the fee to the collector
        if (vars.trace.rewards > 0) {
            _onEarnings(vars.trace.rewards);
        }

        _requestExitsBasedOnRedeemDemandAfterRebalancings(
            _report.validatorsExitingBalance,
            _report.stoppedValidatorCountPerOperator,
            _report.rebalanceDepositToRedeemMode,
            _report.slashingContainmentMode
        );

        // we use the updated balanceToRedeem value to report a withdraw event on the redeem manager
        _reportWithdrawToRedeemManager();

        // if funds are left in the balance to redeem, we move them to the deposit balance
        _skimExcessBalanceToRedeem();

        // we update the committable amount based on daily maximum allowed
        _commitBalanceToDeposit(vars.timeElapsedSinceLastReport);

        // we emit a summary event with all the reporting details
        emit ProcessedConsensusLayerReport(_report, vars.trace);
    }

    /// @notice Retrieve the current epoch based on the current timestamp
    /// @param _cls The consensus layer spec struct
    /// @return The current epoch
    function _currentEpoch(CLSpec.CLSpecStruct memory _cls) internal view returns (uint256) {
        return ((block.timestamp - _cls.genesisTime) / _cls.secondsPerSlot) / _cls.slotsPerEpoch;
    }

    /// @notice Verifies if the given epoch is valid
    /// @param _cls The consensus layer spec struct
    /// @param _epoch The epoch to verify
    /// @return True if valid
    function _isValidEpoch(CLSpec.CLSpecStruct memory _cls, uint256 _epoch) internal view returns (bool) {
        return (
            _currentEpoch(_cls) >= _epoch + _cls.epochsToAssumedFinality
                && _epoch > LastConsensusLayerReport.get().epoch && _epoch % _cls.epochsPerFrame == 0
        );
    }

    /// @notice Retrieves the maximum increase in balance based on current total underlying supply and period since last report
    /// @param _rb The report bounds struct
    /// @param _prevTotalEth The total underlying supply during reporting
    /// @param _timeElapsed The time since last report
    /// @return The maximum allowed increase in balance
    function _maxIncrease(ReportBounds.ReportBoundsStruct memory _rb, uint256 _prevTotalEth, uint256 _timeElapsed)
        internal
        pure
        returns (uint256)
    {
        return (_prevTotalEth * _rb.annualAprUpperBound * _timeElapsed) / (LibBasisPoints.BASIS_POINTS_MAX * ONE_YEAR);
    }

    /// @notice Retrieves the maximum decrease in balance based on current total underlying supply
    /// @param _rb The report bounds struct
    /// @param _prevTotalEth The total underlying supply during reporting
    /// @return The maximum allowed decrease in balance
    function _maxDecrease(ReportBounds.ReportBoundsStruct memory _rb, uint256 _prevTotalEth)
        internal
        pure
        returns (uint256)
    {
        return (_prevTotalEth * _rb.relativeLowerBound) / LibBasisPoints.BASIS_POINTS_MAX;
    }

    /// @notice Retrieve the number of seconds between two epochs
    /// @param _cls The consensus layer spec struct
    /// @param _epochPast The starting epoch
    /// @param _epochNow The current epoch
    /// @return The number of seconds between the two epochs
    function _timeBetweenEpochs(CLSpec.CLSpecStruct memory _cls, uint256 _epochPast, uint256 _epochNow)
        internal
        pure
        returns (uint256)
    {
        return (_epochNow - _epochPast) * (_cls.secondsPerSlot * _cls.slotsPerEpoch);
    }
}

File 6 of 60 : SharesManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../interfaces/components/ISharesManager.1.sol";

import "../libraries/LibSanitize.sol";

import "../state/river/Shares.sol";
import "../state/river/SharesPerOwner.sol";
import "../state/shared/ApprovalsPerOwner.sol";

/// @title Shares Manager (v1)
/// @author Kiln
/// @notice This contract handles the shares of the depositor and the ERC20 interface
abstract contract SharesManagerV1 is ISharesManagerV1 {
    /// @notice Internal hook triggered on the external transfer call
    /// @dev Must be overridden
    /// @param _from Address of the sender
    /// @param _to Address of the recipient
    function _onTransfer(address _from, address _to) internal view virtual;

    /// @notice Internal method to override to provide the total underlying asset balance
    /// @dev Must be overridden
    /// @return The total asset balance of the system
    function _assetBalance() internal view virtual returns (uint256);

    /// @notice Modifier used to ensure that the transfer is allowed by using the internal hook to perform internal checks
    /// @param _from Address of the sender
    /// @param _to Address of the recipient
    modifier transferAllowed(address _from, address _to) {
        _onTransfer(_from, _to);
        _;
    }

    /// @notice Modifier used to ensure the amount transferred is not 0
    /// @param _value Amount to check
    modifier isNotZero(uint256 _value) {
        if (_value == 0) {
            revert NullTransfer();
        }
        _;
    }

    /// @notice Modifier used to ensure that the sender has enough funds for the transfer
    /// @param _owner Address of the sender
    /// @param _value Value that is required to be sent
    modifier hasFunds(address _owner, uint256 _value) {
        if (_balanceOf(_owner) < _value) {
            revert BalanceTooLow();
        }
        _;
    }

    /// @inheritdoc ISharesManagerV1
    function name() external pure returns (string memory) {
        return "Liquid Staked ETH";
    }

    /// @inheritdoc ISharesManagerV1
    function symbol() external pure returns (string memory) {
        return "LsETH";
    }

    /// @inheritdoc ISharesManagerV1
    function decimals() external pure returns (uint8) {
        return 18;
    }

    /// @inheritdoc ISharesManagerV1
    function totalSupply() external view returns (uint256) {
        return _totalSupply();
    }

    /// @inheritdoc ISharesManagerV1
    function totalUnderlyingSupply() external view returns (uint256) {
        return _assetBalance();
    }

    /// @inheritdoc ISharesManagerV1
    function balanceOf(address _owner) external view returns (uint256) {
        return _balanceOf(_owner);
    }

    /// @inheritdoc ISharesManagerV1
    function balanceOfUnderlying(address _owner) public view returns (uint256) {
        return _balanceFromShares(SharesPerOwner.get(_owner));
    }

    /// @inheritdoc ISharesManagerV1
    function underlyingBalanceFromShares(uint256 _shares) external view returns (uint256) {
        return _balanceFromShares(_shares);
    }

    /// @inheritdoc ISharesManagerV1
    function sharesFromUnderlyingBalance(uint256 _underlyingAssetAmount) external view returns (uint256) {
        return _sharesFromBalance(_underlyingAssetAmount);
    }

    /// @inheritdoc ISharesManagerV1
    function allowance(address _owner, address _spender) external view returns (uint256) {
        return ApprovalsPerOwner.get(_owner, _spender);
    }

    /// @inheritdoc ISharesManagerV1
    function transfer(address _to, uint256 _value)
        external
        transferAllowed(msg.sender, _to)
        isNotZero(_value)
        hasFunds(msg.sender, _value)
        returns (bool)
    {
        if (_to == address(0)) {
            revert UnauthorizedTransfer(msg.sender, address(0));
        }
        return _transfer(msg.sender, _to, _value);
    }

    /// @inheritdoc ISharesManagerV1
    function transferFrom(address _from, address _to, uint256 _value)
        external
        transferAllowed(_from, _to)
        isNotZero(_value)
        hasFunds(_from, _value)
        returns (bool)
    {
        if (_to == address(0)) {
            revert UnauthorizedTransfer(_from, address(0));
        }
        _spendAllowance(_from, _value);
        return _transfer(_from, _to, _value);
    }

    /// @inheritdoc ISharesManagerV1
    function approve(address _spender, uint256 _value) external returns (bool) {
        _approve(msg.sender, _spender, _value);
        return true;
    }

    /// @inheritdoc ISharesManagerV1
    function increaseAllowance(address _spender, uint256 _additionalValue) external returns (bool) {
        _approve(msg.sender, _spender, ApprovalsPerOwner.get(msg.sender, _spender) + _additionalValue);
        return true;
    }

    /// @inheritdoc ISharesManagerV1
    function decreaseAllowance(address _spender, uint256 _subtractableValue) external returns (bool) {
        _approve(msg.sender, _spender, ApprovalsPerOwner.get(msg.sender, _spender) - _subtractableValue);
        return true;
    }

    /// @notice Internal utility to spend the allowance of an account from the message sender
    /// @param _from Address owning the allowance
    /// @param _value Amount of allowance in shares to spend
    function _spendAllowance(address _from, uint256 _value) internal {
        uint256 currentAllowance = ApprovalsPerOwner.get(_from, msg.sender);
        if (currentAllowance < _value) {
            revert AllowanceTooLow(_from, msg.sender, currentAllowance, _value);
        }
        if (currentAllowance != type(uint256).max) {
            _approve(_from, msg.sender, currentAllowance - _value);
        }
    }

    /// @notice Internal utility to change the allowance of an owner to a spender
    /// @param _owner The owner of the shares
    /// @param _spender The allowed spender of the shares
    /// @param _value The new allowance value
    function _approve(address _owner, address _spender, uint256 _value) internal {
        LibSanitize._notZeroAddress(_owner);
        LibSanitize._notZeroAddress(_spender);
        ApprovalsPerOwner.set(_owner, _spender, _value);
        emit Approval(_owner, _spender, _value);
    }

    /// @notice Internal utility to retrieve the total supply of tokens
    /// @return The total supply
    function _totalSupply() internal view returns (uint256) {
        return Shares.get();
    }

    /// @notice Internal utility to perform an unchecked transfer
    /// @param _from Address sending the tokens
    /// @param _to Address receiving the tokens
    /// @param _value Amount of shares to be sent
    /// @return True if success
    function _transfer(address _from, address _to, uint256 _value) internal returns (bool) {
        SharesPerOwner.set(_from, SharesPerOwner.get(_from) - _value);
        SharesPerOwner.set(_to, SharesPerOwner.get(_to) + _value);

        emit Transfer(_from, _to, _value);

        return true;
    }

    /// @notice Internal utility to retrieve the underlying asset balance for the given shares
    /// @param _shares Amount of shares to convert
    /// @return The balance from the given shares
    function _balanceFromShares(uint256 _shares) internal view returns (uint256) {
        uint256 _totalSharesValue = Shares.get();

        if (_totalSharesValue == 0) {
            return 0;
        }

        return ((_shares * _assetBalance())) / _totalSharesValue;
    }

    /// @notice Internal utility to retrieve the shares count for a given underlying asset amount
    /// @param _balance Amount of underlying asset balance to convert
    /// @return The shares from the given balance
    function _sharesFromBalance(uint256 _balance) internal view returns (uint256) {
        uint256 _totalSharesValue = Shares.get();

        if (_totalSharesValue == 0) {
            return 0;
        }

        return (_balance * _totalSharesValue) / _assetBalance();
    }

    /// @notice Internal utility to mint shares for the specified user
    /// @dev This method assumes that funds received are now part of the _assetBalance()
    /// @param _owner Account that should receive the new shares
    /// @param _underlyingAssetValue Value of underlying asset received, to convert into shares
    /// @return sharesToMint The amnount of minted shares
    function _mintShares(address _owner, uint256 _underlyingAssetValue) internal returns (uint256 sharesToMint) {
        uint256 oldTotalAssetBalance = _assetBalance() - _underlyingAssetValue;

        if (oldTotalAssetBalance == 0) {
            sharesToMint = _underlyingAssetValue;
            _mintRawShares(_owner, _underlyingAssetValue);
        } else {
            sharesToMint = (_underlyingAssetValue * _totalSupply()) / oldTotalAssetBalance;
            _mintRawShares(_owner, sharesToMint);
        }
    }

    /// @notice Internal utility to retrieve the amount of shares per owner
    /// @param _owner Account to be checked
    /// @return The balance of the account in shares
    function _balanceOf(address _owner) internal view returns (uint256) {
        return SharesPerOwner.get(_owner);
    }

    /// @notice Internal utility to mint shares without any conversion, and emits a mint Transfer event
    /// @param _owner Account that should receive the new shares
    /// @param _value Amount of shares to mint
    function _mintRawShares(address _owner, uint256 _value) internal {
        _setTotalSupply(Shares.get() + _value);
        SharesPerOwner.set(_owner, SharesPerOwner.get(_owner) + _value);
        emit Transfer(address(0), _owner, _value);
    }

    /// @notice Internal utility to burn shares without any conversion, and emits a burn Transfer event
    /// @param _owner Account that should burn its shares
    /// @param _value Amount of shares to burn
    function _burnRawShares(address _owner, uint256 _value) internal {
        _setTotalSupply(Shares.get() - _value);
        SharesPerOwner.set(_owner, SharesPerOwner.get(_owner) - _value);
        emit Transfer(_owner, address(0), _value);
    }

    /// @notice Internal utility to set the total supply and emit an event
    /// @param newTotalSupply The new total supply value
    function _setTotalSupply(uint256 newTotalSupply) internal {
        Shares.set(newTotalSupply);
        emit SetTotalSupply(newTotalSupply);
    }
}

File 7 of 60 : UserDepositManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../interfaces/components/IUserDepositManager.1.sol";

import "../libraries/LibSanitize.sol";

import "../state/river/BalanceToDeposit.sol";

/// @title User Deposit Manager (v1)
/// @author Kiln
/// @notice This contract handles the inbound transfers cases or the explicit submissions
abstract contract UserDepositManagerV1 is IUserDepositManagerV1 {
    /// @notice Handler called whenever a user has sent funds to the contract
    /// @dev Must be overridden
    /// @param _depositor Address that made the deposit
    /// @param _recipient Address that receives the minted shares
    /// @param _amount Amount deposited
    function _onDeposit(address _depositor, address _recipient, uint256 _amount) internal virtual;
    function _setBalanceToDeposit(uint256 newBalanceToDeposit) internal virtual;

    /// @inheritdoc IUserDepositManagerV1
    function deposit() external payable {
        _deposit(msg.sender);
    }

    /// @inheritdoc IUserDepositManagerV1
    function depositAndTransfer(address _recipient) external payable {
        LibSanitize._notZeroAddress(_recipient);
        _deposit(_recipient);
    }

    /// @inheritdoc IUserDepositManagerV1
    receive() external payable {
        _deposit(msg.sender);
    }

    /// @inheritdoc IUserDepositManagerV1
    fallback() external payable {
        revert LibErrors.InvalidCall();
    }

    /// @notice Internal utility calling the deposit handler and emitting the deposit details
    /// @param _recipient The account receiving the minted shares
    function _deposit(address _recipient) internal {
        if (msg.value == 0) {
            revert EmptyDeposit();
        }

        _setBalanceToDeposit(BalanceToDeposit.get() + msg.value);

        _onDeposit(msg.sender, _recipient, msg.value);

        emit UserDeposit(msg.sender, _recipient, msg.value);
    }
}

File 8 of 60 : IAdministrable.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Administrable Interface
/// @author Kiln
/// @notice This interface exposes methods to handle the ownership of the contracts
interface IAdministrable {
    /// @notice The pending admin address changed
    /// @param pendingAdmin New pending admin address
    event SetPendingAdmin(address indexed pendingAdmin);

    /// @notice The admin address changed
    /// @param admin New admin address
    event SetAdmin(address indexed admin);

    /// @notice Retrieves the current admin address
    /// @return The admin address
    function getAdmin() external view returns (address);

    /// @notice Retrieve the current pending admin address
    /// @return The pending admin address
    function getPendingAdmin() external view returns (address);

    /// @notice Proposes a new address as admin
    /// @dev This security prevents setting an invalid address as an admin. The pending
    /// @dev admin has to claim its ownership of the contract, and prove that the new
    /// @dev address is able to perform regular transactions.
    /// @param _newAdmin New admin address
    function proposeAdmin(address _newAdmin) external;

    /// @notice Accept the transfer of ownership
    /// @dev Only callable by the pending admin. Resets the pending admin if succesful.
    function acceptAdmin() external;
}

File 9 of 60 : IAllowlist.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Allowlist Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the list of allowed recipients.
interface IAllowlistV1 {
    /// @notice The permissions of several accounts have changed
    /// @param accounts List of accounts
    /// @param permissions New permissions for each account at the same index
    event SetAllowlistPermissions(address[] accounts, uint256[] permissions);

    /// @notice The stored allower address has been changed
    /// @param allower The new allower address
    event SetAllower(address indexed allower);

    /// @notice The provided accounts list is empty
    error InvalidAlloweeCount();

    /// @notice The account is denied access
    /// @param _account The denied account
    error Denied(address _account);

    /// @notice The provided accounts and permissions list have different lengths
    error MismatchedAlloweeAndStatusCount();

    /// @notice Initializes the allowlist
    /// @param _admin Address of the Allowlist administrator
    /// @param _allower Address of the allower
    function initAllowlistV1(address _admin, address _allower) external;

    /// @notice Retrieves the allower address
    /// @return The address of the allower
    function getAllower() external view returns (address);

    /// @notice This method returns true if the user has the expected permission and
    ///         is not in the deny list
    /// @param _account Recipient to verify
    /// @param _mask Combination of permissions to verify
    /// @return True if mask is respected and user is allowed
    function isAllowed(address _account, uint256 _mask) external view returns (bool);

    /// @notice This method returns true if the user is in the deny list
    /// @param _account Recipient to verify
    /// @return True if user is denied access
    function isDenied(address _account) external view returns (bool);

    /// @notice This method returns true if the user has the expected permission
    ///         ignoring any deny list membership
    /// @param _account Recipient to verify
    /// @param _mask Combination of permissions to verify
    /// @return True if mask is respected
    function hasPermission(address _account, uint256 _mask) external view returns (bool);

    /// @notice This method retrieves the raw permission value
    /// @param _account Recipient to verify
    /// @return The raw permissions value of the account
    function getPermissions(address _account) external view returns (uint256);

    /// @notice This method should be used as a modifier and is expected to revert
    ///         if the user hasn't got the required permission or if the user is
    ///         in the deny list.
    /// @param _account Recipient to verify
    /// @param _mask Combination of permissions to verify
    function onlyAllowed(address _account, uint256 _mask) external view;

    /// @notice Changes the allower address
    /// @param _newAllowerAddress New address allowed to edit the allowlist
    function setAllower(address _newAllowerAddress) external;

    /// @notice Sets the allowlisting status for one or more accounts
    /// @dev The permission value is overridden and not updated
    /// @param _accounts Accounts with statuses to edit
    /// @param _permissions Allowlist permissions for each account, in the same order as _accounts
    function allow(address[] calldata _accounts, uint256[] calldata _permissions) external;
}

File 10 of 60 : ICoverageFund.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Coverage Fund Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to receive donations for the slashing coverage fund and pull the funds into river
interface ICoverageFundV1 {
    /// @notice The storage river address has changed
    /// @param river The new river address
    event SetRiver(address indexed river);

    /// @notice A donation has been made to the coverage fund
    /// @param donator Address that performed the donation
    /// @param amount The amount donated
    event Donate(address indexed donator, uint256 amount);

    /// @notice The fallback or receive callback has been triggered
    error InvalidCall();

    /// @notice A donation with 0 ETH has been performed
    error EmptyDonation();

    /// @notice Initialize the coverage fund with the required arguments
    /// @param _riverAddress Address of River
    function initCoverageFundV1(address _riverAddress) external;

    /// @notice Pulls ETH into the River contract
    /// @dev Only callable by the River contract
    /// @param _maxAmount The maximum amount to pull into the system
    function pullCoverageFunds(uint256 _maxAmount) external;

    /// @notice Donates ETH to the coverage fund contract
    function donate() external payable;

    /// @notice Ether receiver
    receive() external payable;

    /// @notice Invalid fallback detector
    fallback() external payable;
}

File 11 of 60 : IDepositContract.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Deposit Contract Interface
/// @notice This interface exposes methods to perform validator deposits
interface IDepositContract {
    /// @notice Official deposit method to activate a validator on the consensus layer
    /// @param pubkey The 48 bytes long BLS Public key representing the validator
    /// @param withdrawalCredentials The 32 bytes long withdrawal credentials, configures the withdrawal recipient
    /// @param signature The 96 bytes long BLS Signature performed by the pubkey's private key
    /// @param depositDataRoot The root hash of the whole deposit data structure
    function deposit(
        bytes calldata pubkey,
        bytes calldata withdrawalCredentials,
        bytes calldata signature,
        bytes32 depositDataRoot
    ) external payable;
}

File 12 of 60 : IELFeeRecipient.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Execution Layer Fee Recipient Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to receive all the execution layer fees from the proposed blocks + bribes
interface IELFeeRecipientV1 {
    /// @notice The storage river address has changed
    /// @param river The new river address
    event SetRiver(address indexed river);

    /// @notice The fallback has been triggered
    error InvalidCall();

    /// @notice Initialize the fee recipient with the required arguments
    /// @param _riverAddress Address of River
    function initELFeeRecipientV1(address _riverAddress) external;

    /// @notice Pulls ETH to the River contract
    /// @dev Only callable by the River contract
    /// @param _maxAmount The maximum amount to pull into the system
    function pullELFees(uint256 _maxAmount) external;

    /// @notice Ether receiver
    receive() external payable;

    /// @notice Invalid fallback detector
    fallback() external payable;
}

File 13 of 60 : IOperatorRegistry.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../state/operatorsRegistry/Operators.2.sol";

/// @title Operators Registry Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the list of operators and their keys
interface IOperatorsRegistryV1 {
    /// @notice A new operator has been added to the registry
    /// @param index The operator index
    /// @param name The operator display name
    /// @param operatorAddress The operator address
    event AddedOperator(uint256 indexed index, string name, address indexed operatorAddress);

    /// @notice The operator status has been changed
    /// @param index The operator index
    /// @param active True if the operator is active
    event SetOperatorStatus(uint256 indexed index, bool active);

    /// @notice The operator limit has been changed
    /// @param index The operator index
    /// @param newLimit The new operator staking limit
    event SetOperatorLimit(uint256 indexed index, uint256 newLimit);

    /// @notice The operator stopped validator count has been changed
    /// @param index The operator index
    /// @param newStoppedValidatorCount The new stopped validator count
    event SetOperatorStoppedValidatorCount(uint256 indexed index, uint256 newStoppedValidatorCount);

    /// @notice The operator address has been changed
    /// @param index The operator index
    /// @param newOperatorAddress The new operator address
    event SetOperatorAddress(uint256 indexed index, address indexed newOperatorAddress);

    /// @notice The operator display name has been changed
    /// @param index The operator index
    /// @param newName The new display name
    event SetOperatorName(uint256 indexed index, string newName);

    /// @notice The operator or the admin added new validator keys and signatures
    /// @dev The public keys and signatures are concatenated
    /// @dev A public key is 48 bytes long
    /// @dev A signature is 96 bytes long
    /// @dev [P1, S1, P2, S2, ..., PN, SN] where N is the bytes length divided by (96 + 48)
    /// @param index The operator index
    /// @param publicKeysAndSignatures The concatenated public keys and signatures
    event AddedValidatorKeys(uint256 indexed index, bytes publicKeysAndSignatures);

    /// @notice The operator or the admin removed a public key and its signature from the registry
    /// @param index The operator index
    /// @param publicKey The BLS public key that has been removed
    event RemovedValidatorKey(uint256 indexed index, bytes publicKey);

    /// @notice The stored river address has been changed
    /// @param river The new river address
    event SetRiver(address indexed river);

    /// @notice The operator edited its keys after the snapshot block
    /// @dev This means that we cannot assume that its key set is checked by the snapshot
    /// @dev This happens only if the limit was meant to be increased
    /// @param index The operator index
    /// @param currentLimit The current operator limit
    /// @param newLimit The new operator limit that was attempted to be set
    /// @param latestKeysEditBlockNumber The last block number at which the operator changed its keys
    /// @param snapshotBlock The block number of the snapshot
    event OperatorEditsAfterSnapshot(
        uint256 indexed index,
        uint256 currentLimit,
        uint256 newLimit,
        uint256 indexed latestKeysEditBlockNumber,
        uint256 indexed snapshotBlock
    );

    /// @notice The call didn't alter the limit of the operator
    /// @param index The operator index
    /// @param limit The limit of the operator
    event OperatorLimitUnchanged(uint256 indexed index, uint256 limit);

    /// @notice The stopped validator array has been changed
    /// @notice A validator is considered stopped if exiting, exited or slashed
    /// @notice This event is emitted when the oracle reports new stopped validators counts
    /// @param stoppedValidatorCounts The new stopped validator counts
    event UpdatedStoppedValidators(uint32[] stoppedValidatorCounts);

    /// @notice The requested exit count has been updated
    /// @param index The operator index
    /// @param count The count of requested exits
    event RequestedValidatorExits(uint256 indexed index, uint256 count);

    /// @notice The exit request demand has been updated
    /// @param previousValidatorExitsDemand The previous exit request demand
    /// @param nextValidatorExitsDemand The new exit request demand
    event SetCurrentValidatorExitsDemand(uint256 previousValidatorExitsDemand, uint256 nextValidatorExitsDemand);

    /// @notice The total requested exit has been updated
    /// @param previousTotalValidatorExitsRequested The previous total requested exit
    /// @param newTotalValidatorExitsRequested The new total requested exit
    event SetTotalValidatorExitsRequested(
        uint256 previousTotalValidatorExitsRequested, uint256 newTotalValidatorExitsRequested
    );

    /// @notice A validator key got funded on the deposit contract
    /// @notice This event was introduced during a contract upgrade, in order to cover all possible public keys, this event
    /// @notice will be replayed for past funded keys in order to have a complete coverage of all the funded public keys.
    /// @notice In this particuliar scenario, the deferred value will be set to true, to indicate that we are not going to have
    /// @notice the expected additional events and side effects in the same transaction (deposit to official DepositContract etc ...) because
    /// @notice the event was synthetically crafted.
    /// @param index The operator index
    /// @param publicKeys BLS Public key that got funded
    /// @param deferred True if event has been replayed in the context of a migration
    event FundedValidatorKeys(uint256 indexed index, bytes[] publicKeys, bool deferred);

    /// @notice The requested exit count has been update to fill the gap with the reported stopped count
    /// @param index The operator index
    /// @param oldRequestedExits The old requested exit count
    /// @param newRequestedExits The new requested exit count
    event UpdatedRequestedValidatorExitsUponStopped(
        uint256 indexed index, uint32 oldRequestedExits, uint32 newRequestedExits
    );

    /// @notice The calling operator is inactive
    /// @param index The operator index
    error InactiveOperator(uint256 index);

    /// @notice A funded key deletion has been attempted
    error InvalidFundedKeyDeletionAttempt();

    /// @notice The index provided are not sorted properly (descending order)
    error InvalidUnsortedIndexes();

    /// @notice The provided operator and limits array have different lengths
    error InvalidArrayLengths();

    /// @notice The provided operator and limits array are empty
    error InvalidEmptyArray();

    /// @notice The provided key count is 0
    error InvalidKeyCount();

    /// @notice The provided concatenated keys do not have the expected length
    error InvalidKeysLength();

    /// @notice The index that is removed is out of bounds
    error InvalidIndexOutOfBounds();

    /// @notice The value for the operator limit is too high
    /// @param index The operator index
    /// @param limit The new limit provided
    /// @param keyCount The operator key count
    error OperatorLimitTooHigh(uint256 index, uint256 limit, uint256 keyCount);

    /// @notice The value for the limit is too low
    /// @param index The operator index
    /// @param limit The new limit provided
    /// @param fundedKeyCount The operator funded key count
    error OperatorLimitTooLow(uint256 index, uint256 limit, uint256 fundedKeyCount);

    /// @notice The provided list of operators is not in increasing order
    error UnorderedOperatorList();

    /// @notice Thrown when an invalid empty stopped validator array is provided
    error InvalidEmptyStoppedValidatorCountsArray();

    /// @notice Thrown when the sum of stopped validators is invalid
    error InvalidStoppedValidatorCountsSum();

    /// @notice Throw when an element in the stopped validator array is decreasing
    error StoppedValidatorCountsDecreased();

    /// @notice Thrown when the number of elements in the array is too high compared to operator count
    error StoppedValidatorCountsTooHigh();

    /// @notice Thrown when no exit requests can be performed
    error NoExitRequestsToPerform();

    /// @notice The provided stopped validator count array is shrinking
    error StoppedValidatorCountArrayShrinking();

    /// @notice The provided stopped validator count of an operator is above its funded validator count
    error StoppedValidatorCountAboveFundedCount(uint256 operatorIndex, uint32 stoppedCount, uint32 fundedCount);

    /// @notice Initializes the operators registry
    /// @param _admin Admin in charge of managing operators
    /// @param _river Address of River system
    function initOperatorsRegistryV1(address _admin, address _river) external;

    /// @notice Initializes the operators registry for V1_1
    function initOperatorsRegistryV1_1() external;

    /// @notice Retrieve the River address
    /// @return The address of River
    function getRiver() external view returns (address);

    /// @notice Get operator details
    /// @param _index The index of the operator
    /// @return The details of the operator
    function getOperator(uint256 _index) external view returns (OperatorsV2.Operator memory);

    /// @notice Get operator count
    /// @return The operator count
    function getOperatorCount() external view returns (uint256);

    /// @notice Retrieve the stopped validator count for an operator index
    /// @param _idx The index of the operator
    /// @return The stopped validator count of the operator
    function getOperatorStoppedValidatorCount(uint256 _idx) external view returns (uint32);

    /// @notice Retrieve the total stopped validator count
    /// @return The total stopped validator count
    function getTotalStoppedValidatorCount() external view returns (uint32);

    /// @notice Retrieve the total requested exit count
    /// @notice This value is the amount of exit requests that have been performed, emitting an event for operators to catch
    /// @return The total requested exit count
    function getTotalValidatorExitsRequested() external view returns (uint256);

    /// @notice Get the current exit request demand waiting to be triggered
    /// @notice This value is the amount of exit requests that are demanded and not yet performed by the contract
    /// @return The current exit request demand
    function getCurrentValidatorExitsDemand() external view returns (uint256);

    /// @notice Retrieve the total stopped and requested exit count
    /// @return The total stopped count
    /// @return The total requested exit count
    function getStoppedAndRequestedExitCounts() external view returns (uint32, uint256);

    /// @notice Retrieve the raw stopped validators array from storage
    /// @return The stopped validator array
    function getStoppedValidatorCountPerOperator() external view returns (uint32[] memory);

    /// @notice Get the details of a validator
    /// @param _operatorIndex The index of the operator
    /// @param _validatorIndex The index of the validator
    /// @return publicKey The public key of the validator
    /// @return signature The signature used during deposit
    /// @return funded True if validator has been funded
    function getValidator(uint256 _operatorIndex, uint256 _validatorIndex)
        external
        view
        returns (bytes memory publicKey, bytes memory signature, bool funded);

    /// @notice Retrieve the active operator set
    /// @return The list of active operators and their details
    function listActiveOperators() external view returns (OperatorsV2.Operator[] memory);

    /// @notice Allows river to override the stopped validators array
    /// @notice This actions happens during the Oracle report processing
    /// @param _stoppedValidatorCounts The new stopped validators array
    /// @param _depositedValidatorCount The total deposited validator count
    function reportStoppedValidatorCounts(uint32[] calldata _stoppedValidatorCounts, uint256 _depositedValidatorCount)
        external;

    /// @notice Adds an operator to the registry
    /// @dev Only callable by the administrator
    /// @param _name The name identifying the operator
    /// @param _operator The address representing the operator, receiving the rewards
    /// @return The index of the new operator
    function addOperator(string calldata _name, address _operator) external returns (uint256);

    /// @notice Changes the operator address of an operator
    /// @dev Only callable by the administrator or the previous operator address
    /// @param _index The operator index
    /// @param _newOperatorAddress The new address of the operator
    function setOperatorAddress(uint256 _index, address _newOperatorAddress) external;

    /// @notice Changes the operator name
    /// @dev Only callable by the administrator or the operator
    /// @param _index The operator index
    /// @param _newName The new operator name
    function setOperatorName(uint256 _index, string calldata _newName) external;

    /// @notice Changes the operator status
    /// @dev Only callable by the administrator
    /// @param _index The operator index
    /// @param _newStatus The new status of the operator
    function setOperatorStatus(uint256 _index, bool _newStatus) external;

    /// @notice Changes the operator staking limit
    /// @dev Only callable by the administrator
    /// @dev The operator indexes must be in increasing order and contain no duplicate
    /// @dev The limit cannot exceed the total key count of the operator
    /// @dev The _indexes and _newLimits must have the same length.
    /// @dev Each limit value is applied to the operator index at the same index in the _indexes array.
    /// @param _operatorIndexes The operator indexes, in increasing order and duplicate free
    /// @param _newLimits The new staking limit of the operators
    /// @param _snapshotBlock The block number at which the snapshot was computed
    function setOperatorLimits(
        uint256[] calldata _operatorIndexes,
        uint32[] calldata _newLimits,
        uint256 _snapshotBlock
    ) external;

    /// @notice Adds new keys for an operator
    /// @dev Only callable by the administrator or the operator address
    /// @param _index The operator index
    /// @param _keyCount The amount of keys provided
    /// @param _publicKeysAndSignatures Public keys of the validator, concatenated
    function addValidators(uint256 _index, uint32 _keyCount, bytes calldata _publicKeysAndSignatures) external;

    /// @notice Remove validator keys
    /// @dev Only callable by the administrator or the operator address
    /// @dev The indexes must be provided sorted in decreasing order and duplicate-free, otherwise the method will revert
    /// @dev The operator limit will be set to the lowest deleted key index if the operator's limit wasn't equal to its total key count
    /// @dev The operator or the admin cannot remove funded keys
    /// @dev When removing validators, the indexes of specific unfunded keys can be changed in order to properly
    /// @dev remove the keys from the storage array. Beware of this specific behavior when chaining calls as the
    /// @dev targeted public key indexes can point to a different key after a first call was made and performed
    /// @dev some swaps
    /// @param _index The operator index
    /// @param _indexes The indexes of the keys to remove
    function removeValidators(uint256 _index, uint256[] calldata _indexes) external;

    /// @notice Retrieve validator keys based on operator statuses
    /// @param _count Max amount of keys requested
    /// @return publicKeys An array of public keys
    /// @return signatures An array of signatures linked to the public keys
    function pickNextValidatorsToDeposit(uint256 _count)
        external
        returns (bytes[] memory publicKeys, bytes[] memory signatures);

    /// @notice Public endpoint to consume the exit request demand and perform the actual exit requests
    /// @notice The selection algorithm will pick validators based on their active validator counts
    /// @notice This value is computed by using the count of funded keys and taking into account the stopped validator counts and exit requests
    /// @param _count Max amount of exits to request
    function requestValidatorExits(uint256 _count) external;

    /// @notice Increases the exit request demand
    /// @dev This method is only callable by the river contract, and to actually forward the information to the node operators via event emission, the unprotected requestValidatorExits method must be called
    /// @param _count The amount of exit requests to add to the demand
    /// @param _depositedValidatorCount The total deposited validator count
    function demandValidatorExits(uint256 _count, uint256 _depositedValidatorCount) external;
}

File 14 of 60 : IRedeemManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../state/redeemManager/RedeemQueue.sol";
import "../state/redeemManager/WithdrawalStack.sol";

/// @title Redeem Manager Interface (v1)
/// @author Kiln
/// @notice This contract handles the redeem requests of all users
interface IRedeemManagerV1 {
    /// @notice Emitted when a redeem request is created
    /// @param owner The owner of the redeem request
    /// @param height The height of the redeem request in LsETH
    /// @param amount The amount of the redeem request in LsETH
    /// @param maxRedeemableEth The maximum amount of eth that can be redeemed from this request
    /// @param id The id of the new redeem request
    event RequestedRedeem(address indexed owner, uint256 height, uint256 amount, uint256 maxRedeemableEth, uint32 id);

    /// @notice Emitted when a withdrawal event is created
    /// @param height The height of the withdrawal event in LsETH
    /// @param amount The amount of the withdrawal event in LsETH
    /// @param ethAmount The amount of eth to distrubute to claimers
    /// @param id The id of the withdrawal event
    event ReportedWithdrawal(uint256 height, uint256 amount, uint256 ethAmount, uint32 id);

    /// @notice Emitted when a redeem request has been satisfied and filled (even partially) from a withdrawal event
    /// @param redeemRequestId The id of the redeem request
    /// @param withdrawalEventId The id of the withdrawal event used to fill the request
    /// @param lsEthAmountSatisfied The amount of LsETH filled
    /// @param ethAmountSatisfied The amount of ETH filled
    /// @param lsEthAmountRemaining The amount of LsETH remaining
    /// @param ethAmountExceeding The amount of eth added to the exceeding buffer
    event SatisfiedRedeemRequest(
        uint32 indexed redeemRequestId,
        uint32 indexed withdrawalEventId,
        uint256 lsEthAmountSatisfied,
        uint256 ethAmountSatisfied,
        uint256 lsEthAmountRemaining,
        uint256 ethAmountExceeding
    );

    /// @notice Emitted when a redeem request claim has been processed and matched at least once and funds are sent to the recipient
    /// @param redeemRequestId The id of the redeem request
    /// @param recipient The address receiving the redeem request funds
    /// @param ethAmount The amount of eth retrieved
    /// @param lsEthAmount The total amount of LsETH used to redeem the eth
    /// @param remainingLsEthAmount The amount of LsETH remaining
    event ClaimedRedeemRequest(
        uint32 indexed redeemRequestId,
        address indexed recipient,
        uint256 ethAmount,
        uint256 lsEthAmount,
        uint256 remainingLsEthAmount
    );

    /// @notice Emitted when the redeem demand is set
    /// @param oldRedeemDemand The old redeem demand
    /// @param newRedeemDemand The new redeem demand
    event SetRedeemDemand(uint256 oldRedeemDemand, uint256 newRedeemDemand);

    /// @notice Emitted when the River address is set
    /// @param river The new river address
    event SetRiver(address river);

    /// @notice Thrown When a zero value is provided
    error InvalidZeroAmount();

    /// @notice Thrown when a transfer error occured with LsETH
    error TransferError();

    /// @notice Thrown when the provided arrays don't have matching lengths
    error IncompatibleArrayLengths();

    /// @notice Thrown when the provided redeem request id is out of bounds
    /// @param id The redeem request id
    error RedeemRequestOutOfBounds(uint256 id);

    /// @notice Thrown when the withdrawal request id if out of bounds
    /// @param id The withdrawal event id
    error WithdrawalEventOutOfBounds(uint256 id);

    /// @notice Thrown when	the redeem request id is already claimed
    /// @param id The redeem request id
    error RedeemRequestAlreadyClaimed(uint256 id);

    /// @notice Thrown when the redeem request and withdrawal event are not matching during claim
    /// @param redeemRequestId The provided redeem request id
    /// @param withdrawalEventId The provided associated withdrawal event id
    error DoesNotMatch(uint256 redeemRequestId, uint256 withdrawalEventId);

    /// @notice Thrown when the provided withdrawal event exceeds the redeem demand
    /// @param withdrawalAmount The amount of the withdrawal event
    /// @param redeemDemand The current redeem demand
    error WithdrawalExceedsRedeemDemand(uint256 withdrawalAmount, uint256 redeemDemand);

    /// @notice Thrown when the payment after a claim failed
    /// @param recipient The recipient of the payment
    /// @param rdata The revert data
    error ClaimRedeemFailed(address recipient, bytes rdata);

    /// @param _river The address of the River contract
    function initializeRedeemManagerV1(address _river) external;

    /// @notice Retrieve the global count of redeem requests
    function getRedeemRequestCount() external view returns (uint256);

    /// @notice Retrieve the details of a specific redeem request
    /// @param _redeemRequestId The id of the request
    /// @return The redeem request details
    function getRedeemRequestDetails(uint32 _redeemRequestId)
        external
        view
        returns (RedeemQueue.RedeemRequest memory);

    /// @notice Retrieve the global count of withdrawal events
    function getWithdrawalEventCount() external view returns (uint256);

    /// @notice Retrieve the details of a specific withdrawal event
    /// @param _withdrawalEventId The id of the withdrawal event
    /// @return The withdrawal event details
    function getWithdrawalEventDetails(uint32 _withdrawalEventId)
        external
        view
        returns (WithdrawalStack.WithdrawalEvent memory);

    /// @notice Retrieve the amount of redeemed LsETH pending to be supplied with withdrawn ETH
    /// @return The amount of eth in the buffer
    function getBufferedExceedingEth() external view returns (uint256);

    /// @notice Retrieve the amount of LsETH waiting to be exited
    /// @return The amount of LsETH waiting to be exited
    function getRedeemDemand() external view returns (uint256);

    /// @notice Resolves the provided list of redeem request ids
    /// @dev The result is an array of equal length with ids or error code
    /// @dev -1 means that the request is not satisfied yet
    /// @dev -2 means that the request is out of bounds
    /// @dev -3 means that the request has already been claimed
    /// @dev This call was created to be called by an off-chain interface, the output could then be used to perform the claimRewards call in a regular transaction
    /// @param _redeemRequestIds The list of redeem requests to resolve
    /// @return withdrawalEventIds The list of withdrawal events matching every redeem request (or error codes)
    function resolveRedeemRequests(uint32[] calldata _redeemRequestIds)
        external
        view
        returns (int64[] memory withdrawalEventIds);

    /// @notice Creates a redeem request
    /// @param _lsETHAmount The amount of LsETH to redeem
    /// @param _recipient The recipient owning the redeem request
    /// @return redeemRequestId The id of the redeem request
    function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 redeemRequestId);

    /// @notice Creates a redeem request using msg.sender as recipient
    /// @param _lsETHAmount The amount of LsETH to redeem
    /// @return redeemRequestId The id of the redeem request
    function requestRedeem(uint256 _lsETHAmount) external returns (uint32 redeemRequestId);

    /// @notice Claims the rewards of the provided redeem request ids
    /// @param _redeemRequestIds The list of redeem requests to claim
    /// @param _withdrawalEventIds The list of withdrawal events to use for every redeem request claim
    /// @param _skipAlreadyClaimed True if the call should not revert on claiming of already claimed requests
    /// @param _depth The maximum recursive depth for the resolution of the redeem requests
    /// @return claimStatuses The list of claim statuses. 0 for fully claimed, 1 for partially claimed, 2 for skipped
    function claimRedeemRequests(
        uint32[] calldata _redeemRequestIds,
        uint32[] calldata _withdrawalEventIds,
        bool _skipAlreadyClaimed,
        uint16 _depth
    ) external returns (uint8[] memory claimStatuses);

    /// @notice Claims the rewards of the provided redeem request ids
    /// @param _redeemRequestIds The list of redeem requests to claim
    /// @param _withdrawalEventIds The list of withdrawal events to use for every redeem request claim
    /// @return claimStatuses The list of claim statuses. 0 for fully claimed, 1 for partially claimed, 2 for skipped
    function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds)
        external
        returns (uint8[] memory claimStatuses);

    /// @notice Reports a withdraw event from River
    /// @param _lsETHWithdrawable The amount of LsETH that can be redeemed due to this new withdraw event
    function reportWithdraw(uint256 _lsETHWithdrawable) external payable;

    /// @notice Pulls exceeding buffer eth
    /// @param _max The maximum amount that should be pulled
    function pullExceedingEth(uint256 _max) external;
}

File 15 of 60 : IRiver.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../state/river/DailyCommittableLimits.sol";

import "./components/IConsensusLayerDepositManager.1.sol";
import "./components/IOracleManager.1.sol";
import "./components/ISharesManager.1.sol";
import "./components/IUserDepositManager.1.sol";

/// @title River Interface (v1)
/// @author Kiln
/// @notice The main system interface
interface IRiverV1 is IConsensusLayerDepositManagerV1, IUserDepositManagerV1, ISharesManagerV1, IOracleManagerV1 {
    /// @notice Funds have been pulled from the Execution Layer Fee Recipient
    /// @param amount The amount pulled
    event PulledELFees(uint256 amount);

    /// @notice Funds have been pulled from the Coverage Fund
    /// @param amount The amount pulled
    event PulledCoverageFunds(uint256 amount);

    /// @notice Emitted when funds are pulled from the redeem manager
    /// @param amount The amount pulled
    event PulledRedeemManagerExceedingEth(uint256 amount);

    /// @notice Emitted when funds are pulled from the CL recipient
    /// @param pulledSkimmedEthAmount The amount of skimmed ETH pulled
    /// @param pullExitedEthAmount The amount of exited ETH pulled
    event PulledCLFunds(uint256 pulledSkimmedEthAmount, uint256 pullExitedEthAmount);

    /// @notice The stored Execution Layer Fee Recipient has been changed
    /// @param elFeeRecipient The new Execution Layer Fee Recipient
    event SetELFeeRecipient(address indexed elFeeRecipient);

    /// @notice The stored Coverage Fund has been changed
    /// @param coverageFund The new Coverage Fund
    event SetCoverageFund(address indexed coverageFund);

    /// @notice The stored Collector has been changed
    /// @param collector The new Collector
    event SetCollector(address indexed collector);

    /// @notice The stored Allowlist has been changed
    /// @param allowlist The new Allowlist
    event SetAllowlist(address indexed allowlist);

    /// @notice The stored Global Fee has been changed
    /// @param fee The new Global Fee
    event SetGlobalFee(uint256 fee);

    /// @notice The stored Operators Registry has been changed
    /// @param operatorRegistry The new Operators Registry
    event SetOperatorsRegistry(address indexed operatorRegistry);

    /// @notice The stored Metadata URI string has been changed
    /// @param metadataURI The new Metadata URI string
    event SetMetadataURI(string metadataURI);

    /// @notice The system underlying supply increased. This is a snapshot of the balances for accounting purposes
    /// @param _collector The address of the collector during this event
    /// @param _oldTotalUnderlyingBalance Old total ETH balance under management by River
    /// @param _oldTotalSupply Old total supply in shares
    /// @param _newTotalUnderlyingBalance New total ETH balance under management by River
    /// @param _newTotalSupply New total supply in shares
    event RewardsEarned(
        address indexed _collector,
        uint256 _oldTotalUnderlyingBalance,
        uint256 _oldTotalSupply,
        uint256 _newTotalUnderlyingBalance,
        uint256 _newTotalSupply
    );

    /// @notice Emitted when the daily committable limits are changed
    /// @param minNetAmount The minimum amount that must be used as the daily committable amount
    /// @param maxRelativeAmount The maximum amount that can be used as the daily committable amount, relative to the total underlying supply
    event SetMaxDailyCommittableAmounts(uint256 minNetAmount, uint256 maxRelativeAmount);

    /// @notice Emitted when the redeem manager address is changed
    /// @param redeemManager The address of the redeem manager
    event SetRedeemManager(address redeemManager);

    /// @notice Emitted when the balance to deposit is updated
    /// @param oldAmount The old balance to deposit
    /// @param newAmount The new balance to deposit
    event SetBalanceToDeposit(uint256 oldAmount, uint256 newAmount);

    /// @notice Emitted when the balance to redeem is updated
    /// @param oldAmount The old balance to redeem
    /// @param newAmount The new balance to redeem
    event SetBalanceToRedeem(uint256 oldAmount, uint256 newAmount);

    /// @notice Emitted when the balance committed to deposit
    /// @param oldAmount The old balance committed to deposit
    /// @param newAmount The new balance committed to deposit
    event SetBalanceCommittedToDeposit(uint256 oldAmount, uint256 newAmount);

    /// @notice Emitted when the redeem manager received a withdraw event report
    /// @param redeemManagerDemand The total demand in LsETH of the redeem manager
    /// @param suppliedRedeemManagerDemand The amount of LsETH demand actually supplied
    /// @param suppliedRedeemManagerDemandInEth The amount in ETH of the supplied demand
    event ReportedRedeemManager(
        uint256 redeemManagerDemand, uint256 suppliedRedeemManagerDemand, uint256 suppliedRedeemManagerDemandInEth
    );

    /// @notice Thrown when the amount received from the Withdraw contract doe not match the requested amount
    /// @param requested The amount that was requested
    /// @param received The amount that was received
    error InvalidPulledClFundsAmount(uint256 requested, uint256 received);

    /// @notice The computed amount of shares to mint is 0
    error ZeroMintedShares();

    /// @notice The access was denied
    /// @param account The account that was denied
    error Denied(address account);

    /// @notice Initializes the River system
    /// @param _depositContractAddress Address to make Consensus Layer deposits
    /// @param _elFeeRecipientAddress Address that receives the execution layer fees
    /// @param _withdrawalCredentials Credentials to use for every validator deposit
    /// @param _oracleAddress The address of the Oracle contract
    /// @param _systemAdministratorAddress Administrator address
    /// @param _allowlistAddress Address of the allowlist contract
    /// @param _operatorRegistryAddress Address of the operator registry
    /// @param _collectorAddress Address receiving the the global fee on revenue
    /// @param _globalFee Amount retained when the ETH balance increases and sent to the collector
    function initRiverV1(
        address _depositContractAddress,
        address _elFeeRecipientAddress,
        bytes32 _withdrawalCredentials,
        address _oracleAddress,
        address _systemAdministratorAddress,
        address _allowlistAddress,
        address _operatorRegistryAddress,
        address _collectorAddress,
        uint256 _globalFee
    ) external;

    /// @notice Initialized version 1.1 of the River System
    /// @param _redeemManager The redeem manager address
    /// @param _epochsPerFrame The amounts of epochs in a frame
    /// @param _slotsPerEpoch The slots inside an epoch
    /// @param _secondsPerSlot The seconds inside a slot
    /// @param _genesisTime The genesis timestamp
    /// @param _epochsToAssumedFinality The number of epochs before an epoch is considered final on-chain
    /// @param _annualAprUpperBound The reporting upper bound
    /// @param _relativeLowerBound The reporting lower bound
    /// @param _maxDailyNetCommittableAmount_ The net daily committable limit
    /// @param _maxDailyRelativeCommittableAmount_ The relative daily committable limit
    function initRiverV1_1(
        address _redeemManager,
        uint64 _epochsPerFrame,
        uint64 _slotsPerEpoch,
        uint64 _secondsPerSlot,
        uint64 _genesisTime,
        uint64 _epochsToAssumedFinality,
        uint256 _annualAprUpperBound,
        uint256 _relativeLowerBound,
        uint128 _maxDailyNetCommittableAmount_,
        uint128 _maxDailyRelativeCommittableAmount_
    ) external;

    /// @notice Initializes version 1.2 of the River System
    function initRiverV1_2() external;

    /// @notice Get the current global fee
    /// @return The global fee
    function getGlobalFee() external view returns (uint256);

    /// @notice Retrieve the allowlist address
    /// @return The allowlist address
    function getAllowlist() external view returns (address);

    /// @notice Retrieve the collector address
    /// @return The collector address
    function getCollector() external view returns (address);

    /// @notice Retrieve the execution layer fee recipient
    /// @return The execution layer fee recipient address
    function getELFeeRecipient() external view returns (address);

    /// @notice Retrieve the coverage fund
    /// @return The coverage fund address
    function getCoverageFund() external view returns (address);

    /// @notice Retrieve the redeem manager
    /// @return The redeem manager address
    function getRedeemManager() external view returns (address);

    /// @notice Retrieve the operators registry
    /// @return The operators registry address
    function getOperatorsRegistry() external view returns (address);

    /// @notice Retrieve the metadata uri string value
    /// @return The metadata uri string value
    function getMetadataURI() external view returns (string memory);

    /// @notice Retrieve the configured daily committable limits
    /// @return The daily committable limits structure
    function getDailyCommittableLimits()
        external
        view
        returns (DailyCommittableLimits.DailyCommittableLimitsStruct memory);

    /// @notice Resolves the provided redeem requests by calling the redeem manager
    /// @param _redeemRequestIds The list of redeem requests to resolve
    /// @return withdrawalEventIds The list of matching withdrawal events, or error codes
    function resolveRedeemRequests(uint32[] calldata _redeemRequestIds)
        external
        view
        returns (int64[] memory withdrawalEventIds);

    /// @notice Set the daily committable limits
    /// @param _dcl The Daily Committable Limits structure
    function setDailyCommittableLimits(DailyCommittableLimits.DailyCommittableLimitsStruct memory _dcl) external;

    /// @notice Retrieve the current balance to redeem
    /// @return The current balance to redeem
    function getBalanceToRedeem() external view returns (uint256);

    /// @notice Performs a redeem request on the redeem manager
    /// @param _lsETHAmount The amount of LsETH to redeem
    /// @param _recipient The address that will own the redeem request
    /// @return redeemRequestId The ID of the newly created redeem request
    function requestRedeem(uint256 _lsETHAmount, address _recipient) external returns (uint32 redeemRequestId);

    /// @notice Claims several redeem requests
    /// @param _redeemRequestIds The list of redeem requests to claim
    /// @param _withdrawalEventIds The list of resolved withdrawal event ids
    /// @return claimStatuses The operation status results
    function claimRedeemRequests(uint32[] calldata _redeemRequestIds, uint32[] calldata _withdrawalEventIds)
        external
        returns (uint8[] memory claimStatuses);

    /// @notice Changes the global fee parameter
    /// @param _newFee New fee value
    function setGlobalFee(uint256 _newFee) external;

    /// @notice Changes the allowlist address
    /// @param _newAllowlist New address for the allowlist
    function setAllowlist(address _newAllowlist) external;

    /// @notice Changes the collector address
    /// @param _newCollector New address for the collector
    function setCollector(address _newCollector) external;

    /// @notice Changes the execution layer fee recipient
    /// @param _newELFeeRecipient New address for the recipient
    function setELFeeRecipient(address _newELFeeRecipient) external;

    /// @notice Changes the coverage fund
    /// @param _newCoverageFund New address for the fund
    function setCoverageFund(address _newCoverageFund) external;

    /// @notice Sets the metadata uri string value
    /// @param _metadataURI The new metadata uri string value
    function setMetadataURI(string memory _metadataURI) external;

    /// @notice Input for execution layer fee earnings
    function sendELFees() external payable;

    /// @notice Input for consensus layer funds, containing both exit and skimming
    function sendCLFunds() external payable;

    /// @notice Input for coverage funds
    function sendCoverageFunds() external payable;

    /// @notice Input for the redeem manager funds
    function sendRedeemManagerExceedingFunds() external payable;
}

File 16 of 60 : IWithdraw.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Withdraw Interface (V1)
/// @author Kiln
/// @notice This contract is in charge of holding the exit and skimming funds and allow river to pull these funds
interface IWithdrawV1 {
    /// @notice Emitted when the linked River address is changed
    /// @param river The new River address
    event SetRiver(address river);

    /// @param _river The address of the River contract
    function initializeWithdrawV1(address _river) external;

    /// @notice Retrieve the withdrawal credentials to use
    /// @return The withdrawal credentials
    function getCredentials() external view returns (bytes32);

    /// @notice Retrieve the linked River address
    /// @return The River address
    function getRiver() external view returns (address);

    /// @notice Callable by River, sends the specified amount of ETH to River
    /// @param _amount The amount to pull
    function pullEth(uint256 _amount) external;
}

File 17 of 60 : IConsensusLayerDepositManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Consensys Layer Deposit Manager Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the interactions with the official deposit contract
interface IConsensusLayerDepositManagerV1 {
    /// @notice The stored deposit contract address changed
    /// @param depositContract Address of the deposit contract
    event SetDepositContractAddress(address indexed depositContract);

    /// @notice The stored withdrawal credentials changed
    /// @param withdrawalCredentials The withdrawal credentials to use for deposits
    event SetWithdrawalCredentials(bytes32 withdrawalCredentials);

    /// @notice Emitted when the deposited validator count is updated
    /// @param oldDepositedValidatorCount The old deposited validator count value
    /// @param newDepositedValidatorCount The new deposited validator count value
    event SetDepositedValidatorCount(uint256 oldDepositedValidatorCount, uint256 newDepositedValidatorCount);

    /// @notice Not enough funds to deposit one validator
    error NotEnoughFunds();

    /// @notice The length of the BLS Public key is invalid during deposit
    error InconsistentPublicKeys();

    /// @notice The length of the BLS Signature is invalid during deposit
    error InconsistentSignatures();

    /// @notice The internal key retrieval returned no keys
    error NoAvailableValidatorKeys();

    /// @notice The received count of public keys to deposit is invalid
    error InvalidPublicKeyCount();

    /// @notice The received count of signatures to deposit is invalid
    error InvalidSignatureCount();

    /// @notice The withdrawal credentials value is null
    error InvalidWithdrawalCredentials();

    /// @notice An error occured during the deposit
    error ErrorOnDeposit();

    /// @notice Returns the amount of ETH not yet committed for deposit
    /// @return The amount of ETH not yet committed for deposit
    function getBalanceToDeposit() external view returns (uint256);

    /// @notice Returns the amount of ETH committed for deposit
    /// @return The amount of ETH committed for deposit
    function getCommittedBalance() external view returns (uint256);

    /// @notice Retrieve the withdrawal credentials
    /// @return The withdrawal credentials
    function getWithdrawalCredentials() external view returns (bytes32);

    /// @notice Get the deposited validator count (the count of deposits made by the contract)
    /// @return The deposited validator count
    function getDepositedValidatorCount() external view returns (uint256);

    /// @notice Deposits current balance to the Consensus Layer by batches of 32 ETH
    /// @param _maxCount The maximum amount of validator keys to fund
    function depositToConsensusLayer(uint256 _maxCount) external;
}

File 18 of 60 : IOracleManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../state/river/CLSpec.sol";
import "../../state/river/ReportBounds.sol";

/// @title Oracle Manager (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the inputs provided by the oracle
interface IOracleManagerV1 {
    /// @notice The stored oracle address changed
    /// @param oracleAddress The new oracle address
    event SetOracle(address indexed oracleAddress);

    /// @notice The consensus layer data provided by the oracle has been updated
    /// @param validatorCount The new count of validators running on the consensus layer
    /// @param validatorTotalBalance The new total balance sum of all validators
    /// @param roundId Round identifier
    event ConsensusLayerDataUpdate(uint256 validatorCount, uint256 validatorTotalBalance, bytes32 roundId);

    /// @notice The Consensus Layer Spec is changed
    /// @param epochsPerFrame The number of epochs inside a frame
    /// @param slotsPerEpoch The number of slots inside an epoch
    /// @param secondsPerSlot The number of seconds inside a slot
    /// @param genesisTime The genesis timestamp
    /// @param epochsToAssumedFinality The number of epochs before an epoch is considered final
    event SetSpec(
        uint64 epochsPerFrame,
        uint64 slotsPerEpoch,
        uint64 secondsPerSlot,
        uint64 genesisTime,
        uint64 epochsToAssumedFinality
    );

    /// @notice The Report Bounds are changed
    /// @param annualAprUpperBound The reporting upper bound
    /// @param relativeLowerBound The reporting lower bound
    event SetBounds(uint256 annualAprUpperBound, uint256 relativeLowerBound);

    /// @notice The provided report has beend processed
    /// @param report The report that was provided
    /// @param trace The trace structure providing more insights on internals
    event ProcessedConsensusLayerReport(
        IOracleManagerV1.ConsensusLayerReport report, ConsensusLayerDataReportingTrace trace
    );

    /// @notice The reported validator count is invalid
    /// @param providedValidatorCount The received validator count value
    /// @param depositedValidatorCount The number of deposits performed by the system
    /// @param lastReportedValidatorCount The last reported validator count
    error InvalidValidatorCountReport(
        uint256 providedValidatorCount, uint256 depositedValidatorCount, uint256 lastReportedValidatorCount
    );

    /// @notice Thrown when an invalid epoch was reported
    /// @param epoch Invalid epoch
    error InvalidEpoch(uint256 epoch);

    /// @notice The balance increase is higher than the maximum allowed by the upper bound
    /// @param prevTotalEthIncludingExited The previous total balance, including all exited balance
    /// @param postTotalEthIncludingExited The post-report total balance, including all exited balance
    /// @param timeElapsed The time in seconds since last report
    /// @param annualAprUpperBound The upper bound value that was used
    error TotalValidatorBalanceIncreaseOutOfBound(
        uint256 prevTotalEthIncludingExited,
        uint256 postTotalEthIncludingExited,
        uint256 timeElapsed,
        uint256 annualAprUpperBound
    );

    /// @notice The balance decrease is higher than the maximum allowed by the lower bound
    /// @param prevTotalEthIncludingExited The previous total balance, including all exited balance
    /// @param postTotalEthIncludingExited The post-report total balance, including all exited balance
    /// @param timeElapsed The time in seconds since last report
    /// @param relativeLowerBound The lower bound value that was used
    error TotalValidatorBalanceDecreaseOutOfBound(
        uint256 prevTotalEthIncludingExited,
        uint256 postTotalEthIncludingExited,
        uint256 timeElapsed,
        uint256 relativeLowerBound
    );

    /// @notice The total exited balance decreased
    /// @param currentValidatorsExitedBalance The current exited balance
    /// @param newValidatorsExitedBalance The new exited balance
    error InvalidDecreasingValidatorsExitedBalance(
        uint256 currentValidatorsExitedBalance, uint256 newValidatorsExitedBalance
    );

    /// @notice The total skimmed balance decreased
    /// @param currentValidatorsSkimmedBalance The current exited balance
    /// @param newValidatorsSkimmedBalance The new exited balance
    error InvalidDecreasingValidatorsSkimmedBalance(
        uint256 currentValidatorsSkimmedBalance, uint256 newValidatorsSkimmedBalance
    );

    /// @notice Trace structure emitted via logs during reporting
    struct ConsensusLayerDataReportingTrace {
        uint256 rewards;
        uint256 pulledELFees;
        uint256 pulledRedeemManagerExceedingEthBuffer;
        uint256 pulledCoverageFunds;
    }

    /// @notice The format of the oracle report
    struct ConsensusLayerReport {
        // this is the epoch at which the report was performed
        // data should be fetched up to the state of this epoch by the oracles
        uint256 epoch;
        // the sum of all the validator balances on the consensus layer
        // when a validator enters the exit queue, the validator is considered stopped, its balance is accounted in both validatorsExitingBalance and validatorsBalance
        // when a validator leaves the exit queue and the funds are sweeped onto the execution layer, the balance is only accounted in validatorsExitedBalance and not in validatorsBalance
        // this value can decrease between reports
        uint256 validatorsBalance;
        // the sum of all the skimmings performed on the validators
        // these values can be found in the execution layer block bodies under the withdrawals field
        // a withdrawal is considered skimming if
        // - the epoch at which it happened is < validator.withdrawableEpoch
        // - the epoch at which it happened is >= validator.withdrawableEpoch and in that case we only account for what would be above 32 eth as skimming
        // this value cannot decrease over reports
        uint256 validatorsSkimmedBalance;
        // the sum of all the exits performed on the validators
        // these values can be found in the execution layer block bodies under the withdrawals field
        // a withdrawal is considered exit if
        // - the epoch at which it happened is >= validator.withdrawableEpoch and in that case we only account for what would be <= 32 eth as exit
        // this value cannot decrease over reports
        uint256 validatorsExitedBalance;
        // the sum of all the exiting balance, which is all the validators on their way to get sweeped and exited
        // this includes voluntary exits and slashings
        // this value can decrease between reports
        uint256 validatorsExitingBalance;
        // the count of activated validators
        // even validators that are exited are still accounted
        // this value cannot decrease over reports
        uint32 validatorsCount;
        // an array containing the count of stopped validators per operator
        // the first element of the array is the sum of all stopped validators
        // then index 1 would be operator 0
        // these values cannot decrease over reports
        uint32[] stoppedValidatorCountPerOperator;
        // flag enabled by the oracles when the buffer rebalancing is activated
        // the activation logic is written in the oracle specification and all oracle members must agree on the activation
        // when active, the eth in the deposit buffer can be used to pay for exits in the redeem manager
        bool rebalanceDepositToRedeemMode;
        // flag enabled by the oracles when the slashing containment is activated
        // the activation logic is written in the oracle specification and all oracle members must agree on the activation
        // This flag is activated when a pre-defined threshold of slashed validators in our set of validators is reached
        // This flag is deactivated when a bottom threshold is met, this means that when we reach the upper threshold and activate the flag, we will deactivate it when we reach the bottom threshold and not before
        // when active, no more validator exits can be requested by the protocol
        bool slashingContainmentMode;
    }

    /// @notice The format of the oracle report in storage
    /// @notice These fields have the exact same function as the ones in ConsensusLayerReport, but this struct is optimized for storage
    struct StoredConsensusLayerReport {
        uint256 epoch;
        uint256 validatorsBalance;
        uint256 validatorsSkimmedBalance;
        uint256 validatorsExitedBalance;
        uint256 validatorsExitingBalance;
        uint32 validatorsCount;
        bool rebalanceDepositToRedeemMode;
        bool slashingContainmentMode;
    }

    /// @notice Get oracle address
    /// @return The oracle address
    function getOracle() external view returns (address);

    /// @notice Get CL validator total balance
    /// @return The CL Validator total balance
    function getCLValidatorTotalBalance() external view returns (uint256);

    /// @notice Get CL validator count (the amount of validator reported by the oracles)
    /// @return The CL validator count
    function getCLValidatorCount() external view returns (uint256);

    /// @notice Verifies if the provided epoch is valid
    /// @param epoch The epoch to lookup
    /// @return True if valid
    function isValidEpoch(uint256 epoch) external view returns (bool);

    /// @notice Retrieve the block timestamp
    /// @return The current timestamp from the EVM context
    function getTime() external view returns (uint256);

    /// @notice Retrieve expected epoch id
    /// @return The current expected epoch id
    function getExpectedEpochId() external view returns (uint256);

    /// @notice Retrieve the last completed epoch id
    /// @return The last completed epoch id
    function getLastCompletedEpochId() external view returns (uint256);

    /// @notice Retrieve the current epoch id based on block timestamp
    /// @return The current epoch id
    function getCurrentEpochId() external view returns (uint256);

    /// @notice Retrieve the current cl spec
    /// @return The Consensus Layer Specification
    function getCLSpec() external view returns (CLSpec.CLSpecStruct memory);

    /// @notice Retrieve the current frame details
    /// @return _startEpochId The epoch at the beginning of the frame
    /// @return _startTime The timestamp of the beginning of the frame in seconds
    /// @return _endTime The timestamp of the end of the frame in seconds
    function getCurrentFrame() external view returns (uint256 _startEpochId, uint256 _startTime, uint256 _endTime);

    /// @notice Retrieve the first epoch id of the frame of the provided epoch id
    /// @param _epochId Epoch id used to get the frame
    /// @return The first epoch id of the frame containing the given epoch id
    function getFrameFirstEpochId(uint256 _epochId) external view returns (uint256);

    /// @notice Retrieve the report bounds
    /// @return The report bounds
    function getReportBounds() external view returns (ReportBounds.ReportBoundsStruct memory);

    /// @notice Retrieve the last consensus layer report
    /// @return The stored consensus layer report
    function getLastConsensusLayerReport() external view returns (IOracleManagerV1.StoredConsensusLayerReport memory);

    /// @notice Set the oracle address
    /// @param _oracleAddress Address of the oracle
    function setOracle(address _oracleAddress) external;

    /// @notice Set the consensus layer spec
    /// @param _newValue The new consensus layer spec value
    function setCLSpec(CLSpec.CLSpecStruct calldata _newValue) external;

    /// @notice Set the report bounds
    /// @param _newValue The new report bounds value
    function setReportBounds(ReportBounds.ReportBoundsStruct calldata _newValue) external;

    /// @notice Performs all the reporting logics
    /// @param _report The consensus layer report structure
    function setConsensusLayerData(ConsensusLayerReport calldata _report) external;
}

File 19 of 60 : ISharesManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";

/// @title Shares Manager Interface (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the shares of the depositor and the ERC20 interface
interface ISharesManagerV1 is IERC20 {
    /// @notice Emitted when the total supply is changed
    event SetTotalSupply(uint256 totalSupply);

    /// @notice Balance too low to perform operation
    error BalanceTooLow();

    /// @notice Allowance too low to perform operation
    /// @param _from Account where funds are sent from
    /// @param _operator Account attempting the transfer
    /// @param _allowance Current allowance
    /// @param _value Requested transfer value in shares
    error AllowanceTooLow(address _from, address _operator, uint256 _allowance, uint256 _value);

    /// @notice Invalid empty transfer
    error NullTransfer();

    /// @notice Invalid transfer recipients
    /// @param _from Account sending the funds in the invalid transfer
    /// @param _to Account receiving the funds in the invalid transfer
    error UnauthorizedTransfer(address _from, address _to);

    /// @notice Retrieve the token name
    /// @return The token name
    function name() external pure returns (string memory);

    /// @notice Retrieve the token symbol
    /// @return The token symbol
    function symbol() external pure returns (string memory);

    /// @notice Retrieve the decimal count
    /// @return The decimal count
    function decimals() external pure returns (uint8);

    /// @notice Retrieve the total token supply
    /// @return The total supply in shares
    function totalSupply() external view returns (uint256);

    /// @notice Retrieve the total underlying asset supply
    /// @return The total underlying asset supply
    function totalUnderlyingSupply() external view returns (uint256);

    /// @notice Retrieve the balance of an account
    /// @param _owner Address to be checked
    /// @return The balance of the account in shares
    function balanceOf(address _owner) external view returns (uint256);

    /// @notice Retrieve the underlying asset balance of an account
    /// @param _owner Address to be checked
    /// @return The underlying balance of the account
    function balanceOfUnderlying(address _owner) external view returns (uint256);

    /// @notice Retrieve the underlying asset balance from an amount of shares
    /// @param _shares Amount of shares to convert
    /// @return The underlying asset balance represented by the shares
    function underlyingBalanceFromShares(uint256 _shares) external view returns (uint256);

    /// @notice Retrieve the shares count from an underlying asset amount
    /// @param _underlyingAssetAmount Amount of underlying asset to convert
    /// @return The amount of shares worth the underlying asset amopunt
    function sharesFromUnderlyingBalance(uint256 _underlyingAssetAmount) external view returns (uint256);

    /// @notice Retrieve the allowance value for a spender
    /// @param _owner Address that issued the allowance
    /// @param _spender Address that received the allowance
    /// @return The allowance in shares for a given spender
    function allowance(address _owner, address _spender) external view returns (uint256);

    /// @notice Performs a transfer from the message sender to the provided account
    /// @param _to Address receiving the tokens
    /// @param _value Amount of shares to be sent
    /// @return True if success
    function transfer(address _to, uint256 _value) external returns (bool);

    /// @notice Performs a transfer between two recipients
    /// @param _from Address sending the tokens
    /// @param _to Address receiving the tokens
    /// @param _value Amount of shares to be sent
    /// @return True if success
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool);

    /// @notice Approves an account for future spendings
    /// @dev An approved account can use transferFrom to transfer funds on behalf of the token owner
    /// @param _spender Address that is allowed to spend the tokens
    /// @param _value The allowed amount in shares, will override previous value
    /// @return True if success
    function approve(address _spender, uint256 _value) external returns (bool);

    /// @notice Increase allowance to another account
    /// @param _spender Spender that receives the allowance
    /// @param _additionalValue Amount of shares to add
    /// @return True if success
    function increaseAllowance(address _spender, uint256 _additionalValue) external returns (bool);

    /// @notice Decrease allowance to another account
    /// @param _spender Spender that receives the allowance
    /// @param _subtractableValue Amount of shares to subtract
    /// @return True if success
    function decreaseAllowance(address _spender, uint256 _subtractableValue) external returns (bool);
}

File 20 of 60 : IUserDepositManager.1.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title User Deposit Manager (v1)
/// @author Kiln
/// @notice This interface exposes methods to handle the inbound transfers cases or the explicit submissions
interface IUserDepositManagerV1 {
    /// @notice User deposited ETH in the system
    /// @param depositor Address performing the deposit
    /// @param recipient Address receiving the minted shares
    /// @param amount Amount in ETH deposited
    event UserDeposit(address indexed depositor, address indexed recipient, uint256 amount);

    /// @notice And empty deposit attempt was made
    error EmptyDeposit();

    /// @notice Explicit deposit method to mint on msg.sender
    function deposit() external payable;

    /// @notice Explicit deposit method to mint on msg.sender and transfer to _recipient
    /// @param _recipient Address receiving the minted LsETH
    function depositAndTransfer(address _recipient) external payable;

    /// @notice Implicit deposit method, when the user performs a regular transfer to the contract
    receive() external payable;

    /// @notice Invalid call, when the user sends a transaction with a data payload but no method matched
    fallback() external payable;
}

File 21 of 60 : LibAdministrable.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../state/shared/AdministratorAddress.sol";
import "../state/shared/PendingAdministratorAddress.sol";

/// @title Lib Administrable
/// @author Kiln
/// @notice This library handles the admin and pending admin storage vars
library LibAdministrable {
    /// @notice Retrieve the system admin
    /// @return The address of the system admin
    function _getAdmin() internal view returns (address) {
        return AdministratorAddress.get();
    }

    /// @notice Retrieve the pending system admin
    /// @return The adress of the pending system admin
    function _getPendingAdmin() internal view returns (address) {
        return PendingAdministratorAddress.get();
    }

    /// @notice Sets the system admin
    /// @param _admin New system admin
    function _setAdmin(address _admin) internal {
        AdministratorAddress.set(_admin);
    }

    /// @notice Sets the pending system admin
    /// @param _pendingAdmin New pending system admin
    function _setPendingAdmin(address _pendingAdmin) internal {
        PendingAdministratorAddress.set(_pendingAdmin);
    }
}

File 22 of 60 : LibAllowlistMasks.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Lib Allowlist Masks
/// @notice Holds all the mask values
library LibAllowlistMasks {
    /// @notice Mask used for denied accounts
    uint256 internal constant DENY_MASK = 0x1 << 255;
    /// @notice The mask for the deposit right
    uint256 internal constant DEPOSIT_MASK = 0x1;
    /// @notice The mask for the donation right
    uint256 internal constant DONATE_MASK = 0x1 << 1;
    /// @notice The mask for the redeem right
    uint256 internal constant REDEEM_MASK = 0x1 << 2;
}

File 23 of 60 : LibBasisPoints.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Lib Basis Points
/// @notice Holds the basis points max value
library LibBasisPoints {
    /// @notice The max value for basis points (represents 100%)
    uint256 internal constant BASIS_POINTS_MAX = 10_000;
}

File 24 of 60 : LibBytes.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

/// @title Lib Bytes
/// @notice This library helps manipulating bytes
library LibBytes {
    /// @notice The length overflows an uint
    error SliceOverflow();

    /// @notice The slice is outside of the initial bytes bounds
    error SliceOutOfBounds();

    /// @notice Slices the provided bytes
    /// @param _bytes Bytes to slice
    /// @param _start The starting index of the slice
    /// @param _length The length of the slice
    /// @return The slice of _bytes starting at _start of length _length
    function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
        unchecked {
            if (_length + 31 < _length) {
                revert SliceOverflow();
            }
        }
        if (_bytes.length < _start + _length) {
            revert SliceOutOfBounds();
        }

        bytes memory tempBytes;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } { mstore(mc, mload(cc)) }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }
}

File 25 of 60 : LibErrors.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

/// @title Lib Errors
/// @notice Library of common errors
library LibErrors {
    /// @notice The operator is unauthorized for the caller
    /// @param caller Address performing the call
    error Unauthorized(address caller);

    /// @notice The call was invalid
    error InvalidCall();

    /// @notice The argument was invalid
    error InvalidArgument();

    /// @notice The address is zero
    error InvalidZeroAddress();

    /// @notice The string is empty
    error InvalidEmptyString();

    /// @notice The fee is invalid
    error InvalidFee();
}

File 26 of 60 : LibSanitize.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "./LibErrors.sol";
import "./LibBasisPoints.sol";

/// @title Lib Sanitize
/// @notice Utilities to sanitize input values
library LibSanitize {
    /// @notice Reverts if address is 0
    /// @param _address Address to check
    function _notZeroAddress(address _address) internal pure {
        if (_address == address(0)) {
            revert LibErrors.InvalidZeroAddress();
        }
    }

    /// @notice Reverts if string is empty
    /// @param _string String to check
    function _notEmptyString(string memory _string) internal pure {
        if (bytes(_string).length == 0) {
            revert LibErrors.InvalidEmptyString();
        }
    }

    /// @notice Reverts if fee is invalid
    /// @param _fee Fee to check
    function _validFee(uint256 _fee) internal pure {
        if (_fee > LibBasisPoints.BASIS_POINTS_MAX) {
            revert LibErrors.InvalidFee();
        }
    }
}

File 27 of 60 : LibUint256.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

/// @title Lib Uint256
/// @notice Utilities to perform uint operations
library LibUint256 {
    /// @notice Converts a value to little endian (64 bits)
    /// @param _value The value to convert
    /// @return result The converted value
    function toLittleEndian64(uint256 _value) internal pure returns (uint256 result) {
        result = 0;
        uint256 tempValue = _value;
        result = tempValue & 0xFF;
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        result = (result << 8) | (tempValue & 0xFF);
        tempValue >>= 8;

        assert(0 == tempValue); // fully converted
        result <<= (24 * 8);
    }

    /// @notice Returns the minimum value
    /// @param _a First value
    /// @param _b Second value
    /// @return Smallest value between _a and _b
    function min(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return (_a > _b ? _b : _a);
    }

    /// @notice Returns the max value
    /// @param _a First value
    /// @param _b Second value
    /// @return Highest value between _a and _b
    function max(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return (_a < _b ? _b : _a);
    }

    /// @notice Performs a ceiled division
    /// @param _a Numerator
    /// @param _b Denominator
    /// @return ceil(_a / _b)
    function ceil(uint256 _a, uint256 _b) internal pure returns (uint256) {
        return (_a / _b) + (_a % _b > 0 ? 1 : 0);
    }
}

File 28 of 60 : LibUnstructuredStorage.sol
// SPDX-License-Identifier:    MIT

pragma solidity 0.8.10;

/// @title Lib Unstructured Storage
/// @notice Utilities to work with unstructured storage
library LibUnstructuredStorage {
    /// @notice Retrieve a bool value at a storage slot
    /// @param _position The storage slot to retrieve
    /// @return data The bool value
    function getStorageBool(bytes32 _position) internal view returns (bool data) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            data := sload(_position)
        }
    }

    /// @notice Retrieve an address value at a storage slot
    /// @param _position The storage slot to retrieve
    /// @return data The address value
    function getStorageAddress(bytes32 _position) internal view returns (address data) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            data := sload(_position)
        }
    }

    /// @notice Retrieve a bytes32 value at a storage slot
    /// @param _position The storage slot to retrieve
    /// @return data The bytes32 value
    function getStorageBytes32(bytes32 _position) internal view returns (bytes32 data) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            data := sload(_position)
        }
    }

    /// @notice Retrieve an uint256 value at a storage slot
    /// @param _position The storage slot to retrieve
    /// @return data The uint256 value
    function getStorageUint256(bytes32 _position) internal view returns (uint256 data) {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            data := sload(_position)
        }
    }

    /// @notice Sets a bool value at a storage slot
    /// @param _position The storage slot to set
    /// @param _data The bool value to set
    function setStorageBool(bytes32 _position, bool _data) internal {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_position, _data)
        }
    }

    /// @notice Sets an address value at a storage slot
    /// @param _position The storage slot to set
    /// @param _data The address value to set
    function setStorageAddress(bytes32 _position, address _data) internal {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_position, _data)
        }
    }

    /// @notice Sets a bytes32 value at a storage slot
    /// @param _position The storage slot to set
    /// @param _data The bytes32 value to set
    function setStorageBytes32(bytes32 _position, bytes32 _data) internal {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_position, _data)
        }
    }

    /// @notice Sets an uint256 value at a storage slot
    /// @param _position The storage slot to set
    /// @param _data The uint256 value to set
    function setStorageUint256(bytes32 _position, uint256 _data) internal {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            sstore(_position, _data)
        }
    }
}

File 29 of 60 : Operators.2.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibSanitize.sol";

/// @title Operators Storage
/// @notice Utility to manage the Operators in storage
library OperatorsV2 {
    /// @notice Storage slot of the Operators
    bytes32 internal constant OPERATORS_SLOT = bytes32(uint256(keccak256("river.state.v2.operators")) - 1);

    /// @notice The Operator structure in storage
    struct Operator {
        /// @dev The following values respect this invariant:
        /// @dev     keys >= limit >= funded >= RequestedExits

        /// @custom:attribute Staking limit of the operator
        uint32 limit;
        /// @custom:attribute The count of funded validators
        uint32 funded;
        /// @custom:attribute The count of exit requests made to this operator
        uint32 requestedExits;
        /// @custom:attribute The total count of keys of the operator
        uint32 keys;
        /// @custom attribute The block at which the last edit happened in the operator details
        uint64 latestKeysEditBlockNumber;
        /// @custom:attribute True if the operator is active and allowed to operate on River
        bool active;
        /// @custom:attribute Display name of the operator
        string name;
        /// @custom:attribute Address of the operator
        address operator;
    }

    /// @notice The Operator structure when loaded in memory
    struct CachedOperator {
        /// @custom:attribute Staking limit of the operator
        uint32 limit;
        /// @custom:attribute The count of funded validators
        uint32 funded;
        /// @custom:attribute The count of exit requests made to this operator
        uint32 requestedExits;
        /// @custom:attribute The original index of the operator
        uint32 index;
        /// @custom:attribute The amount of picked keys, buffer used before changing funded in storage
        uint32 picked;
    }

    /// @notice The Operator structure when loaded in memory for the exit selection
    struct CachedExitableOperator {
        /// @custom:attribute The count of funded validators
        uint32 funded;
        /// @custom:attribute The count of exit requests made to this operator
        uint32 requestedExits;
        /// @custom:attribute The original index of the operator
        uint32 index;
        /// @custom:attribute The amount of picked keys, buffer used before changing funded in storage
        uint32 picked;
    }

    /// @notice The structure at the storage slot
    struct SlotOperator {
        /// @custom:attribute Array containing all the operators
        Operator[] value;
    }

    /// @notice The operator was not found
    /// @param index The provided index
    error OperatorNotFound(uint256 index);

    /// @notice Retrieve the operator in storage
    /// @param _index The index of the operator
    /// @return The Operator structure
    function get(uint256 _index) internal view returns (Operator storage) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        if (r.value.length <= _index) {
            revert OperatorNotFound(_index);
        }

        return r.value[_index];
    }

    /// @notice Retrieve the operators in storage
    /// @return The Operator structure array
    function getAll() internal view returns (Operator[] storage) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Retrieve the operator count in storage
    /// @return The count of operators in storage
    function getCount() internal view returns (uint256) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value.length;
    }

    /// @notice Retrieve all the active operators
    /// @return The list of active operator structures
    function getAllActive() internal view returns (Operator[] memory) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        uint256 activeCount = 0;
        uint256 operatorCount = r.value.length;

        for (uint256 idx = 0; idx < operatorCount;) {
            if (r.value[idx].active) {
                unchecked {
                    ++activeCount;
                }
            }
            unchecked {
                ++idx;
            }
        }

        Operator[] memory activeOperators = new Operator[](activeCount);

        uint256 activeIdx = 0;
        for (uint256 idx = 0; idx < operatorCount;) {
            if (r.value[idx].active) {
                activeOperators[activeIdx] = r.value[idx];
                unchecked {
                    ++activeIdx;
                }
            }
            unchecked {
                ++idx;
            }
        }

        return activeOperators;
    }

    /// @notice Retrieve the stopped validator count for an operator by its index
    /// @param stoppedValidatorCounts The storage pointer to the raw array containing the stopped validator counts
    /// @param index The index of the operator to lookup
    /// @return The amount of stopped validators for the given operator index
    function _getStoppedValidatorCountAtIndex(uint32[] storage stoppedValidatorCounts, uint256 index)
        internal
        view
        returns (uint32)
    {
        if (index + 1 >= stoppedValidatorCounts.length) {
            return 0;
        }
        return stoppedValidatorCounts[index + 1];
    }

    /// @notice Retrieve all the active and fundable operators
    /// @dev This method will return a memory array of length equal to the number of operator, but only
    /// @dev populated up to the fundable operator count, also returned by the method
    /// @return The list of active and fundable operators
    /// @return The count of active and fundable operators
    function getAllFundable() internal view returns (CachedOperator[] memory, uint256) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        uint256 fundableCount = 0;
        uint256 operatorCount = r.value.length;
        CachedOperator[] memory fundableOperators = new CachedOperator[](operatorCount);

        uint32[] storage stoppedValidatorCounts = getStoppedValidators();

        for (uint256 idx = 0; idx < operatorCount;) {
            if (
                _hasFundableKeys(r.value[idx])
                    && _getStoppedValidatorCountAtIndex(stoppedValidatorCounts, idx) >= r.value[idx].requestedExits
            ) {
                Operator storage op = r.value[idx];
                fundableOperators[fundableCount] = CachedOperator({
                    limit: op.limit,
                    funded: op.funded,
                    requestedExits: op.requestedExits,
                    index: uint32(idx),
                    picked: 0
                });
                unchecked {
                    ++fundableCount;
                }
            }
            unchecked {
                ++idx;
            }
        }

        return (fundableOperators, fundableCount);
    }

    /// @notice Retrieve all the active and exitable operators
    /// @dev This method will return a memory array of length equal to the number of operator, but only
    /// @dev populated up to the exitable operator count, also returned by the method
    /// @return The list of active and exitable operators
    /// @return The count of active and exitable operators
    function getAllExitable() internal view returns (CachedExitableOperator[] memory, uint256) {
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        uint256 exitableCount = 0;
        uint256 operatorCount = r.value.length;

        CachedExitableOperator[] memory exitableOperators = new CachedExitableOperator[](operatorCount);

        for (uint256 idx = 0; idx < operatorCount;) {
            if (_hasExitableKeys(r.value[idx])) {
                Operator storage op = r.value[idx];
                exitableOperators[exitableCount] = CachedExitableOperator({
                    funded: op.funded,
                    requestedExits: op.requestedExits,
                    index: uint32(idx),
                    picked: 0
                });
                unchecked {
                    ++exitableCount;
                }
            }
            unchecked {
                ++idx;
            }
        }

        return (exitableOperators, exitableCount);
    }

    /// @notice Add a new operator in storage
    /// @param _newOperator Value of the new operator
    /// @return The size of the operator array after the operation
    function push(Operator memory _newOperator) internal returns (uint256) {
        LibSanitize._notZeroAddress(_newOperator.operator);
        LibSanitize._notEmptyString(_newOperator.name);
        bytes32 slot = OPERATORS_SLOT;

        SlotOperator storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value.push(_newOperator);

        return r.value.length;
    }

    /// @notice Atomic operation to set the key count and update the latestKeysEditBlockNumber field at the same time
    /// @param _index The operator index
    /// @param _newKeys The new value for the key count
    function setKeys(uint256 _index, uint32 _newKeys) internal {
        Operator storage op = get(_index);

        op.keys = _newKeys;
        op.latestKeysEditBlockNumber = uint64(block.number);
    }

    /// @notice Checks if an operator is active and has fundable keys
    /// @param _operator The operator details
    /// @return True if active and fundable
    function _hasFundableKeys(OperatorsV2.Operator memory _operator) internal pure returns (bool) {
        return (_operator.active && _operator.limit > _operator.funded);
    }

    /// @notice Checks if an operator is active and has exitable keys
    /// @param _operator The operator details
    /// @return True if active and exitable
    function _hasExitableKeys(OperatorsV2.Operator memory _operator) internal pure returns (bool) {
        return (_operator.active && _operator.funded > _operator.requestedExits);
    }

    /// @notice Storage slot of the Stopped Validators
    bytes32 internal constant STOPPED_VALIDATORS_SLOT = bytes32(uint256(keccak256("river.state.stoppedValidators")) - 1);

    struct SlotStoppedValidators {
        uint32[] value;
    }

    /// @notice Retrieve the storage pointer of the Stopped Validators array
    /// @return The Stopped Validators storage pointer
    function getStoppedValidators() internal view returns (uint32[] storage) {
        bytes32 slot = STOPPED_VALIDATORS_SLOT;

        SlotStoppedValidators storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Sets the entire stopped validators array
    /// @param value The new stopped validators array
    function setRawStoppedValidators(uint32[] memory value) internal {
        bytes32 slot = STOPPED_VALIDATORS_SLOT;

        SlotStoppedValidators storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = value;
    }
}

File 30 of 60 : RedeemQueue.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Redeem Manager Redeem Queue storage
/// @notice Utility to manage the Redeem Queue in the Redeem Manager
library RedeemQueue {
    /// @notice Storage slot of the Redeem Queue
    bytes32 internal constant REDEEM_QUEUE_ID_SLOT = bytes32(uint256(keccak256("river.state.redeemQueue")) - 1);

    /// @notice The Redeemer structure represents the redeem request made by a user
    struct RedeemRequest {
        /// @custom:attribute The amount of the redeem request in LsETH
        uint256 amount;
        /// @custom:attribute The maximum amount of ETH redeemable by this request
        uint256 maxRedeemableEth;
        /// @custom:attribute The owner of the redeem request
        address owner;
        /// @custom:attribute The height is the cumulative sum of all the sizes of preceding redeem requests
        uint256 height;
    }

    /// @notice Retrieve the Redeem Queue array storage pointer
    /// @return data The Redeem Queue array storage pointer
    function get() internal pure returns (RedeemRequest[] storage data) {
        bytes32 position = REDEEM_QUEUE_ID_SLOT;
        assembly {
            data.slot := position
        }
    }
}

File 31 of 60 : WithdrawalStack.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Redeem Manager Withdrawal Stack storage
/// @notice Utility to manage the Withdrawal Stack in the Redeem Manager
library WithdrawalStack {
    /// @notice Storage slot of the Withdrawal Stack
    bytes32 internal constant WITHDRAWAL_STACK_ID_SLOT = bytes32(uint256(keccak256("river.state.withdrawalStack")) - 1);

    /// @notice The Redeemer structure represents the withdrawal events made by River
    struct WithdrawalEvent {
        /// @custom:attribute The amount of the withdrawal event in LsETH
        uint256 amount;
        /// @custom:attribute The amount of the withdrawal event in ETH
        uint256 withdrawnEth;
        /// @custom:attribute The height is the cumulative sum of all the sizes of preceding withdrawal events
        uint256 height;
    }

    /// @notice Retrieve the Withdrawal Stack array storage pointer
    /// @return data The Withdrawal Stack array storage pointer
    function get() internal pure returns (WithdrawalEvent[] storage data) {
        bytes32 position = WITHDRAWAL_STACK_ID_SLOT;
        assembly {
            data.slot := position
        }
    }
}

File 32 of 60 : AllowlistAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Allowlist Address Storage
/// @notice Utility to manage the Allowlist Address in storage
library AllowlistAddress {
    /// @notice Storage slot of the Allowlist Address
    bytes32 internal constant ALLOWLIST_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.allowlistAddress")) - 1);

    /// @notice Retrieve the Allowlist Address
    /// @return The Allowlist Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(ALLOWLIST_ADDRESS_SLOT);
    }

    /// @notice Sets the Allowlist Address
    /// @param _newValue New Allowlist Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(ALLOWLIST_ADDRESS_SLOT, _newValue);
    }
}

File 33 of 60 : BalanceToDeposit.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

library BalanceToDeposit {
    bytes32 internal constant BALANCE_TO_DEPOSIT_SLOT = bytes32(uint256(keccak256("river.state.balanceToDeposit")) - 1);

    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(BALANCE_TO_DEPOSIT_SLOT);
    }

    function set(uint256 newValue) internal {
        LibUnstructuredStorage.setStorageUint256(BALANCE_TO_DEPOSIT_SLOT, newValue);
    }
}

File 34 of 60 : BalanceToRedeem.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

library BalanceToRedeem {
    bytes32 internal constant BALANCE_TO_REDEEM_SLOT = bytes32(uint256(keccak256("river.state.balanceToRedeem")) - 1);

    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(BALANCE_TO_REDEEM_SLOT);
    }

    function set(uint256 newValue) internal {
        LibUnstructuredStorage.setStorageUint256(BALANCE_TO_REDEEM_SLOT, newValue);
    }
}

File 35 of 60 : CLSpec.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Consensus Layer Spec Storage
/// @notice Utility to manage the Consensus Layer Spec in storage
library CLSpec {
    /// @notice Storage slot of the Consensus Layer Spec
    bytes32 internal constant CL_SPEC_SLOT = bytes32(uint256(keccak256("river.state.clSpec")) - 1);

    /// @notice The Consensus Layer Spec structure
    struct CLSpecStruct {
        /// @custom:attribute The count of epochs per frame, 225 means 24h
        uint64 epochsPerFrame;
        /// @custom:attribute The count of slots in an epoch (32 on mainnet)
        uint64 slotsPerEpoch;
        /// @custom:attribute The seconds in a slot (12 on mainnet)
        uint64 secondsPerSlot;
        /// @custom:attribute The block timestamp of the first consensus layer block
        uint64 genesisTime;
        /// @custom:attribute The count of epochs before considering an epoch final on-chain
        uint64 epochsToAssumedFinality;
    }

    /// @notice The structure in storage
    struct Slot {
        /// @custom:attribute The structure in storage
        CLSpecStruct value;
    }

    /// @notice Retrieve the Consensus Layer Spec from storage
    /// @return The Consensus Layer Spec
    function get() internal view returns (CLSpecStruct memory) {
        bytes32 slot = CL_SPEC_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Set the Consensus Layer Spec value in storage
    /// @param _newCLSpec The new value to set in storage
    function set(CLSpecStruct memory _newCLSpec) internal {
        bytes32 slot = CL_SPEC_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = _newCLSpec;
    }
}

File 36 of 60 : CLValidatorCount.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Consensus Layer Validator Count Storage
/// @notice Utility to manage the Consensus Layer Validator Count in storage
/// @notice This state variable is deprecated and was kept due to migration logic needs
library CLValidatorCount {
    /// @notice Storage slot of the Consensus Layer Validator Count
    bytes32 internal constant CL_VALIDATOR_COUNT_SLOT = bytes32(uint256(keccak256("river.state.clValidatorCount")) - 1);

    /// @notice Retrieve the Consensus Layer Validator Count
    /// @return The Consensus Layer Validator Count
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(CL_VALIDATOR_COUNT_SLOT);
    }

    /// @notice Sets the Consensus Layer Validator Count
    /// @param _newValue New Consensus Layer Validator Count
    function set(uint256 _newValue) internal {
        LibUnstructuredStorage.setStorageUint256(CL_VALIDATOR_COUNT_SLOT, _newValue);
    }
}

File 37 of 60 : CLValidatorTotalBalance.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Consensus Layer Validator Total Balance Storage
/// @notice Utility to manage the Consensus Layer Validator Total Balance in storage
/// @notice This state variable is deprecated and was kept due to migration logic needs
library CLValidatorTotalBalance {
    /// @notice Storage slot of the Consensus Layer Validator Total Balance
    bytes32 internal constant CL_VALIDATOR_TOTAL_BALANCE_SLOT =
        bytes32(uint256(keccak256("river.state.clValidatorTotalBalance")) - 1);

    /// @notice Retrieve the Consensus Layer Validator Total Balance
    /// @return The Consensus Layer Validator Total Balance
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(CL_VALIDATOR_TOTAL_BALANCE_SLOT);
    }

    /// @notice Sets the Consensus Layer Validator Total Balance
    /// @param _newValue New Consensus Layer Validator Total Balance
    function set(uint256 _newValue) internal {
        LibUnstructuredStorage.setStorageUint256(CL_VALIDATOR_TOTAL_BALANCE_SLOT, _newValue);
    }
}

File 38 of 60 : CollectorAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Collector Address Storage
/// @notice Utility to manage the Collector Address in storage
library CollectorAddress {
    /// @notice Storage slot of the Collector Address
    bytes32 internal constant COLLECTOR_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.collectorAddress")) - 1);

    /// @notice Retrieve the Collector Address
    /// @return The Collector Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(COLLECTOR_ADDRESS_SLOT);
    }

    /// @notice Sets the Collector Address
    /// @param _newValue New Collector Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(COLLECTOR_ADDRESS_SLOT, _newValue);
    }
}

File 39 of 60 : CommittedBalance.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

library CommittedBalance {
    bytes32 internal constant COMMITTED_BALANCE_SLOT = bytes32(uint256(keccak256("river.state.committedBalance")) - 1);

    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(COMMITTED_BALANCE_SLOT);
    }

    function set(uint256 newValue) internal {
        LibUnstructuredStorage.setStorageUint256(COMMITTED_BALANCE_SLOT, newValue);
    }
}

File 40 of 60 : CoverageFundAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Coverage Fund Address Storage
/// @notice Utility to manage the Coverage Fund Address in storage
library CoverageFundAddress {
    /// @notice Storage slot of the Coverage Fund Address
    bytes32 internal constant COVERAGE_FUND_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.coverageFundAddress")) - 1);

    /// @notice Retrieve the Coverage Fund Address
    /// @return The Coverage Fund Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(COVERAGE_FUND_ADDRESS_SLOT);
    }

    /// @notice Sets the Coverage Fund Address
    /// @param _newValue New Coverage Fund Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(COVERAGE_FUND_ADDRESS_SLOT, _newValue);
    }
}

File 41 of 60 : DailyCommittableLimits.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibSanitize.sol";

/// @title Daily Committable Limits storage
/// @notice Utility to manage the Daily Committable Limits in storage
library DailyCommittableLimits {
    /// @notice Storage slot of the Daily Committable Limits storage
    bytes32 internal constant DAILY_COMMITTABLE_LIMITS_SLOT =
        bytes32(uint256(keccak256("river.state.dailyCommittableLimits")) - 1);

    /// @notice The daily committable limits structure
    struct DailyCommittableLimitsStruct {
        uint128 minDailyNetCommittableAmount;
        uint128 maxDailyRelativeCommittableAmount;
    }

    /// @notice The structure in storage
    struct Slot {
        /// @custom:attribute The structure in storage
        DailyCommittableLimitsStruct value;
    }

    /// @notice Retrieve the Daily Committable Limits from storage
    /// @return The Daily Committable Limits
    function get() internal view returns (DailyCommittableLimitsStruct memory) {
        bytes32 slot = DAILY_COMMITTABLE_LIMITS_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Set the Daily Committable Limits value in storage
    /// @param _newValue The new value to set in storage
    function set(DailyCommittableLimitsStruct memory _newValue) internal {
        bytes32 slot = DAILY_COMMITTABLE_LIMITS_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = _newValue;
    }
}

File 42 of 60 : DepositContractAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibSanitize.sol";
import "../../libraries/LibUnstructuredStorage.sol";

/// @title Deposit Contract Address Storage
/// @notice Utility to manage the Deposit Contract Address in storage
library DepositContractAddress {
    /// @notice Storage slot of the Deposit Contract Address
    bytes32 internal constant DEPOSIT_CONTRACT_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.depositContractAddress")) - 1);

    /// @notice Retrieve the Deposit Contract Address
    /// @return The Deposit Contract Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(DEPOSIT_CONTRACT_ADDRESS_SLOT);
    }

    /// @notice Sets the Deposit Contract Address
    /// @param _newValue New Deposit Contract Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(DEPOSIT_CONTRACT_ADDRESS_SLOT, _newValue);
    }
}

File 43 of 60 : DepositedValidatorCount.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Deposited Validator Count Storage
/// @notice Utility to manage the Deposited Validator Count in storage
library DepositedValidatorCount {
    /// @notice Storage slot of the Deposited Validator Count
    bytes32 internal constant DEPOSITED_VALIDATOR_COUNT_SLOT =
        bytes32(uint256(keccak256("river.state.depositedValidatorCount")) - 1);

    /// @notice Retrieve the Deposited Validator Count
    /// @return The Deposited Validator Count
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(DEPOSITED_VALIDATOR_COUNT_SLOT);
    }

    /// @notice Sets the Deposited Validator Count
    /// @param _newValue New Deposited Validator Count
    function set(uint256 _newValue) internal {
        LibUnstructuredStorage.setStorageUint256(DEPOSITED_VALIDATOR_COUNT_SLOT, _newValue);
    }
}

File 44 of 60 : ELFeeRecipientAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Execution Layer Fee Recipient Address Storage
/// @notice Utility to manage the Execution Layer Fee Recipient Address in storage
library ELFeeRecipientAddress {
    /// @notice Storage slot of the Execution Layer Fee Recipient Address
    bytes32 internal constant EL_FEE_RECIPIENT_ADDRESS =
        bytes32(uint256(keccak256("river.state.elFeeRecipientAddress")) - 1);

    /// @notice Retrieve the Execution Layer Fee Recipient Address
    /// @return The Execution Layer Fee Recipient Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(EL_FEE_RECIPIENT_ADDRESS);
    }

    /// @notice Sets the Execution Layer Fee Recipient Address
    /// @param _newValue New Execution Layer Fee Recipient Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(EL_FEE_RECIPIENT_ADDRESS, _newValue);
    }
}

File 45 of 60 : GlobalFee.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibSanitize.sol";
import "../../libraries/LibUnstructuredStorage.sol";

/// @title Global Fee Storage
/// @notice Utility to manage the Global Fee in storage
library GlobalFee {
    /// @notice Storage slot of the Global Fee
    bytes32 internal constant GLOBAL_FEE_SLOT = bytes32(uint256(keccak256("river.state.globalFee")) - 1);

    /// @notice Retrieve the Global Fee
    /// @return The Global Fee
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(GLOBAL_FEE_SLOT);
    }

    /// @notice Sets the Global Fee
    /// @param _newValue New Global Fee
    function set(uint256 _newValue) internal {
        LibSanitize._validFee(_newValue);
        LibUnstructuredStorage.setStorageUint256(GLOBAL_FEE_SLOT, _newValue);
    }
}

File 46 of 60 : LastConsensusLayerReport.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../interfaces/components/IOracleManager.1.sol";

/// @title Last Consensus Layer Report Storage
/// @notice Utility to manage the Last Consensus Layer Report in storage
library LastConsensusLayerReport {
    /// @notice Storage slot of the Last Consensus Layer Report
    bytes32 internal constant LAST_CONSENSUS_LAYER_REPORT_SLOT =
        bytes32(uint256(keccak256("river.state.lastConsensusLayerReport")) - 1);

    /// @notice The structure in storage
    struct Slot {
        /// @custom:attribute The structure in storage
        IOracleManagerV1.StoredConsensusLayerReport value;
    }

    /// @notice Retrieve the Last Consensus Layer Report from storage
    /// @return The Last Consensus Layer Report
    function get() internal view returns (IOracleManagerV1.StoredConsensusLayerReport storage) {
        bytes32 slot = LAST_CONSENSUS_LAYER_REPORT_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Set the Last Consensus Layer Report value in storage
    /// @param _newValue The new value to set in storage
    function set(IOracleManagerV1.StoredConsensusLayerReport memory _newValue) internal {
        bytes32 slot = LAST_CONSENSUS_LAYER_REPORT_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = _newValue;
    }
}

File 47 of 60 : LastOracleRoundId.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Last Oracle Round Id Storage
/// @notice Utility to manage the Last Oracle Round Id in storage
/// @notice This state variable is deprecated and was kept due to migration logic needs
library LastOracleRoundId {
    /// @notice Storage slot of the Last Oracle Round Id
    bytes32 internal constant LAST_ORACLE_ROUND_ID_SLOT =
        bytes32(uint256(keccak256("river.state.lastOracleRoundId")) - 1);

    /// @notice Retrieve the Last Oracle Round Id
    /// @return The Last Oracle Round Id
    function get() internal view returns (bytes32) {
        return LibUnstructuredStorage.getStorageBytes32(LAST_ORACLE_ROUND_ID_SLOT);
    }

    /// @notice Sets the Last Oracle Round Id
    /// @param _newValue New Last Oracle Round Id
    function set(bytes32 _newValue) internal {
        LibUnstructuredStorage.setStorageBytes32(LAST_ORACLE_ROUND_ID_SLOT, _newValue);
    }
}

File 48 of 60 : MetadataURI.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Metadata URI Storage
/// @notice Utility to manage the Metadata in storage
library MetadataURI {
    /// @notice Storage slot of the Metadata URI
    bytes32 internal constant METADATA_URI_SLOT = bytes32(uint256(keccak256("river.state.metadataUri")) - 1);

    /// @notice Structure in storage
    struct Slot {
        /// @custom:attribute The metadata value
        string value;
    }

    /// @notice Retrieve the metadata URI
    /// @return The metadata URI string
    function get() internal view returns (string memory) {
        bytes32 slot = METADATA_URI_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Set the metadata URI value
    /// @param _newValue The new metadata URI value
    function set(string memory _newValue) internal {
        bytes32 slot = METADATA_URI_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = _newValue;
    }
}

File 49 of 60 : OperatorsRegistryAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Operators Registry Address Storage
/// @notice Utility to manage the Operators Registry Address in storage
library OperatorsRegistryAddress {
    /// @notice Storage slot of the Operators Registry Address
    bytes32 internal constant OPERATORS_REGISTRY_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.operatorsRegistryAddress")) - 1);

    /// @notice Retrieve the Operators Registry Address
    /// @return The Operators Registry Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(OPERATORS_REGISTRY_ADDRESS_SLOT);
    }

    /// @notice Sets the Operators Registry Address
    /// @param _newValue New Operators Registry Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(OPERATORS_REGISTRY_ADDRESS_SLOT, _newValue);
    }
}

File 50 of 60 : OracleAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Oracle Address Storage
/// @notice Utility to manage the Oracle Address in storage
library OracleAddress {
    /// @notice Storage slot of the Oracle Address
    bytes32 internal constant ORACLE_ADDRESS_SLOT = bytes32(uint256(keccak256("river.state.oracleAddress")) - 1);

    /// @notice Retrieve the Oracle Address
    /// @return The Oracle Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(ORACLE_ADDRESS_SLOT);
    }

    /// @notice Sets the Oracle Address
    /// @param _newValue New Oracle Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(ORACLE_ADDRESS_SLOT, _newValue);
    }
}

File 51 of 60 : RedeemManagerAddress.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Redeem Manager Address Storage
/// @notice Utility to manage the Redeem Manager Address in storage
library RedeemManagerAddress {
    /// @notice Storage slot of the Redeem Manager Address
    bytes32 internal constant REDEEM_MANAGER_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.redeemManagerAddress")) - 1);

    /// @notice Retrieve the Redeem Manager Address
    /// @return The Redeem Manager Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(REDEEM_MANAGER_ADDRESS_SLOT);
    }

    /// @notice Sets the Redeem Manager Address
    /// @param _newValue New Redeem Manager Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(REDEEM_MANAGER_ADDRESS_SLOT, _newValue);
    }
}

File 52 of 60 : ReportBounds.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Report Bounds Storage
/// @notice Utility to manage the Report Bounds in storage
library ReportBounds {
    /// @notice Storage slot of the Report Bounds
    bytes32 internal constant REPORT_BOUNDS_SLOT = bytes32(uint256(keccak256("river.state.reportBounds")) - 1);

    /// @notice The Report Bounds structure
    struct ReportBoundsStruct {
        /// @custom:attribute The maximum allowed annual apr, checked before submitting a report to River
        uint256 annualAprUpperBound;
        /// @custom:attribute The maximum allowed balance decrease, also checked before submitting a report to River
        uint256 relativeLowerBound;
    }

    /// @notice The structure in storage
    struct Slot {
        /// @custom:attribute The structure in storage
        ReportBoundsStruct value;
    }

    /// @notice Retrieve the Report Bounds from storage
    /// @return The Report Bounds
    function get() internal view returns (ReportBoundsStruct memory) {
        bytes32 slot = REPORT_BOUNDS_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value;
    }

    /// @notice Set the Report Bounds in storage
    /// @param _newReportBounds The new Report Bounds value
    function set(ReportBoundsStruct memory _newReportBounds) internal {
        bytes32 slot = REPORT_BOUNDS_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value = _newReportBounds;
    }
}

File 53 of 60 : Shares.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Shares Count Storage
/// @notice Utility to manage the Shares Count in storage
library Shares {
    /// @notice Storage slot of the Shares Count
    bytes32 internal constant SHARES_SLOT = bytes32(uint256(keccak256("river.state.shares")) - 1);

    /// @notice Retrieve the Shares Count
    /// @return The Shares Count
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(SHARES_SLOT);
    }

    /// @notice Sets the Shares Count
    /// @param _newValue New Shares Count
    function set(uint256 _newValue) internal {
        LibUnstructuredStorage.setStorageUint256(SHARES_SLOT, _newValue);
    }
}

File 54 of 60 : SharesPerOwner.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Shares Per Owner Storage
/// @notice Utility to manage the Shares Per Owner in storage
library SharesPerOwner {
    /// @notice Storage slot of the Shares Per Owner
    bytes32 internal constant SHARES_PER_OWNER_SLOT = bytes32(uint256(keccak256("river.state.sharesPerOwner")) - 1);

    /// @notice Structure in storage
    struct Slot {
        /// @custom:attribute The mapping from an owner to its share count
        mapping(address => uint256) value;
    }

    /// @notice Retrieve the share count for given owner
    /// @param _owner The address to get the balance of
    /// @return The amount of shares
    function get(address _owner) internal view returns (uint256) {
        bytes32 slot = SHARES_PER_OWNER_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value[_owner];
    }

    /// @notice Set the amount of shares for an owner
    /// @param _owner The owner of the shares to edit
    /// @param _newValue The new shares value for the owner
    function set(address _owner, uint256 _newValue) internal {
        bytes32 slot = SHARES_PER_OWNER_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value[_owner] = _newValue;
    }
}

File 55 of 60 : WithdrawalCredentials.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibErrors.sol";
import "../../libraries/LibUnstructuredStorage.sol";

/// @title Withdrawal Credentials Storage
/// @notice Utility to manage the Withdrawal Credentials in storage
library WithdrawalCredentials {
    /// @notice Storage slot of the Withdrawal Credentials
    bytes32 internal constant WITHDRAWAL_CREDENTIALS_SLOT =
        bytes32(uint256(keccak256("river.state.withdrawalCredentials")) - 1);

    /// @notice Retrieve the Withdrawal Credentials
    /// @return The Withdrawal Credentials
    function get() internal view returns (bytes32) {
        return LibUnstructuredStorage.getStorageBytes32(WITHDRAWAL_CREDENTIALS_SLOT);
    }

    /// @notice Retrieve the Withdrawal Credential under its address format
    /// @return The Withdrawal Credentials in its address format
    function getAddress() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(WITHDRAWAL_CREDENTIALS_SLOT);
    }

    /// @notice Sets the Withdrawal Credentials
    /// @param _newValue New Withdrawal Credentials
    function set(bytes32 _newValue) internal {
        if (_newValue == bytes32(0)) {
            revert LibErrors.InvalidArgument();
        }
        LibUnstructuredStorage.setStorageBytes32(WITHDRAWAL_CREDENTIALS_SLOT, _newValue);
    }
}

File 56 of 60 : AdministratorAddress.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";
import "../../libraries/LibSanitize.sol";

/// @title Administrator Address Storage
/// @notice Utility to manage the Administrator Address in storage
library AdministratorAddress {
    /// @notice Storage slot of the Administrator Address
    bytes32 public constant ADMINISTRATOR_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.administratorAddress")) - 1);

    /// @notice Retrieve the Administrator Address
    /// @return The Administrator Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(ADMINISTRATOR_ADDRESS_SLOT);
    }

    /// @notice Sets the Administrator Address
    /// @param _newValue New Administrator Address
    function set(address _newValue) internal {
        LibSanitize._notZeroAddress(_newValue);
        LibUnstructuredStorage.setStorageAddress(ADMINISTRATOR_ADDRESS_SLOT, _newValue);
    }
}

File 57 of 60 : ApprovalsPerOwner.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

/// @title Approvals Per Owner Storage
/// @notice Utility to manage the Approvals Per Owner in storage
library ApprovalsPerOwner {
    /// @notice Storage slot of the Approvals Per Owner
    bytes32 internal constant APPROVALS_PER_OWNER_SLOT =
        bytes32(uint256(keccak256("river.state.approvalsPerOwner")) - 1);

    /// @notice The structure in storage
    struct Slot {
        /// @custom:attribute The mapping from an owner to an operator to the approval amount
        mapping(address => mapping(address => uint256)) value;
    }

    /// @notice Retrieve the approval for an owner to an operator
    /// @param _owner The account that gave the approval
    /// @param _operator The account receiving the approval
    /// @return The value of the approval
    function get(address _owner, address _operator) internal view returns (uint256) {
        bytes32 slot = APPROVALS_PER_OWNER_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        return r.value[_owner][_operator];
    }

    /// @notice Set the approval value for an owner to an operator
    /// @param _owner The account that gives the approval
    /// @param _operator The account receiving the approval
    /// @param _newValue The value of the approval
    function set(address _owner, address _operator, uint256 _newValue) internal {
        bytes32 slot = APPROVALS_PER_OWNER_SLOT;

        Slot storage r;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            r.slot := slot
        }

        r.value[_owner][_operator] = _newValue;
    }
}

File 58 of 60 : PendingAdministratorAddress.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Pending Administrator Address Storage
/// @notice Utility to manage the Pending Administrator Address in storage
library PendingAdministratorAddress {
    /// @notice Storage slot of the Pending Administrator Address
    bytes32 public constant PENDING_ADMINISTRATOR_ADDRESS_SLOT =
        bytes32(uint256(keccak256("river.state.pendingAdministratorAddress")) - 1);

    /// @notice Retrieve the Pending Administrator Address
    /// @return The Pending Administrator Address
    function get() internal view returns (address) {
        return LibUnstructuredStorage.getStorageAddress(PENDING_ADMINISTRATOR_ADDRESS_SLOT);
    }

    /// @notice Sets the Pending Administrator Address
    /// @param _newValue New Pending Administrator Address
    function set(address _newValue) internal {
        LibUnstructuredStorage.setStorageAddress(PENDING_ADMINISTRATOR_ADDRESS_SLOT, _newValue);
    }
}

File 59 of 60 : Version.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.10;

import "../../libraries/LibUnstructuredStorage.sol";

/// @title Version Storage
/// @notice Utility to manage the Version in storage
library Version {
    /// @notice Storage slot of the Version
    bytes32 public constant VERSION_SLOT = bytes32(uint256(keccak256("river.state.version")) - 1);

    /// @notice Retrieve the Version
    /// @return The Version
    function get() internal view returns (uint256) {
        return LibUnstructuredStorage.getStorageUint256(VERSION_SLOT);
    }

    /// @notice Sets the Version
    /// @param _newValue New Version
    function set(uint256 _newValue) internal {
        LibUnstructuredStorage.setStorageUint256(VERSION_SLOT, _newValue);
    }
}

File 60 of 60 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.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);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 10
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"uint256","name":"_allowance","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"AllowanceTooLow","type":"error"},{"inputs":[],"name":"BalanceTooLow","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"Denied","type":"error"},{"inputs":[],"name":"EmptyDeposit","type":"error"},{"inputs":[],"name":"ErrorOnDeposit","type":"error"},{"inputs":[],"name":"InconsistentPublicKeys","type":"error"},{"inputs":[],"name":"InconsistentSignatures","type":"error"},{"inputs":[],"name":"InvalidArgument","type":"error"},{"inputs":[],"name":"InvalidCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentValidatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"newValidatorsExitedBalance","type":"uint256"}],"name":"InvalidDecreasingValidatorsExitedBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentValidatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"newValidatorsSkimmedBalance","type":"uint256"}],"name":"InvalidDecreasingValidatorsSkimmedBalance","type":"error"},{"inputs":[],"name":"InvalidEmptyString","type":"error"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"}],"name":"InvalidEpoch","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"uint256","name":"expectedVersion","type":"uint256"}],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidPublicKeyCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"InvalidPulledClFundsAmount","type":"error"},{"inputs":[],"name":"InvalidSignatureCount","type":"error"},{"inputs":[{"internalType":"uint256","name":"providedValidatorCount","type":"uint256"},{"internalType":"uint256","name":"depositedValidatorCount","type":"uint256"},{"internalType":"uint256","name":"lastReportedValidatorCount","type":"uint256"}],"name":"InvalidValidatorCountReport","type":"error"},{"inputs":[],"name":"InvalidWithdrawalCredentials","type":"error"},{"inputs":[],"name":"InvalidZeroAddress","type":"error"},{"inputs":[],"name":"NoAvailableValidatorKeys","type":"error"},{"inputs":[],"name":"NotEnoughFunds","type":"error"},{"inputs":[],"name":"NullTransfer","type":"error"},{"inputs":[],"name":"SliceOutOfBounds","type":"error"},{"inputs":[],"name":"SliceOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"prevTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"postTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"name":"TotalValidatorBalanceDecreaseOutOfBound","type":"error"},{"inputs":[{"internalType":"uint256","name":"prevTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"postTotalEthIncludingExited","type":"uint256"},{"internalType":"uint256","name":"timeElapsed","type":"uint256"},{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"}],"name":"TotalValidatorBalanceIncreaseOutOfBound","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"}],"name":"UnauthorizedTransfer","type":"error"},{"inputs":[],"name":"ZeroMintedShares","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"validatorCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"validatorTotalBalance","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"roundId","type":"bytes32"}],"name":"ConsensusLayerDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"cdata","type":"bytes"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"uint32[]","name":"stoppedValidatorCountPerOperator","type":"uint32[]"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"indexed":false,"internalType":"struct IOracleManagerV1.ConsensusLayerReport","name":"report","type":"tuple"},{"components":[{"internalType":"uint256","name":"rewards","type":"uint256"},{"internalType":"uint256","name":"pulledELFees","type":"uint256"},{"internalType":"uint256","name":"pulledRedeemManagerExceedingEthBuffer","type":"uint256"},{"internalType":"uint256","name":"pulledCoverageFunds","type":"uint256"}],"indexed":false,"internalType":"struct IOracleManagerV1.ConsensusLayerDataReportingTrace","name":"trace","type":"tuple"}],"name":"ProcessedConsensusLayerReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"pulledSkimmedEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"pullExitedEthAmount","type":"uint256"}],"name":"PulledCLFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledCoverageFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledELFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PulledRedeemManagerExceedingEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"redeemManagerDemand","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"suppliedRedeemManagerDemand","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"suppliedRedeemManagerDemandInEth","type":"uint256"}],"name":"ReportedRedeemManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_collector","type":"address"},{"indexed":false,"internalType":"uint256","name":"_oldTotalUnderlyingBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalUnderlyingBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotalSupply","type":"uint256"}],"name":"RewardsEarned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"SetAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"allowlist","type":"address"}],"name":"SetAllowlist","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceCommittedToDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceToDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"SetBalanceToRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"name":"SetBounds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"collector","type":"address"}],"name":"SetCollector","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"coverageFund","type":"address"}],"name":"SetCoverageFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositContract","type":"address"}],"name":"SetDepositContractAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldDepositedValidatorCount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newDepositedValidatorCount","type":"uint256"}],"name":"SetDepositedValidatorCount","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"elFeeRecipient","type":"address"}],"name":"SetELFeeRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetGlobalFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minNetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxRelativeAmount","type":"uint256"}],"name":"SetMaxDailyCommittableAmounts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"metadataURI","type":"string"}],"name":"SetMetadataURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operatorRegistry","type":"address"}],"name":"SetOperatorsRegistry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracleAddress","type":"address"}],"name":"SetOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingAdmin","type":"address"}],"name":"SetPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"redeemManager","type":"address"}],"name":"SetRedeemManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"genesisTime","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"name":"SetSpec","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"SetTotalSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"}],"name":"SetWithdrawalCredentials","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UserDeposit","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"DEPOSIT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_KEY_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNATURE_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_DEPOSIT_SIZE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOfUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_redeemRequestIds","type":"uint32[]"},{"internalType":"uint32[]","name":"_withdrawalEventIds","type":"uint32[]"}],"name":"claimRedeemRequests","outputs":[{"internalType":"uint8[]","name":"claimStatuses","type":"uint8[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_subtractableValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"depositAndTransfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxCount","type":"uint256"}],"name":"depositToConsensusLayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowlist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceToDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceToRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLSpec","outputs":[{"components":[{"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"genesisTime","type":"uint64"},{"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"internalType":"struct CLSpec.CLSpecStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLValidatorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCLValidatorTotalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCommittedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCoverageFund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentFrame","outputs":[{"internalType":"uint256","name":"_startEpochId","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDailyCommittableLimits","outputs":[{"components":[{"internalType":"uint128","name":"minDailyNetCommittableAmount","type":"uint128"},{"internalType":"uint128","name":"maxDailyRelativeCommittableAmount","type":"uint128"}],"internalType":"struct DailyCommittableLimits.DailyCommittableLimitsStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDepositedValidatorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getELFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpectedEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epochId","type":"uint256"}],"name":"getFrameFirstEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCompletedEpochId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastConsensusLayerReport","outputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"internalType":"struct IOracleManagerV1.StoredConsensusLayerReport","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetadataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOperatorsRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedeemManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReportBounds","outputs":[{"components":[{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"internalType":"struct ReportBounds.ReportBoundsStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_additionalValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_depositContractAddress","type":"address"},{"internalType":"address","name":"_elFeeRecipientAddress","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"},{"internalType":"address","name":"_oracleAddress","type":"address"},{"internalType":"address","name":"_systemAdministratorAddress","type":"address"},{"internalType":"address","name":"_allowlistAddress","type":"address"},{"internalType":"address","name":"_operatorRegistryAddress","type":"address"},{"internalType":"address","name":"_collectorAddress","type":"address"},{"internalType":"uint256","name":"_globalFee","type":"uint256"}],"name":"initRiverV1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_redeemManager","type":"address"},{"internalType":"uint64","name":"_epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"_slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"_secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"_genesisTime","type":"uint64"},{"internalType":"uint64","name":"_epochsToAssumedFinality","type":"uint64"},{"internalType":"uint256","name":"_annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"_relativeLowerBound","type":"uint256"},{"internalType":"uint128","name":"_minDailyNetCommittableAmount_","type":"uint128"},{"internalType":"uint128","name":"_maxDailyRelativeCommittableAmount_","type":"uint128"}],"name":"initRiverV1_1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initRiverV1_2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"name":"isValidEpoch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"proposeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lsETHAmount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"requestRedeem","outputs":[{"internalType":"uint32","name":"_redeemRequestId","type":"uint32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_redeemRequestIds","type":"uint32[]"}],"name":"resolveRedeemRequests","outputs":[{"internalType":"int64[]","name":"withdrawalEventIds","type":"int64[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sendCLFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendCoverageFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendELFees","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendRedeemManagerExceedingFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAllowlist","type":"address"}],"name":"setAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"epochsPerFrame","type":"uint64"},{"internalType":"uint64","name":"slotsPerEpoch","type":"uint64"},{"internalType":"uint64","name":"secondsPerSlot","type":"uint64"},{"internalType":"uint64","name":"genesisTime","type":"uint64"},{"internalType":"uint64","name":"epochsToAssumedFinality","type":"uint64"}],"internalType":"struct CLSpec.CLSpecStruct","name":"_newValue","type":"tuple"}],"name":"setCLSpec","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCollector","type":"address"}],"name":"setCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"validatorsBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsSkimmedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitedBalance","type":"uint256"},{"internalType":"uint256","name":"validatorsExitingBalance","type":"uint256"},{"internalType":"uint32","name":"validatorsCount","type":"uint32"},{"internalType":"uint32[]","name":"stoppedValidatorCountPerOperator","type":"uint32[]"},{"internalType":"bool","name":"rebalanceDepositToRedeemMode","type":"bool"},{"internalType":"bool","name":"slashingContainmentMode","type":"bool"}],"internalType":"struct IOracleManagerV1.ConsensusLayerReport","name":"_report","type":"tuple"}],"name":"setConsensusLayerData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCoverageFund","type":"address"}],"name":"setCoverageFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"minDailyNetCommittableAmount","type":"uint128"},{"internalType":"uint128","name":"maxDailyRelativeCommittableAmount","type":"uint128"}],"internalType":"struct DailyCommittableLimits.DailyCommittableLimitsStruct","name":"_dcl","type":"tuple"}],"name":"setDailyCommittableLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newELFeeRecipient","type":"address"}],"name":"setELFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setGlobalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_metadataURI","type":"string"}],"name":"setMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracleAddress","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"annualAprUpperBound","type":"uint256"},{"internalType":"uint256","name":"relativeLowerBound","type":"uint256"}],"internalType":"struct ReportBounds.ReportBoundsStruct","name":"_newValue","type":"tuple"}],"name":"setReportBounds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_underlyingAssetAmount","type":"uint256"}],"name":"sharesFromUnderlyingBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnderlyingSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"underlyingBalanceFromShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b506200002a6000196200007060201b620023a71760201c565b7f1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a716000196000366040516200006293929190620000bd565b60405180910390a162000119565b620000b6620000a160017f82055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd620000f3565b60001b82620000b960201b620023c81760201c565b50565b9055565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6000828210156200011457634e487b7160e01b600052601160045260246000fd5b500390565b615f6080620001296000396000f3fe6080604052600436106103555760003560e01c80635d95e801116101b95780635d95e801146108595780635f2e5f071461086157806363f62aaf1461088e5780636e9960c3146108a357806370a08231146108b857806372f79b13146108d8578063750521f51461090857806378a010e814610928578063799a1954146109485780637adbf97314610968578063833b1fce1461098857806386a92af71461099d57806387f2adfb146109b257806389896aef146109c75780639332525d146109dc57806395d89b4114610a095780639b498e2614610a375780639d49cca114610a4c578063a29a839f14610a7c578063a457c2d714610a91578063a9059cbb14610ab1578063ac232bde14610ad1578063bb6583ec14610ae4578063bf15af5614610b04578063c5eff3d014610b19578063d046815614610b2e578063d0e30db014610b43578063d497052414610b4b578063d7f8f4741461072b578063dd62ed3e14610b53578063e3a88e6114610b73578063efd6034714610baf578063efd6684614610bb7578063f79c3f0214610bd7578063f9f95a9014610bf7578063fb5b82d014610c17578063fe7c12ae14610c3757610365565b8063020f086e1461037e5780630407de471461039e57806304843a17146103be578063056850c6146103e657806306fdde03146103ee578063095ea7b3146104315780630e18b68114610461578063107703ab14610476578063107d7fa0146104ab5780631311cf8d146104c057806313d86aed146104e0578063143a08d414610500578063147bf6c4146105155780631546962b1461053557806315ca4cee1461055757806317e648581461057757806318160ddd146105f75780631bcbfaba1461060c57806323b872dd14610621578063281a312214610641578063291206f6146106615780632cb562e1146106815780632d6b59bf146106965780632dc5c97c146106ab578063313ce5671461070f57806336bf33251461072b57806339509351146107485780633af9e6691461076857806346425ef0146107885780634b47b74f1461079d57806350228201146107b2578063540bc5ea146107c757806354a29cdc146107dc578063557ed1ba146107f1578063563967151461080457806357fa85471461081957806358bf3c7f1461083957610365565b366103655761036333610c4c565b005b60405163574b16a760e11b815260040160405180910390fd5b34801561038a57600080fd5b50610363610399366004614bb1565b610cd3565b3480156103aa57600080fd5b506103636103b9366004614bfa565b610d57565b3480156103ca57600080fd5b506103d3610e60565b6040519081526020015b60405180910390f35b610363610e6f565b3480156103fa57600080fd5b50604080518082019091526011815270098d2e2ead2c840a6e8c2d6cac8408aa89607b1b60208201525b6040516103dd9190614cfe565b34801561043d57600080fd5b5061045161044c366004614d11565b610eac565b60405190151581526020016103dd565b34801561046d57600080fd5b50610363610ec2565b34801561048257600080fd5b50610496610491366004614d3b565b610f17565b60405163ffffffff90911681526020016103dd565b3480156104b757600080fd5b506103d361100f565b3480156104cc57600080fd5b506103636104db366004614bb1565b611028565b3480156104ec57600080fd5b506103636104fb366004614d67565b611091565b34801561050c57600080fd5b506103d3611237565b34801561052157600080fd5b50610363610530366004614bb1565b611241565b34801561054157600080fd5b5061054a611288565b6040516103dd9190614d80565b34801561056357600080fd5b50610363610572366004614d94565b611292565b34801561058357600080fd5b5061058c611314565b6040516103dd9190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015263ffffffff60a08401511660a083015260c0830151151560c083015260e0830151151560e083015292915050565b34801561060357600080fd5b506103d3611396565b34801561061857600080fd5b506103d36113a0565b34801561062d57600080fd5b5061045161063c366004614da6565b6113aa565b34801561064d57600080fd5b5061036361065c366004614de2565b611450565b34801561066d57600080fd5b5061036361067c366004614d67565b6115b1565b34801561068d57600080fd5b5061054a611613565b3480156106a257600080fd5b506103d361161d565b3480156106b757600080fd5b506106c0611627565b6040516103dd919081516001600160401b039081168252602080840151821690830152604083810151821690830152606080840151821690830152608092830151169181019190915260a00190565b34801561071b57600080fd5b50604051601281526020016103dd565b34801561073757600080fd5b506103d36801bc16d674ec80000081565b34801561075457600080fd5b50610451610763366004614d11565b611637565b34801561077457600080fd5b506103d3610783366004614bb1565b611658565b34801561079457600080fd5b506103d3611671565b3480156107a957600080fd5b506103d3611684565b3480156107be57600080fd5b5061054a6116ed565b3480156107d357600080fd5b506103d3606081565b3480156107e857600080fd5b506103636116f7565b3480156107fd57600080fd5b50426103d3565b34801561081057600080fd5b506103d3611783565b34801561082557600080fd5b506103d3610834366004614d67565b61178d565b34801561084557600080fd5b50610363610854366004614bb1565b6117b5565b61036361181e565b34801561086d57600080fd5b5061088161087c366004614ec7565b611826565b6040516103dd9190614f08565b34801561089a57600080fd5b5061054a6118a2565b3480156108af57600080fd5b5061054a6118ac565b3480156108c457600080fd5b506103d36108d3366004614bb1565b6118b6565b3480156108e457600080fd5b506108ed6118c1565b604080519384526020840192909252908201526060016103dd565b34801561091457600080fd5b50610363610923366004614fe4565b611991565b34801561093457600080fd5b50610363610943366004615063565b611a0d565b34801561095457600080fd5b506103d3610963366004614d67565b611acc565b34801561097457600080fd5b50610363610983366004614bb1565b611ad7565b34801561099457600080fd5b5061054a611b52565b3480156109a957600080fd5b50610424611b5c565b3480156109be57600080fd5b506103d3611b66565b3480156109d357600080fd5b506103d3611b70565b3480156109e857600080fd5b506109fc6109f7366004615075565b611b80565b6040516103dd91906150e0565b348015610a1557600080fd5b50604080518082019091526005815264098e68aa8960db1b6020820152610424565b348015610a4357600080fd5b5061054a611c12565b348015610a5857600080fd5b50610a61611c1c565b604080518251815260209283015192810192909252016103dd565b348015610a8857600080fd5b506103d3611c2c565b348015610a9d57600080fd5b50610451610aac366004614d11565b611c3e565b348015610abd57600080fd5b50610451610acc366004614d11565b611c5a565b610363610adf366004614bb1565b611cf5565b348015610af057600080fd5b50610363610aff36600461511b565b611d07565b348015610b1057600080fd5b506103d3603081565b348015610b2557600080fd5b5061054a611d4b565b348015610b3a57600080fd5b5061054a611d55565b610363611d5f565b610363611d68565b348015610b5f57600080fd5b506103d3610b6e366004615158565b611d70565b348015610b7f57600080fd5b50610b88611d7c565b6040805182516001600160801b0390811682526020938401511692810192909252016103dd565b610363611d8c565b348015610bc357600080fd5b50610363610bd2366004615182565b611d94565b348015610be357600080fd5b506103d3610bf2366004614d67565b612316565b348015610c0357600080fd5b50610451610c12366004614d67565b612321565b348015610c2357600080fd5b50610363610c32366004614bb1565b612334565b348015610c4357600080fd5b506103d361239d565b34610c6a576040516395b66fe960e01b815260040160405180910390fd5b610c8534610c766123cc565b610c8091906151d3565b6123ee565b610c90338234612437565b6040513481526001600160a01b0382169033907f3bc57f469ad6d10d7723ea226cd22bd2b9e527def2b529f6ab44645a166895829060200160405180910390a350565b610cdb6125cf565b6001600160a01b0316336001600160a01b031614610d17573360405163472511eb60e11b8152600401610d0e9190614d80565b60405180910390fd5b610d20816125d9565b6040516001600160a01b038216907f67b26a33f305cc027b2d45b2f6f418793afcd3e22f7376afa7be068ce18604e890600090a250565b6001610d616125fe565b8114610d8b5780610d706125fe565b604051631cfd276760e31b8152600401610d0e9291906151eb565b610d9e610d998260016151d3565b6123a7565b610da78b61261c565b7faf890c07e266df31e0725841eb0e85596a0caa1b17bbae5c0b206fdcc92d7ce18b604051610dd69190614d80565b60405180910390a1610e0d6040518060400160405280856001600160801b03168152602001846001600160801b0316815250612641565b610e1c8a8a8a8a8a8a8a612695565b610e29308c6000196127ca565b600080516020615b2b83398151915281600036604051610e4b939291906151f9565b60405180910390a15050505050505050505050565b6000610e6a6123cc565b905090565b610e77612839565b6001600160a01b0316336001600160a01b031614610eaa573360405163472511eb60e11b8152600401610d0e9190614d80565b565b6000610eb93384846127ca565b50600192915050565b610eca612857565b6001600160a01b0316336001600160a01b031614610efd573360405163472511eb60e11b8152600401610d0e9190614d80565b610f0d610f08612857565b612861565b610eaa60006128aa565b6000610f216128ea565b6001600160a01b0316635a4091023360046040518363ffffffff1660e01b8152600401610f4f92919061522f565b60006040518083038186803b158015610f6757600080fd5b505afa158015610f7b573d6000803e3d6000fd5b50505050610f8a333085612908565b50610f93612839565b60405163107703ab60e01b8152600481018590526001600160a01b038481166024830152919091169063107703ab906044016020604051808303816000875af1158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611008919061525a565b9392505050565b6000611019612984565b6005015463ffffffff16919050565b6110306125cf565b6001600160a01b0316336001600160a01b031614611063573360405163472511eb60e11b8152600401610d0e9190614d80565b61106c816129a0565b6040516001600160a01b03821690600080516020615dcb83398151915290600090a250565b600061109b6129c5565b905060006110bb6110b56801bc16d674ec8000008461528d565b846129e3565b9050806110db57604051631036b5ad60e31b815260040160405180910390fd5b6000806110e7836129f8565b815191935091508061110c5760405163200149ad60e21b815260040160405180910390fd5b8381111561112d57604051635993bd5760e01b815260040160405180910390fd5b6000611137612a80565b90508061115757604051639be7315960e01b815260040160405180910390fd5b60005b828110156111a75761119f858281518110611177576111776152a1565b6020026020010151858381518110611191576111916152a1565b602002602001015184612a9e565b60010161115a565b506111cd6111be836801bc16d674ec8000006152b7565b6111c890886152d6565b612eef565b60006111d7612f38565b90506111eb6111e684836151d3565b612f56565b7f220ab8fd274cf58c09b0825ccf00e74ba4ce4117fd47285adc2183a635838f1b8161121785826151d3565b6040516112259291906151eb565b60405180910390a15050505050505050565b6000610e6a612f72565b6112496125cf565b6001600160a01b0316336001600160a01b03161461127c573360405163472511eb60e11b8152600401610d0e9190614d80565b611285816128aa565b50565b6000610e6a613031565b61129a61304f565b6001600160a01b0316336001600160a01b0316146112cd573360405163472511eb60e11b8152600401610d0e9190614d80565b6112e46112df368390038301836152ed565b613059565b604051600080516020615d8b83398151915290611309908335906020850135906151eb565b60405180910390a150565b61131c6149d3565b611324612984565b60408051610100810182528254815260018301546020820152600283015491810191909152600382015460608201526004820154608082015260059091015463ffffffff811660a083015260ff600160201b82048116151560c0840152600160281b90910416151560e0820152919050565b6000610e6a61308a565b6000610e6a613094565b600083836113b882826130b2565b83806113d7576040516336b216db60e21b815260040160405180910390fd5b8685806113e3836131de565b1015611402576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b03881661142e57886000604051637617407560e11b8152600401610d0e92919061531f565b61143889886131e9565b611443898989612908565b9998505050505050505050565b600061145a6125fe565b81146114695780610d706125fe565b611477610d998260016151d3565b61148086612861565b6114898361324f565b6040516001600160a01b03841690600080516020615c6b83398151915290600090a26114b482613274565b604051828152600080516020615ceb8339815191529060200160405180910390a16114de896129a0565b6040516001600160a01b038a1690600080516020615dcb83398151915290600090a261150985613299565b6040516001600160a01b03861690600080516020615eab83398151915290600090a2611534846132be565b6040516001600160a01b038516907fffc0721ef0563a1b0a51a0dc92113025f33ca434ada9ee3eebff2f385d2a8f9a90600090a26115728a896132e3565b61157b87611b12565b600080516020615b2b8339815191528160003660405161159d939291906151f9565b60405180910390a150505050505050505050565b6115b96125cf565b6001600160a01b0316336001600160a01b0316146115ec573360405163472511eb60e11b8152600401610d0e9190614d80565b6115f581613274565b604051818152600080516020615ceb83398151915290602001611309565b6000610e6a61335f565b6000610e6a61337d565b61162f614a22565b610e6a61339b565b6000610eb93384846116493388613415565b61165391906151d3565b6127ca565b600061166b6116668361345b565b613497565b92915050565b600061167b612984565b60010154905090565b60008061168f61339b565b9050600061169c826134cf565b90506116e682600001516001600160401b03166116b7612984565b546116c291906151d3565b83516116d7906001600160401b031684615339565b6116e190846152d6565b61351a565b9250505090565b6000610e6a613529565b60026117016125fe565b81146117105780610d706125fe565b61171e610d998260016151d3565b60006801bc16d674ec8000006117326129c5565b61173c9190615339565b90506117548161174a6129c5565b6111c891906152d6565b61176081610c766123cc565b50600080516020615b2b83398151915281600036604051611309939291906151f9565b6000610e6a612a80565b600061179761339b565b516117ab906001600160401b031683615339565b61166b90836152d6565b6117bd6125cf565b6001600160a01b0316336001600160a01b0316146117f0573360405163472511eb60e11b8152600401610d0e9190614d80565b6117f981613299565b6040516001600160a01b03821690600080516020615eab83398151915290600090a250565b610e77612a80565b6060611830612839565b6001600160a01b0316635f2e5f0784846040518363ffffffff1660e01b815260040161185d92919061539e565b600060405180830381865afa15801561187a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261100891908101906153d5565b6000610e6a612839565b6000610e6a6125cf565b600061166b826131de565b6000806000806118cf61339b565b905060006118dc826134cf565b82519091506118f4906001600160401b031682615339565b6118fe90826152d6565b945081604001516001600160401b031682602001516001600160401b03168661192791906152b7565b61193191906152b7565b9350600182604001516001600160401b031683602001516001600160401b031684600001516001600160401b03168861196a91906151d3565b61197491906152b7565b61197e91906152b7565b61198891906152d6565b92505050909192565b6119996125cf565b6001600160a01b0316336001600160a01b0316146119cc573360405163472511eb60e11b8152600401610d0e9190614d80565b6119d581613547565b6119de81613566565b7f8d2df192dd17edf92a7964b78aa322f3d717b2ab9de00651bee32bbc4c5da63a816040516113099190614cfe565b611a1561304f565b6001600160a01b0316336001600160a01b031614611a48573360405163472511eb60e11b8152600401610d0e9190614d80565b611a5f611a5a36839003830183615475565b61359e565b600080516020615d2b833981519152611a7b6020830183615502565b611a8b6040840160208501615502565b611a9b6060850160408601615502565b611aab6080860160608701615502565b611abb60a0870160808801615502565b60405161130995949392919061551d565b600061166b82613647565b611adf61304f565b6001600160a01b0316336001600160a01b031614611b12573360405163472511eb60e11b8152600401610d0e9190614d80565b611b1b81613674565b6040516001600160a01b038216907fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e0803190600090a250565b6000610e6a613699565b6060610e6a6136b7565b6000610e6a612f38565b6000611b7a612984565b54919050565b6060611b8a612839565b6001600160a01b0316637c044e5586868686600161ffff6040518763ffffffff1660e01b8152600401611bc29695949392919061554f565b6000604051808303816000875af1158015611be1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c099190810190615595565b95945050505050565b6000610e6a61376b565b611c24614a50565b610e6a613789565b6000610e6a611c3961339b565b6134cf565b6000610eb9338484611c503388613415565b61165391906152d6565b60003383611c6882826130b2565b8380611c87576040516336b216db60e21b815260040160405180910390fd5b338580611c93836131de565b1015611cb2576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b038816611cde57336000604051637617407560e11b8152600401610d0e92919061531f565b611ce9338989612908565b98975050505050505050565b611cfe816137cb565b61128581610c4c565b611d0f6125cf565b6001600160a01b0316336001600160a01b031614611d42573360405163472511eb60e11b8152600401610d0e9190614d80565b61128581612641565b6000610e6a6128ea565b6000610e6a612857565b610eaa33610c4c565b610e77613031565b60006110088383613415565b611d84614a6a565b610e6a6137f2565b610e7761335f565b611d9c613699565b6001600160a01b0316336001600160a01b031614611dcf573360405163472511eb60e11b8152600401610d0e9190614d80565b6000611dd961339b565b9050611de6818335613842565b611e065760405163a225656d60e01b815282356004820152602401610d0e565b611e0e614a81565b6000611e18612984565b60038101546040840181905290915060608501351015611e565781604001518460600135604051621ee1cf60e11b8152600401610d0e9291906151eb565b6040820151611e699060608601356152d6565b608083015260028101546060830181905260408501351015611eaa5781606001518460400135604051636f24834360e01b8152600401610d0e9291906151eb565b611eb2612f38565b611ec260c0860160a0870161562a565b63ffffffff161180611ef25750600581015463ffffffff16611eea60c0860160a0870161562a565b63ffffffff16105b15611f4757611f0760c0850160a0860161562a565b611f0f612f38565b6005830154604051632f776b1760e01b815263ffffffff93841660048201526024810192909252919091166044820152606401610d0e565b6060820151611f5a9060408601356152d6565b60a08301528054611f6e908490863561389f565b60c083015250611f7c612f72565b815260a08101516080820151600091611f94916151d3565b1115611fac57611fac8160a0015182608001516138da565b611fb46149d3565b8335815260208085013590820152604080850135908201526060808501359082015260808085013590820152611ff060c0850160a0860161562a565b63ffffffff1660a082015261200c610100850160e08601615660565b151560c082015261202561012085016101008601615660565b151560e0820152612035816139fa565b506000612040613789565b905060006120578284600001518560c00151613a91565b9050612061612f72565b602084018190528351116120e457825161207c9082906151d3565b836020015111156120b2578251602084015160c0850151845160405163eb7a968960e01b8152610d0e949392919060040161567d565b825160208401516120c391906152d6565b610120840180519190915251516120da90826152d6565b60e084015261216a565b60006120f4838560000151613ac5565b90506121048185600001516129e3565b845161211091906152d6565b8460200151101561214857835160208086015160c08701519186015160405163063bb83f60e11b8152610d0e9493919060040161567d565b6020840151845161215991906152d6565b61216390836151d3565b60e0850152505b60e0830151156121c8576121818360e00151613ada565b61012084018051602090810192909252519081015181519091906121a69083906151d3565b9052506101208301516020015160e0840180516121c49083906152d6565b9052505b60e083015115612207576121df8360e00151613ba2565b6101208401805160409081019290925251015160e0840180516122039083906152d6565b9052505b60e0830151156122295761221e8360e00151613c68565b610120840151606001525b6101208301515115612245576101208301515161224590613d3a565b6122b4608086013561225a60c0880188615698565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061229d92505050610100890160e08a01615660565b6122af6101208a016101008b01615660565b613e5f565b6122bc614153565b6122c46142d8565b6122d18360c00151614300565b7f49ac0d2bb2a688ca460f7993eb93eccd3b9c9188da6b0727e9a409cf8b10587585846101200151604051612307929190615729565b60405180910390a15050505050565b600061166b82613497565b600061166b61232e61339b565b83613842565b61233c6125cf565b6001600160a01b0316336001600160a01b03161461236f573360405163472511eb60e11b8152600401610d0e9190614d80565b6123788161324f565b6040516001600160a01b03821690600080516020615c6b83398151915290600090a250565b6000610e6a6129c5565b6112856123c36001600080516020615eeb8339815191526152d6565b829055565b9055565b6000610e6a6123ea6001600080516020615e4b8339815191526152d6565b5490565b7f48f67c1dada0cab2163f6282292ad97ea97376cfed46bb3851654aaa630db7276124176123cc565b826040516124269291906151eb565b60405180910390a1611285816143d6565b600061244384836143f2565b9050600061244f6128ea565b9050836001600160a01b0316856001600160a01b031614156124cf57604051632d20488160e11b81526001600160a01b03821690635a4091029061249a90889060019060040161522f565b60006040518083038186803b1580156124b257600080fd5b505afa1580156124c6573d6000803e3d6000fd5b505050506125c8565b604051632d20488160e11b81526001600160a01b03821690635a409102906124fe90889060019060040161522f565b60006040518083038186803b15801561251657600080fd5b505afa15801561252a573d6000803e3d6000fd5b505060405163e838dfbb60e01b81526001600160a01b038416925063e838dfbb915061255a908790600401614d80565b602060405180830381865afa158015612577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259b91906157fd565b156125bb578360405163e7d05e2760e01b8152600401610d0e9190614d80565b6125c6858584612908565b505b5050505050565b6000610e6a614451565b6125e2816137cb565b6112856123c36001600080516020615b6b8339815191526152d6565b6000610e6a6123ea6001600080516020615eeb8339815191526152d6565b612625816137cb565b6112856123c36001600080516020615e6b8339815191526152d6565b61264a8161446f565b805160208201516040517e4180017d3dd609da6980999655a6bd2591e313d31d6230b1889c369a9713a0926113099290916001600160801b0392831681529116602082015260400190565b6126f16040518060a00160405280896001600160401b03168152602001886001600160401b03168152602001876001600160401b03168152602001866001600160401b03168152602001856001600160401b031681525061359e565b600080516020615d2b833981519152878787878760405161271695949392919061551d565b60405180910390a161273b604051806040016040528084815260200183815250613059565b600080516020615d8b833981519152828260405161275a9291906151eb565b60405180910390a161276a6149d3565b6127726144af565b815261277c6144df565b602082015260006040820181905260608201819052608082015261279e61450f565b63ffffffff1660a0820152600060c0820181905260e08201526127c0816139fa565b5050505050505050565b6127d3836137cb565b6127dc826137cb565b6127e783838361453f565b816001600160a01b0316836001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161282c91815260200190565b60405180910390a3505050565b6000610e6a6123ea6001600080516020615e6b8339815191526152d6565b6000610e6a614584565b61286a816137cb565b612873816145a2565b6040516001600160a01b038216907f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a190600090a250565b6128b3816145ab565b6040516001600160a01b038216907f2a0f8515de3fa34ef68b99300347b8793c01683350743e96fe440594528298f490600090a250565b6000610e6a6123ea6001600080516020615cab8339815191526152d6565b600061292784836129188761345b565b61292291906152d6565b6145b4565b61293f83836129358661345b565b61292291906151d3565b826001600160a01b0316846001600160a01b0316600080516020615e0b8339815191528460405161297291815260200190565b60405180910390a35060019392505050565b60008061166b6001600080516020615b0b8339815191526152d6565b6129a9816137cb565b6112856123c36001600080516020615d6b8339815191526152d6565b6000610e6a6123ea6001600080516020615d4b8339815191526152d6565b60008183116129f25782611008565b50919050565b606080612a0361376b565b6001600160a01b031663277c9d45846040518263ffffffff1660e01b8152600401612a3091815260200190565b6000604051808303816000875af1158015612a4f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a7791908101906158e0565b91509150915091565b6000610e6a6123ea6001600080516020615e2b8339815191526152d6565b6030835114612ac05760405163050cb55360e41b815260040160405180910390fd5b6060825114612ae25760405163408ebd3960e01b815260040160405180910390fd5b6801bc16d674ec8000006000612afc633b9aca008361528d565b90506000600286600060801b604051602001612b19929190615943565b60408051601f1981840301815290829052612b3391615972565b602060405180830381855afa158015612b50573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612b73919061598e565b90506000600280612b8788600060406145ee565b604051612b949190615972565b602060405180830381855afa158015612bb1573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612bd4919061598e565b6002612bec896040612be78160606152d6565b6145ee565b604051612bff91906000906020016159a7565b60408051601f1981840301815290829052612c1991615972565b602060405180830381855afa158015612c36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612c59919061598e565b60408051602081019390935282015260600160408051601f1981840301815290829052612c8591615972565b602060405180830381855afa158015612ca2573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612cc5919061598e565b905060006002808488604051602001612ce8929190918252602082015260400190565b60408051601f1981840301815290829052612d0291615972565b602060405180830381855afa158015612d1f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612d42919061598e565b6002612d4d876146b1565b604080516020810192909252810186905260600160408051601f1981840301815290829052612d7b91615972565b602060405180830381855afa158015612d98573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612dbb919061598e565b60408051602081019390935282015260600160408051601f1981840301815290829052612de791615972565b602060405180830381855afa158015612e04573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612e27919061598e565b90506000612e3586476152d6565b9050612e3f61471e565b6001600160a01b03166322895118878b8a604051602001612e6291815260200190565b6040516020818303038152906040528c876040518663ffffffff1660e01b8152600401612e9294939291906159c9565b6000604051808303818588803b158015612eab57600080fd5b505af1158015612ebf573d6000803e3d6000fd5b5050505050804714612ee457604051638051a6bb60e01b815260040160405180910390fd5b505050505050505050565b7f86fd21e9b5bd76b20471c7f93a82aa4e25c37d48b179bda0a4d1a45e22a842f4612f186129c5565b82604051612f279291906151eb565b60405180910390a16112858161473c565b6000610e6a6123ea6001600080516020615b8b8339815191526152d6565b6112856123c36001600080516020615b8b8339815191526152d6565b600080612f7d612984565b600581015490915063ffffffff166000612f95612f38565b90508082101561300a576801bc16d674ec800000612fb383836152d6565b612fbd91906152b7565b612fc561337d565b612fcd6129c5565b612fd56123cc565b8660010154612fe491906151d3565b612fee91906151d3565b612ff891906151d3565b61300291906151d3565b935050505090565b61301261337d565b61301a6129c5565b6130226123cc565b8560010154612fee91906151d3565b6000610e6a6123ea6001600080516020615b6b8339815191526152d6565b6000610e6a6118ac565b60006130746001600080516020615e8b8339815191526152d6565b8251815560209092015160019092019190915550565b6000610e6a614758565b6000610e6a6123ea6001600080516020615beb8339815191526152d6565b60006130bc6128ea565b60405163e838dfbb60e01b81529091506001600160a01b0382169063e838dfbb906130eb908690600401614d80565b602060405180830381865afa158015613108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312c91906157fd565b1561314c578260405163e7d05e2760e01b8152600401610d0e9190614d80565b60405163e838dfbb60e01b81526001600160a01b0382169063e838dfbb90613178908590600401614d80565b602060405180830381865afa158015613195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131b991906157fd565b156131d9578160405163e7d05e2760e01b8152600401610d0e9190614d80565b505050565b600061166b8261345b565b60006131f58333613415565b90508181101561323757604051637b936de360e01b81526001600160a01b03841660048201523360248201526044810182905260648101839052608401610d0e565b60001981146131d9576131d9833361165385856152d6565b613258816137cb565b6112856123c36001600080516020615c8b8339815191526152d6565b61327d81614776565b6112856123c36001600080516020615beb8339815191526152d6565b6132a2816137cb565b6112856123c36001600080516020615cab8339815191526152d6565b6132c7816137cb565b6112856123c36001600080516020615ccb8339815191526152d6565b6132ec82614799565b6040516001600160a01b038316907e043cf7635f276413ae358250286a479a631abd9d74d57d4aa0bb87ebc7d11790600090a2613328816147be565b6040518181527f4c86ba184ea1a1558f84835ca34f6d67e222e8ee5cc4f324b8861dda4cf1740c9060200160405180910390a15050565b6000610e6a6123ea6001600080516020615d6b8339815191526152d6565b6000610e6a6123ea6001600080516020615d0b8339815191526152d6565b6133a3614a22565b60006133be6001600080516020615bcb8339815191526152d6565b6040805160a08101825282546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b90048216606082015260019092015416608082015292915050565b6000806134316001600080516020615dab8339815191526152d6565b6001600160a01b039485166000908152602091825260408082209590961681529390525050205490565b6000806134776001600080516020615deb8339815191526152d6565b6001600160a01b0390931660009081526020939093525050604090205490565b6000806134a2614758565b9050806134b25750600092915050565b806134bb612f72565b6134c590856152b7565b611008919061528d565b600081602001516001600160401b031682604001516001600160401b031683606001516001600160401b03164261350691906152d6565b613510919061528d565b61166b919061528d565b60008183106129f25782611008565b6000610e6a6123ea6001600080516020615c8b8339815191526152d6565b805161128557604051638d46fe0560e01b815260040160405180910390fd5b60006135816001600080516020615c0b8339815191526152d6565b825190915081906135989082906020860190614afc565b50505050565b60006135b96001600080516020615bcb8339815191526152d6565b825181546020850151604086015160608701516001600160401b039485166001600160801b031990941693909317600160401b92851692909202919091176001600160801b0316600160801b918416919091026001600160c01b031617600160c01b91831691909102178255608090930151600190910180546001600160401b031916919093161790915550565b600080613652614758565b9050806136625750600092915050565b61366a612f72565b6134c582856152b7565b61367d816137cb565b6112856123c36001600080516020615c4b8339815191526152d6565b6000610e6a6123ea6001600080516020615c4b8339815191526152d6565b606060006136d46001600080516020615c0b8339815191526152d6565b8054909150819081906136e690615a14565b80601f016020809104026020016040519081016040528092919081815260200182805461371290615a14565b801561375f5780601f106137345761010080835404028352916020019161375f565b820191906000526020600020905b81548152906001019060200180831161374257829003601f168201915b50505050509250505090565b6000610e6a6123ea6001600080516020615ccb8339815191526152d6565b613791614a50565b60006137ac6001600080516020615e8b8339815191526152d6565b6040805180820190915281548152600190910154602082015292915050565b6001600160a01b0381166112855760405163f6b2911f60e01b815260040160405180910390fd5b6137fa614a6a565b60006138156001600080516020615ecb8339815191526152d6565b6040805180820190915290546001600160801b038082168352600160801b90910416602082015292915050565b600082608001516001600160401b03168261385d91906151d3565b613866846134cf565b1015801561387b5750613877612984565b5482115b801561100857508251613897906001600160401b031683615339565b159392505050565b6000836020015184604001516138b59190615a49565b6001600160401b03166138c884846152d6565b6138d291906152b7565b949350505050565b4760006138e783856151d3565b90506138f1612a80565b6001600160a01b031663ea74f479826040518263ffffffff1660e01b815260040161391e91815260200190565b600060405180830381600087803b15801561393857600080fd5b505af115801561394c573d6000803e3d6000fd5b505050506000824761395e91906152d6565b905061396a84866151d3565b81146139965761397a84866151d3565b816040516349a1938b60e01b8152600401610d0e9291906151eb565b84156139a8576139a885610c766123cc565b83156139c9576139c9846139ba61337d565b6139c491906151d3565b6147f8565b7fcb5410dc8f29b2f498e023c3f9237dbd600255a717edf94a6072bcd03b0c773c85856040516123079291906151eb565b6000613a156001600080516020615b0b8339815191526152d6565b825181556020830151600182015560408301516002820155606083015160038201556080830151600482015560a08301516005909101805460c085015160e0909501511515600160281b0260ff60281b19951515600160201b0264ffffffffff1990921663ffffffff9094169390931717939093161790915550565b6000613aa36301e133806127106152b7565b84518390613ab190866152b7565b613abb91906152b7565b6138d2919061528d565b60006127108360200151836134c591906152b7565b600080613ae561335f565b60405163c8a6dfd360e01b81526004810185905290915047906001600160a01b0383169063c8a6dfd390602401600060405180830381600087803b158015613b2c57600080fd5b505af1158015613b40573d6000803e3d6000fd5b5050505060008147613b5291906152d6565b90508015613b6657613b6681610c766123cc565b6040518181527fda841d3042d792e2509a333b9dcbd4b3dd9b9047d382011f8788fab90ca7e3c7906020015b60405180910390a1949350505050565b600047613bad612839565b6001600160a01b0316630c779401846040518263ffffffff1660e01b8152600401613bda91815260200190565b600060405180830381600087803b158015613bf457600080fd5b505af1158015613c08573d6000803e3d6000fd5b5050505060008147613c1a91906152d6565b90508015613c2e57613c2e81610c766123cc565b6040518181527f4e484734eb4d444bfa106f917d05d9ceb8ce18bf516c85d7aeb9b322925339f99060200160405180910390a19392505050565b600080613c73613031565b90506001600160a01b038116613c8c5750600092915050565b604051638ede6b6b60e01b81526004810184905247906001600160a01b03831690638ede6b6b90602401600060405180830381600087803b158015613cd057600080fd5b505af1158015613ce4573d6000803e3d6000fd5b5050505060008147613cf691906152d6565b90508015613d0a57613d0a81610c766123cc565b6040518181527fd500b67e5bd8019c0af744cadeec120d1b5e3d3a3a011f18cf182aa4c97947b690602001613b92565b6000613d4461308a565b905080613d6457604051630d35acd760e21b815260040160405180910390fd5b6000613d6e612f72565b90506000613d7a613094565b9050600081613d8985876152b7565b613d9391906152b7565b90506000613da183876152b7565b613dad612710866152b7565b613db791906152d6565b905060008115613dd057613dcb828461528d565b613dd3565b60005b90508015613e56576000613de5613529565b9050613df18183614841565b6000613dfb61308a565b90506000613e098a896152d6565b9050826001600160a01b03167f3d1669e813a9845c288f0e1f642a4343a451103b87886d12de37e63b39bbd942828b8b86604051613e4a949392919061567d565b60405180910390a25050505b50505050505050565b613e6761376b565b6001600160a01b031663b405e17484613e7e612f38565b6040518363ffffffff1660e01b8152600401613e9b929190615a78565b600060405180830381600087803b158015613eb557600080fd5b505af1158015613ec9573d6000803e3d6000fd5b505050508015613ed857613598565b6000613ee261308a565b905080156125c8576000613ef461337d565b90506000613f006123cc565b90506000613f70613f0f612839565b6001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611666919061598e565b905080613f7d89856151d3565b10156127c057858015613f905750600082115b15613fe1576000613fb58385613fa68c866152d6565b613fb091906152d6565b6129e3565b90508015613fdf57613fc781856151d3565b9350613fd2846147f8565b613fdf610c8082856152d6565b505b6000613feb61376b565b9050600080826001600160a01b0316634a3c63bb6040518163ffffffff1660e01b81526004016040805180830381865afa15801561402d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140519190615ac6565b915063ffffffff16915060006801bc16d674ec80000083831161407557600061407f565b61407f84846152d6565b61408991906152b7565b905084816140978e8a6151d3565b6140a191906151d3565b10156141455760006140da826140b78f8b6151d3565b6140c191906151d3565b6140cb90886152d6565b6801bc16d674ec80000061489e565b9050846001600160a01b0316632d1fc39d826140f4612f38565b6040518363ffffffff1660e01b81526004016141119291906151eb565b600060405180830381600087803b15801561412b57600080fd5b505af115801561413f573d6000803e3d6000fd5b50505050505b505050505050505050505050565b600061415d612839565b90506000614169612f72565b9050600061417561308a565b90506000821180156141875750600081115b156131d9576000836001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa1580156141cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f0919061598e565b90508060006141fe82613497565b9050600061420a61337d565b9050808211156142235780915061422082613647565b92505b60408051858152602081018590529081018390527f709263092d8d9fef472d907900405b5edae3d76f8ff4354858025b18424d71019060600160405180910390a18115613e56576142776139c483836152d6565b61428187846148d1565b60405163b30d8bb760e01b8152600481018490526001600160a01b0388169063b30d8bb79084906024016000604051808303818588803b1580156142c457600080fd5b505af1158015614145573d6000803e3d6000fd5b60006142e261337d565b90508015611285576142f681610c766123cc565b61128560006147f8565b600061430a612f72565b905060006143166123cc565b905060006143226137f2565b8051909150600090614366906001600160801b031661271061434486886152d6565b85602001516001600160801b031661435c91906152b7565b6116e1919061528d565b9050600061438b6201518061437b88856152b7565b614385919061528d565b856129e3565b90506801bc16d674ec8000006143a1818361528d565b6143ab91906152b7565b905080156125c6576143c9816143bf6129c5565b6111c891906151d3565b6125c6610c8082866152d6565b6112856123c36001600080516020615e4b8339815191526152d6565b600080826143fe612f72565b61440891906152d6565b9050806144215782915061441c8484614841565b61444a565b8061442a61308a565b61443490856152b7565b61443e919061528d565b915061444a8483614841565b5092915050565b6000610e6a6123ea6001600080516020615c2b8339815191526152d6565b600061448a6001600080516020615ecb8339815191526152d6565b82516020909301516001600160801b03908116600160801b0293169290921790915550565b6000610e6a6123ea60017fd7f2d45e512a86049f7a113657b39731b6b558609584243063a52cd31a8eb5296152d6565b6000610e6a6123ea60017ffedfd2c285a57fb23bf45a3fe9ac02d36a76ebb72801b1c8aaf553d74e9d46536152d6565b6000610e6a6123ea60017f0f1e7733641e4d843128fea0d2ec90d3d06a40b0fe244ff603d8c1aa200dc0f96152d6565b600061455a6001600080516020615dab8339815191526152d6565b6001600160a01b039485166000908152602091825260408082209590961681529390525091902055565b6000610e6a6123ea6001600080516020615f0b8339815191526152d6565b61128581614921565b61128581614946565b60006145cf6001600080516020615deb8339815191526152d6565b6001600160a01b03909316600090815260209390935250604090912055565b60608182601f011015614614576040516323d5783d60e11b815260040160405180910390fd5b61461e82846151d3565b8451101561463f57604051633b99b53d60e01b815260040160405180910390fd5b60608215801561465e57604051915060008252602082016040526146a8565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561469757805183526020928301920161467f565b5050858452601f01601f1916604052505b50949350505050565b603881901c60ff908116603083901c8216602884901c8316602085901c8416601886901c8516601087901c8616600888811c9790971688881b61ff001617871b17861b17851b17841b17831b1790911b17604082901c801561471557614715615af4565b5060c01b919050565b6000610e6a6123ea6001600080516020615bab8339815191526152d6565b6112856123c36001600080516020615d4b8339815191526152d6565b6000610e6a6123ea6001600080516020615b4b8339815191526152d6565b612710811115611285576040516358d620b360e01b815260040160405180910390fd5b6147a2816137cb565b6112856123c36001600080516020615bab8339815191526152d6565b806147dc5760405163a9cb9e0d60e01b815260040160405180910390fd5b6112856123c36001600080516020615e2b8339815191526152d6565b7f215c2b83e8c232e42091088056ab75d2ff643855c32997024f786cddb22d229061482161337d565b826040516148309291906151eb565b60405180910390a161128581614962565b61485c8161484d614758565b61485791906151d3565b61497e565b61486a82826129358561345b565b6040518181526001600160a01b03831690600090600080516020615e0b833981519152906020015b60405180910390a35050565b6000806148ab8385615339565b116148b75760006148ba565b60015b60ff166148c7838561528d565b61100891906151d3565b6148e7816148dd614758565b61485791906152d6565b6148f582826129188561345b565b6040518181526000906001600160a01b03841690600080516020615e0b83398151915290602001614892565b61492a816137cb565b6112856123c36001600080516020615c2b8339815191526152d6565b6112856123c36001600080516020615f0b8339815191526152d6565b6112856123c36001600080516020615d0b8339815191526152d6565b614987816149b7565b6040518181527fc80ea35a3f9016535e5b7c87746740c5045afe42188d02c5786eb97495c2f42990602001611309565b6112856123c36001600080516020615b4b8339815191526152d6565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600063ffffffff1681526020016000151581526020016000151581525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604051806040016040528060008152602001600081525090565b604080518082019091526000808252602082015290565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001614af76040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b828054614b0890615a14565b90600052602060002090601f016020900481019282614b2a5760008555614b70565b82601f10614b4357805160ff1916838001178555614b70565b82800160010185558215614b70579182015b82811115614b70578251825591602001919060010190614b55565b50614b7c929150614b80565b5090565b5b80821115614b7c5760008155600101614b81565b80356001600160a01b0381168114614bac57600080fd5b919050565b600060208284031215614bc357600080fd5b61100882614b95565b80356001600160401b0381168114614bac57600080fd5b80356001600160801b0381168114614bac57600080fd5b6000806000806000806000806000806101408b8d031215614c1a57600080fd5b614c238b614b95565b9950614c3160208c01614bcc565b9850614c3f60408c01614bcc565b9750614c4d60608c01614bcc565b9650614c5b60808c01614bcc565b9550614c6960a08c01614bcc565b945060c08b0135935060e08b01359250614c866101008c01614be3565b9150614c956101208c01614be3565b90509295989b9194979a5092959850565b60005b83811015614cc1578181015183820152602001614ca9565b838111156135985750506000910152565b60008151808452614cea816020860160208601614ca6565b601f01601f19169290920160200192915050565b6020815260006110086020830184614cd2565b60008060408385031215614d2457600080fd5b614d2d83614b95565b946020939093013593505050565b60008060408385031215614d4e57600080fd5b82359150614d5e60208401614b95565b90509250929050565b600060208284031215614d7957600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6000604082840312156129f257600080fd5b600080600060608486031215614dbb57600080fd5b614dc484614b95565b9250614dd260208501614b95565b9150604084013590509250925092565b60008060008060008060008060006101208a8c031215614e0157600080fd5b614e0a8a614b95565b9850614e1860208b01614b95565b975060408a01359650614e2d60608b01614b95565b9550614e3b60808b01614b95565b9450614e4960a08b01614b95565b9350614e5760c08b01614b95565b9250614e6560e08b01614b95565b91506101008a013590509295985092959850929598565b60008083601f840112614e8e57600080fd5b5081356001600160401b03811115614ea557600080fd5b6020830191508360208260051b8501011115614ec057600080fd5b9250929050565b60008060208385031215614eda57600080fd5b82356001600160401b03811115614ef057600080fd5b614efc85828601614e7c565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b81811015614f4357835160070b83529284019291840191600101614f24565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614f8757614f87614f4f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614fb557614fb5614f4f565b604052919050565b60006001600160401b03821115614fd657614fd6614f4f565b50601f01601f191660200190565b600060208284031215614ff657600080fd5b81356001600160401b0381111561500c57600080fd5b8201601f8101841361501d57600080fd5b803561503061502b82614fbd565b614f8d565b81815285602083850101111561504557600080fd5b81602084016020830137600091810160200191909152949350505050565b600060a082840312156129f257600080fd5b6000806000806040858703121561508b57600080fd5b84356001600160401b03808211156150a257600080fd5b6150ae88838901614e7c565b909650945060208701359150808211156150c757600080fd5b506150d487828801614e7c565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015614f4357835160ff16835292840192918401916001016150fc565b60006040828403121561512d57600080fd5b615135614f65565b61513e83614be3565b815261514c60208401614be3565b60208201529392505050565b6000806040838503121561516b57600080fd5b61517483614b95565b9150614d5e60208401614b95565b60006020828403121561519457600080fd5b81356001600160401b038111156151aa57600080fd5b8201610120818503121561100857600080fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156151e6576151e66151bd565b500190565b918252602082015260400190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6001600160a01b03929092168252602082015260400190565b63ffffffff8116811461128557600080fd5b60006020828403121561526c57600080fd5b815161100881615248565b634e487b7160e01b600052601260045260246000fd5b60008261529c5761529c615277565b500490565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156152d1576152d16151bd565b500290565b6000828210156152e8576152e86151bd565b500390565b6000604082840312156152ff57600080fd5b615307614f65565b82358152602083013560208201528091505092915050565b6001600160a01b0392831681529116602082015260400190565b60008261534857615348615277565b500690565b8035614bac81615248565b8183526000602080850194508260005b8581101561539357813561537b81615248565b63ffffffff1687529582019590820190600101615368565b509495945050505050565b6020815260006138d2602083018486615358565b60006001600160401b038211156153cb576153cb614f4f565b5060051b60200190565b600060208083850312156153e857600080fd5b82516001600160401b038111156153fe57600080fd5b8301601f8101851361540f57600080fd5b805161541d61502b826153b2565b81815260059190911b8201830190838101908783111561543c57600080fd5b928401925b8284101561546a5783518060070b811461545b5760008081fd5b82529284019290840190615441565b979650505050505050565b600060a0828403121561548757600080fd5b60405160a081016001600160401b03811182821017156154a9576154a9614f4f565b6040526154b583614bcc565b81526154c360208401614bcc565b60208201526154d460408401614bcc565b60408201526154e560608401614bcc565b60608201526154f660808401614bcc565b60808201529392505050565b60006020828403121561551457600080fd5b61100882614bcc565b6001600160401b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b60808152600061556360808301888a615358565b8281036020840152615576818789615358565b9415156040840152505061ffff91909116606090910152949350505050565b600060208083850312156155a857600080fd5b82516001600160401b038111156155be57600080fd5b8301601f810185136155cf57600080fd5b80516155dd61502b826153b2565b81815260059190911b820183019083810190878311156155fc57600080fd5b928401925b8284101561546a57835160ff8116811461561b5760008081fd5b82529284019290840190615601565b60006020828403121561563c57600080fd5b813561100881615248565b801515811461128557600080fd5b8035614bac81615647565b60006020828403121561567257600080fd5b813561100881615647565b93845260208401929092526040830152606082015260800190565b6000808335601e198436030181126156af57600080fd5b8301803591506001600160401b038211156156c957600080fd5b6020019150600581901b3603821315614ec057600080fd5b6000808335601e198436030181126156f857600080fd5b83016020810192503590506001600160401b0381111561571757600080fd5b8060051b3603831315614ec057600080fd5b60a08152823560a0820152602083013560c0820152604083013560e0820152600061010060608501358184015261012060808601358185015261576e60a0870161534d565b63ffffffff1661014085015261578760c08701876156e1565b8261016087015261579d6101c087018284615358565b925050506157ad60e08701615655565b15156101808501526157c0868301615655565b8015156101a08601529150915061100890506020830184805182526020810151602083015260408101516040830152606081015160608301525050565b60006020828403121561580f57600080fd5b815161100881615647565b600082601f83011261582b57600080fd5b8151602061583b61502b836153b2565b82815260059290921b8401810191818101908684111561585a57600080fd5b8286015b848110156158d55780516001600160401b0381111561587d5760008081fd5b8701603f8101891361588f5760008081fd5b8481015160406158a161502b83614fbd565b8281528b828486010111156158b65760008081fd5b6158c583898301848701614ca6565b865250505091830191830161585e565b509695505050505050565b600080604083850312156158f357600080fd5b82516001600160401b038082111561590a57600080fd5b6159168683870161581a565b9350602085015191508082111561592c57600080fd5b506159398582860161581a565b9150509250929050565b60008351615955818460208801614ca6565b6001600160801b0319939093169190920190815260100192915050565b60008251615984818460208701614ca6565b9190910192915050565b6000602082840312156159a057600080fd5b5051919050565b600083516159b9818460208801614ca6565b9190910191825250602001919050565b6080815260006159dc6080830187614cd2565b82810360208401526159ee8187614cd2565b90508281036040840152615a028186614cd2565b91505082606083015295945050505050565b600181811c90821680615a2857607f821691505b602082108114156129f257634e487b7160e01b600052602260045260246000fd5b60006001600160401b0382811684821681151582840482111615615a6f57615a6f6151bd565b02949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615ab757815163ffffffff1684529284019290840190600101615a95565b50505092019290925292915050565b60008060408385031215615ad957600080fd5b8251615ae481615248565b6020939093015192949293505050565b634e487b7160e01b600052600160045260246000fdfedbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a716b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70bf4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a80c77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a835efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf91260d84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a37b63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd6b5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb113c8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd2227867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a7803f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd69061bd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc884850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cfbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b65ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5cc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee054078471da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a8838ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c422b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b711e458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae4f81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca0424c305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d182055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a9847281a2646970667358221220e02de5da910f2e302ce88e1d383cfbca158bb52fff77f76d823f8ce65ed1a89164736f6c634300080a0033

Deployed Bytecode

0x6080604052600436106103555760003560e01c80635d95e801116101b95780635d95e801146108595780635f2e5f071461086157806363f62aaf1461088e5780636e9960c3146108a357806370a08231146108b857806372f79b13146108d8578063750521f51461090857806378a010e814610928578063799a1954146109485780637adbf97314610968578063833b1fce1461098857806386a92af71461099d57806387f2adfb146109b257806389896aef146109c75780639332525d146109dc57806395d89b4114610a095780639b498e2614610a375780639d49cca114610a4c578063a29a839f14610a7c578063a457c2d714610a91578063a9059cbb14610ab1578063ac232bde14610ad1578063bb6583ec14610ae4578063bf15af5614610b04578063c5eff3d014610b19578063d046815614610b2e578063d0e30db014610b43578063d497052414610b4b578063d7f8f4741461072b578063dd62ed3e14610b53578063e3a88e6114610b73578063efd6034714610baf578063efd6684614610bb7578063f79c3f0214610bd7578063f9f95a9014610bf7578063fb5b82d014610c17578063fe7c12ae14610c3757610365565b8063020f086e1461037e5780630407de471461039e57806304843a17146103be578063056850c6146103e657806306fdde03146103ee578063095ea7b3146104315780630e18b68114610461578063107703ab14610476578063107d7fa0146104ab5780631311cf8d146104c057806313d86aed146104e0578063143a08d414610500578063147bf6c4146105155780631546962b1461053557806315ca4cee1461055757806317e648581461057757806318160ddd146105f75780631bcbfaba1461060c57806323b872dd14610621578063281a312214610641578063291206f6146106615780632cb562e1146106815780632d6b59bf146106965780632dc5c97c146106ab578063313ce5671461070f57806336bf33251461072b57806339509351146107485780633af9e6691461076857806346425ef0146107885780634b47b74f1461079d57806350228201146107b2578063540bc5ea146107c757806354a29cdc146107dc578063557ed1ba146107f1578063563967151461080457806357fa85471461081957806358bf3c7f1461083957610365565b366103655761036333610c4c565b005b60405163574b16a760e11b815260040160405180910390fd5b34801561038a57600080fd5b50610363610399366004614bb1565b610cd3565b3480156103aa57600080fd5b506103636103b9366004614bfa565b610d57565b3480156103ca57600080fd5b506103d3610e60565b6040519081526020015b60405180910390f35b610363610e6f565b3480156103fa57600080fd5b50604080518082019091526011815270098d2e2ead2c840a6e8c2d6cac8408aa89607b1b60208201525b6040516103dd9190614cfe565b34801561043d57600080fd5b5061045161044c366004614d11565b610eac565b60405190151581526020016103dd565b34801561046d57600080fd5b50610363610ec2565b34801561048257600080fd5b50610496610491366004614d3b565b610f17565b60405163ffffffff90911681526020016103dd565b3480156104b757600080fd5b506103d361100f565b3480156104cc57600080fd5b506103636104db366004614bb1565b611028565b3480156104ec57600080fd5b506103636104fb366004614d67565b611091565b34801561050c57600080fd5b506103d3611237565b34801561052157600080fd5b50610363610530366004614bb1565b611241565b34801561054157600080fd5b5061054a611288565b6040516103dd9190614d80565b34801561056357600080fd5b50610363610572366004614d94565b611292565b34801561058357600080fd5b5061058c611314565b6040516103dd9190600061010082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015263ffffffff60a08401511660a083015260c0830151151560c083015260e0830151151560e083015292915050565b34801561060357600080fd5b506103d3611396565b34801561061857600080fd5b506103d36113a0565b34801561062d57600080fd5b5061045161063c366004614da6565b6113aa565b34801561064d57600080fd5b5061036361065c366004614de2565b611450565b34801561066d57600080fd5b5061036361067c366004614d67565b6115b1565b34801561068d57600080fd5b5061054a611613565b3480156106a257600080fd5b506103d361161d565b3480156106b757600080fd5b506106c0611627565b6040516103dd919081516001600160401b039081168252602080840151821690830152604083810151821690830152606080840151821690830152608092830151169181019190915260a00190565b34801561071b57600080fd5b50604051601281526020016103dd565b34801561073757600080fd5b506103d36801bc16d674ec80000081565b34801561075457600080fd5b50610451610763366004614d11565b611637565b34801561077457600080fd5b506103d3610783366004614bb1565b611658565b34801561079457600080fd5b506103d3611671565b3480156107a957600080fd5b506103d3611684565b3480156107be57600080fd5b5061054a6116ed565b3480156107d357600080fd5b506103d3606081565b3480156107e857600080fd5b506103636116f7565b3480156107fd57600080fd5b50426103d3565b34801561081057600080fd5b506103d3611783565b34801561082557600080fd5b506103d3610834366004614d67565b61178d565b34801561084557600080fd5b50610363610854366004614bb1565b6117b5565b61036361181e565b34801561086d57600080fd5b5061088161087c366004614ec7565b611826565b6040516103dd9190614f08565b34801561089a57600080fd5b5061054a6118a2565b3480156108af57600080fd5b5061054a6118ac565b3480156108c457600080fd5b506103d36108d3366004614bb1565b6118b6565b3480156108e457600080fd5b506108ed6118c1565b604080519384526020840192909252908201526060016103dd565b34801561091457600080fd5b50610363610923366004614fe4565b611991565b34801561093457600080fd5b50610363610943366004615063565b611a0d565b34801561095457600080fd5b506103d3610963366004614d67565b611acc565b34801561097457600080fd5b50610363610983366004614bb1565b611ad7565b34801561099457600080fd5b5061054a611b52565b3480156109a957600080fd5b50610424611b5c565b3480156109be57600080fd5b506103d3611b66565b3480156109d357600080fd5b506103d3611b70565b3480156109e857600080fd5b506109fc6109f7366004615075565b611b80565b6040516103dd91906150e0565b348015610a1557600080fd5b50604080518082019091526005815264098e68aa8960db1b6020820152610424565b348015610a4357600080fd5b5061054a611c12565b348015610a5857600080fd5b50610a61611c1c565b604080518251815260209283015192810192909252016103dd565b348015610a8857600080fd5b506103d3611c2c565b348015610a9d57600080fd5b50610451610aac366004614d11565b611c3e565b348015610abd57600080fd5b50610451610acc366004614d11565b611c5a565b610363610adf366004614bb1565b611cf5565b348015610af057600080fd5b50610363610aff36600461511b565b611d07565b348015610b1057600080fd5b506103d3603081565b348015610b2557600080fd5b5061054a611d4b565b348015610b3a57600080fd5b5061054a611d55565b610363611d5f565b610363611d68565b348015610b5f57600080fd5b506103d3610b6e366004615158565b611d70565b348015610b7f57600080fd5b50610b88611d7c565b6040805182516001600160801b0390811682526020938401511692810192909252016103dd565b610363611d8c565b348015610bc357600080fd5b50610363610bd2366004615182565b611d94565b348015610be357600080fd5b506103d3610bf2366004614d67565b612316565b348015610c0357600080fd5b50610451610c12366004614d67565b612321565b348015610c2357600080fd5b50610363610c32366004614bb1565b612334565b348015610c4357600080fd5b506103d361239d565b34610c6a576040516395b66fe960e01b815260040160405180910390fd5b610c8534610c766123cc565b610c8091906151d3565b6123ee565b610c90338234612437565b6040513481526001600160a01b0382169033907f3bc57f469ad6d10d7723ea226cd22bd2b9e527def2b529f6ab44645a166895829060200160405180910390a350565b610cdb6125cf565b6001600160a01b0316336001600160a01b031614610d17573360405163472511eb60e11b8152600401610d0e9190614d80565b60405180910390fd5b610d20816125d9565b6040516001600160a01b038216907f67b26a33f305cc027b2d45b2f6f418793afcd3e22f7376afa7be068ce18604e890600090a250565b6001610d616125fe565b8114610d8b5780610d706125fe565b604051631cfd276760e31b8152600401610d0e9291906151eb565b610d9e610d998260016151d3565b6123a7565b610da78b61261c565b7faf890c07e266df31e0725841eb0e85596a0caa1b17bbae5c0b206fdcc92d7ce18b604051610dd69190614d80565b60405180910390a1610e0d6040518060400160405280856001600160801b03168152602001846001600160801b0316815250612641565b610e1c8a8a8a8a8a8a8a612695565b610e29308c6000196127ca565b600080516020615b2b83398151915281600036604051610e4b939291906151f9565b60405180910390a15050505050505050505050565b6000610e6a6123cc565b905090565b610e77612839565b6001600160a01b0316336001600160a01b031614610eaa573360405163472511eb60e11b8152600401610d0e9190614d80565b565b6000610eb93384846127ca565b50600192915050565b610eca612857565b6001600160a01b0316336001600160a01b031614610efd573360405163472511eb60e11b8152600401610d0e9190614d80565b610f0d610f08612857565b612861565b610eaa60006128aa565b6000610f216128ea565b6001600160a01b0316635a4091023360046040518363ffffffff1660e01b8152600401610f4f92919061522f565b60006040518083038186803b158015610f6757600080fd5b505afa158015610f7b573d6000803e3d6000fd5b50505050610f8a333085612908565b50610f93612839565b60405163107703ab60e01b8152600481018590526001600160a01b038481166024830152919091169063107703ab906044016020604051808303816000875af1158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611008919061525a565b9392505050565b6000611019612984565b6005015463ffffffff16919050565b6110306125cf565b6001600160a01b0316336001600160a01b031614611063573360405163472511eb60e11b8152600401610d0e9190614d80565b61106c816129a0565b6040516001600160a01b03821690600080516020615dcb83398151915290600090a250565b600061109b6129c5565b905060006110bb6110b56801bc16d674ec8000008461528d565b846129e3565b9050806110db57604051631036b5ad60e31b815260040160405180910390fd5b6000806110e7836129f8565b815191935091508061110c5760405163200149ad60e21b815260040160405180910390fd5b8381111561112d57604051635993bd5760e01b815260040160405180910390fd5b6000611137612a80565b90508061115757604051639be7315960e01b815260040160405180910390fd5b60005b828110156111a75761119f858281518110611177576111776152a1565b6020026020010151858381518110611191576111916152a1565b602002602001015184612a9e565b60010161115a565b506111cd6111be836801bc16d674ec8000006152b7565b6111c890886152d6565b612eef565b60006111d7612f38565b90506111eb6111e684836151d3565b612f56565b7f220ab8fd274cf58c09b0825ccf00e74ba4ce4117fd47285adc2183a635838f1b8161121785826151d3565b6040516112259291906151eb565b60405180910390a15050505050505050565b6000610e6a612f72565b6112496125cf565b6001600160a01b0316336001600160a01b03161461127c573360405163472511eb60e11b8152600401610d0e9190614d80565b611285816128aa565b50565b6000610e6a613031565b61129a61304f565b6001600160a01b0316336001600160a01b0316146112cd573360405163472511eb60e11b8152600401610d0e9190614d80565b6112e46112df368390038301836152ed565b613059565b604051600080516020615d8b83398151915290611309908335906020850135906151eb565b60405180910390a150565b61131c6149d3565b611324612984565b60408051610100810182528254815260018301546020820152600283015491810191909152600382015460608201526004820154608082015260059091015463ffffffff811660a083015260ff600160201b82048116151560c0840152600160281b90910416151560e0820152919050565b6000610e6a61308a565b6000610e6a613094565b600083836113b882826130b2565b83806113d7576040516336b216db60e21b815260040160405180910390fd5b8685806113e3836131de565b1015611402576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b03881661142e57886000604051637617407560e11b8152600401610d0e92919061531f565b61143889886131e9565b611443898989612908565b9998505050505050505050565b600061145a6125fe565b81146114695780610d706125fe565b611477610d998260016151d3565b61148086612861565b6114898361324f565b6040516001600160a01b03841690600080516020615c6b83398151915290600090a26114b482613274565b604051828152600080516020615ceb8339815191529060200160405180910390a16114de896129a0565b6040516001600160a01b038a1690600080516020615dcb83398151915290600090a261150985613299565b6040516001600160a01b03861690600080516020615eab83398151915290600090a2611534846132be565b6040516001600160a01b038516907fffc0721ef0563a1b0a51a0dc92113025f33ca434ada9ee3eebff2f385d2a8f9a90600090a26115728a896132e3565b61157b87611b12565b600080516020615b2b8339815191528160003660405161159d939291906151f9565b60405180910390a150505050505050505050565b6115b96125cf565b6001600160a01b0316336001600160a01b0316146115ec573360405163472511eb60e11b8152600401610d0e9190614d80565b6115f581613274565b604051818152600080516020615ceb83398151915290602001611309565b6000610e6a61335f565b6000610e6a61337d565b61162f614a22565b610e6a61339b565b6000610eb93384846116493388613415565b61165391906151d3565b6127ca565b600061166b6116668361345b565b613497565b92915050565b600061167b612984565b60010154905090565b60008061168f61339b565b9050600061169c826134cf565b90506116e682600001516001600160401b03166116b7612984565b546116c291906151d3565b83516116d7906001600160401b031684615339565b6116e190846152d6565b61351a565b9250505090565b6000610e6a613529565b60026117016125fe565b81146117105780610d706125fe565b61171e610d998260016151d3565b60006801bc16d674ec8000006117326129c5565b61173c9190615339565b90506117548161174a6129c5565b6111c891906152d6565b61176081610c766123cc565b50600080516020615b2b83398151915281600036604051611309939291906151f9565b6000610e6a612a80565b600061179761339b565b516117ab906001600160401b031683615339565b61166b90836152d6565b6117bd6125cf565b6001600160a01b0316336001600160a01b0316146117f0573360405163472511eb60e11b8152600401610d0e9190614d80565b6117f981613299565b6040516001600160a01b03821690600080516020615eab83398151915290600090a250565b610e77612a80565b6060611830612839565b6001600160a01b0316635f2e5f0784846040518363ffffffff1660e01b815260040161185d92919061539e565b600060405180830381865afa15801561187a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261100891908101906153d5565b6000610e6a612839565b6000610e6a6125cf565b600061166b826131de565b6000806000806118cf61339b565b905060006118dc826134cf565b82519091506118f4906001600160401b031682615339565b6118fe90826152d6565b945081604001516001600160401b031682602001516001600160401b03168661192791906152b7565b61193191906152b7565b9350600182604001516001600160401b031683602001516001600160401b031684600001516001600160401b03168861196a91906151d3565b61197491906152b7565b61197e91906152b7565b61198891906152d6565b92505050909192565b6119996125cf565b6001600160a01b0316336001600160a01b0316146119cc573360405163472511eb60e11b8152600401610d0e9190614d80565b6119d581613547565b6119de81613566565b7f8d2df192dd17edf92a7964b78aa322f3d717b2ab9de00651bee32bbc4c5da63a816040516113099190614cfe565b611a1561304f565b6001600160a01b0316336001600160a01b031614611a48573360405163472511eb60e11b8152600401610d0e9190614d80565b611a5f611a5a36839003830183615475565b61359e565b600080516020615d2b833981519152611a7b6020830183615502565b611a8b6040840160208501615502565b611a9b6060850160408601615502565b611aab6080860160608701615502565b611abb60a0870160808801615502565b60405161130995949392919061551d565b600061166b82613647565b611adf61304f565b6001600160a01b0316336001600160a01b031614611b12573360405163472511eb60e11b8152600401610d0e9190614d80565b611b1b81613674565b6040516001600160a01b038216907fd3b5d1e0ffaeff528910f3663f0adace7694ab8241d58e17a91351ced2e0803190600090a250565b6000610e6a613699565b6060610e6a6136b7565b6000610e6a612f38565b6000611b7a612984565b54919050565b6060611b8a612839565b6001600160a01b0316637c044e5586868686600161ffff6040518763ffffffff1660e01b8152600401611bc29695949392919061554f565b6000604051808303816000875af1158015611be1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611c099190810190615595565b95945050505050565b6000610e6a61376b565b611c24614a50565b610e6a613789565b6000610e6a611c3961339b565b6134cf565b6000610eb9338484611c503388613415565b61165391906152d6565b60003383611c6882826130b2565b8380611c87576040516336b216db60e21b815260040160405180910390fd5b338580611c93836131de565b1015611cb2576040516351940b3960e11b815260040160405180910390fd5b6001600160a01b038816611cde57336000604051637617407560e11b8152600401610d0e92919061531f565b611ce9338989612908565b98975050505050505050565b611cfe816137cb565b61128581610c4c565b611d0f6125cf565b6001600160a01b0316336001600160a01b031614611d42573360405163472511eb60e11b8152600401610d0e9190614d80565b61128581612641565b6000610e6a6128ea565b6000610e6a612857565b610eaa33610c4c565b610e77613031565b60006110088383613415565b611d84614a6a565b610e6a6137f2565b610e7761335f565b611d9c613699565b6001600160a01b0316336001600160a01b031614611dcf573360405163472511eb60e11b8152600401610d0e9190614d80565b6000611dd961339b565b9050611de6818335613842565b611e065760405163a225656d60e01b815282356004820152602401610d0e565b611e0e614a81565b6000611e18612984565b60038101546040840181905290915060608501351015611e565781604001518460600135604051621ee1cf60e11b8152600401610d0e9291906151eb565b6040820151611e699060608601356152d6565b608083015260028101546060830181905260408501351015611eaa5781606001518460400135604051636f24834360e01b8152600401610d0e9291906151eb565b611eb2612f38565b611ec260c0860160a0870161562a565b63ffffffff161180611ef25750600581015463ffffffff16611eea60c0860160a0870161562a565b63ffffffff16105b15611f4757611f0760c0850160a0860161562a565b611f0f612f38565b6005830154604051632f776b1760e01b815263ffffffff93841660048201526024810192909252919091166044820152606401610d0e565b6060820151611f5a9060408601356152d6565b60a08301528054611f6e908490863561389f565b60c083015250611f7c612f72565b815260a08101516080820151600091611f94916151d3565b1115611fac57611fac8160a0015182608001516138da565b611fb46149d3565b8335815260208085013590820152604080850135908201526060808501359082015260808085013590820152611ff060c0850160a0860161562a565b63ffffffff1660a082015261200c610100850160e08601615660565b151560c082015261202561012085016101008601615660565b151560e0820152612035816139fa565b506000612040613789565b905060006120578284600001518560c00151613a91565b9050612061612f72565b602084018190528351116120e457825161207c9082906151d3565b836020015111156120b2578251602084015160c0850151845160405163eb7a968960e01b8152610d0e949392919060040161567d565b825160208401516120c391906152d6565b610120840180519190915251516120da90826152d6565b60e084015261216a565b60006120f4838560000151613ac5565b90506121048185600001516129e3565b845161211091906152d6565b8460200151101561214857835160208086015160c08701519186015160405163063bb83f60e11b8152610d0e9493919060040161567d565b6020840151845161215991906152d6565b61216390836151d3565b60e0850152505b60e0830151156121c8576121818360e00151613ada565b61012084018051602090810192909252519081015181519091906121a69083906151d3565b9052506101208301516020015160e0840180516121c49083906152d6565b9052505b60e083015115612207576121df8360e00151613ba2565b6101208401805160409081019290925251015160e0840180516122039083906152d6565b9052505b60e0830151156122295761221e8360e00151613c68565b610120840151606001525b6101208301515115612245576101208301515161224590613d3a565b6122b4608086013561225a60c0880188615698565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061229d92505050610100890160e08a01615660565b6122af6101208a016101008b01615660565b613e5f565b6122bc614153565b6122c46142d8565b6122d18360c00151614300565b7f49ac0d2bb2a688ca460f7993eb93eccd3b9c9188da6b0727e9a409cf8b10587585846101200151604051612307929190615729565b60405180910390a15050505050565b600061166b82613497565b600061166b61232e61339b565b83613842565b61233c6125cf565b6001600160a01b0316336001600160a01b03161461236f573360405163472511eb60e11b8152600401610d0e9190614d80565b6123788161324f565b6040516001600160a01b03821690600080516020615c6b83398151915290600090a250565b6000610e6a6129c5565b6112856123c36001600080516020615eeb8339815191526152d6565b829055565b9055565b6000610e6a6123ea6001600080516020615e4b8339815191526152d6565b5490565b7f48f67c1dada0cab2163f6282292ad97ea97376cfed46bb3851654aaa630db7276124176123cc565b826040516124269291906151eb565b60405180910390a1611285816143d6565b600061244384836143f2565b9050600061244f6128ea565b9050836001600160a01b0316856001600160a01b031614156124cf57604051632d20488160e11b81526001600160a01b03821690635a4091029061249a90889060019060040161522f565b60006040518083038186803b1580156124b257600080fd5b505afa1580156124c6573d6000803e3d6000fd5b505050506125c8565b604051632d20488160e11b81526001600160a01b03821690635a409102906124fe90889060019060040161522f565b60006040518083038186803b15801561251657600080fd5b505afa15801561252a573d6000803e3d6000fd5b505060405163e838dfbb60e01b81526001600160a01b038416925063e838dfbb915061255a908790600401614d80565b602060405180830381865afa158015612577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061259b91906157fd565b156125bb578360405163e7d05e2760e01b8152600401610d0e9190614d80565b6125c6858584612908565b505b5050505050565b6000610e6a614451565b6125e2816137cb565b6112856123c36001600080516020615b6b8339815191526152d6565b6000610e6a6123ea6001600080516020615eeb8339815191526152d6565b612625816137cb565b6112856123c36001600080516020615e6b8339815191526152d6565b61264a8161446f565b805160208201516040517e4180017d3dd609da6980999655a6bd2591e313d31d6230b1889c369a9713a0926113099290916001600160801b0392831681529116602082015260400190565b6126f16040518060a00160405280896001600160401b03168152602001886001600160401b03168152602001876001600160401b03168152602001866001600160401b03168152602001856001600160401b031681525061359e565b600080516020615d2b833981519152878787878760405161271695949392919061551d565b60405180910390a161273b604051806040016040528084815260200183815250613059565b600080516020615d8b833981519152828260405161275a9291906151eb565b60405180910390a161276a6149d3565b6127726144af565b815261277c6144df565b602082015260006040820181905260608201819052608082015261279e61450f565b63ffffffff1660a0820152600060c0820181905260e08201526127c0816139fa565b5050505050505050565b6127d3836137cb565b6127dc826137cb565b6127e783838361453f565b816001600160a01b0316836001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161282c91815260200190565b60405180910390a3505050565b6000610e6a6123ea6001600080516020615e6b8339815191526152d6565b6000610e6a614584565b61286a816137cb565b612873816145a2565b6040516001600160a01b038216907f5a272403b402d892977df56625f4164ccaf70ca3863991c43ecfe76a6905b0a190600090a250565b6128b3816145ab565b6040516001600160a01b038216907f2a0f8515de3fa34ef68b99300347b8793c01683350743e96fe440594528298f490600090a250565b6000610e6a6123ea6001600080516020615cab8339815191526152d6565b600061292784836129188761345b565b61292291906152d6565b6145b4565b61293f83836129358661345b565b61292291906151d3565b826001600160a01b0316846001600160a01b0316600080516020615e0b8339815191528460405161297291815260200190565b60405180910390a35060019392505050565b60008061166b6001600080516020615b0b8339815191526152d6565b6129a9816137cb565b6112856123c36001600080516020615d6b8339815191526152d6565b6000610e6a6123ea6001600080516020615d4b8339815191526152d6565b60008183116129f25782611008565b50919050565b606080612a0361376b565b6001600160a01b031663277c9d45846040518263ffffffff1660e01b8152600401612a3091815260200190565b6000604051808303816000875af1158015612a4f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612a7791908101906158e0565b91509150915091565b6000610e6a6123ea6001600080516020615e2b8339815191526152d6565b6030835114612ac05760405163050cb55360e41b815260040160405180910390fd5b6060825114612ae25760405163408ebd3960e01b815260040160405180910390fd5b6801bc16d674ec8000006000612afc633b9aca008361528d565b90506000600286600060801b604051602001612b19929190615943565b60408051601f1981840301815290829052612b3391615972565b602060405180830381855afa158015612b50573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612b73919061598e565b90506000600280612b8788600060406145ee565b604051612b949190615972565b602060405180830381855afa158015612bb1573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612bd4919061598e565b6002612bec896040612be78160606152d6565b6145ee565b604051612bff91906000906020016159a7565b60408051601f1981840301815290829052612c1991615972565b602060405180830381855afa158015612c36573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612c59919061598e565b60408051602081019390935282015260600160408051601f1981840301815290829052612c8591615972565b602060405180830381855afa158015612ca2573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612cc5919061598e565b905060006002808488604051602001612ce8929190918252602082015260400190565b60408051601f1981840301815290829052612d0291615972565b602060405180830381855afa158015612d1f573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612d42919061598e565b6002612d4d876146b1565b604080516020810192909252810186905260600160408051601f1981840301815290829052612d7b91615972565b602060405180830381855afa158015612d98573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612dbb919061598e565b60408051602081019390935282015260600160408051601f1981840301815290829052612de791615972565b602060405180830381855afa158015612e04573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250810190612e27919061598e565b90506000612e3586476152d6565b9050612e3f61471e565b6001600160a01b03166322895118878b8a604051602001612e6291815260200190565b6040516020818303038152906040528c876040518663ffffffff1660e01b8152600401612e9294939291906159c9565b6000604051808303818588803b158015612eab57600080fd5b505af1158015612ebf573d6000803e3d6000fd5b5050505050804714612ee457604051638051a6bb60e01b815260040160405180910390fd5b505050505050505050565b7f86fd21e9b5bd76b20471c7f93a82aa4e25c37d48b179bda0a4d1a45e22a842f4612f186129c5565b82604051612f279291906151eb565b60405180910390a16112858161473c565b6000610e6a6123ea6001600080516020615b8b8339815191526152d6565b6112856123c36001600080516020615b8b8339815191526152d6565b600080612f7d612984565b600581015490915063ffffffff166000612f95612f38565b90508082101561300a576801bc16d674ec800000612fb383836152d6565b612fbd91906152b7565b612fc561337d565b612fcd6129c5565b612fd56123cc565b8660010154612fe491906151d3565b612fee91906151d3565b612ff891906151d3565b61300291906151d3565b935050505090565b61301261337d565b61301a6129c5565b6130226123cc565b8560010154612fee91906151d3565b6000610e6a6123ea6001600080516020615b6b8339815191526152d6565b6000610e6a6118ac565b60006130746001600080516020615e8b8339815191526152d6565b8251815560209092015160019092019190915550565b6000610e6a614758565b6000610e6a6123ea6001600080516020615beb8339815191526152d6565b60006130bc6128ea565b60405163e838dfbb60e01b81529091506001600160a01b0382169063e838dfbb906130eb908690600401614d80565b602060405180830381865afa158015613108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312c91906157fd565b1561314c578260405163e7d05e2760e01b8152600401610d0e9190614d80565b60405163e838dfbb60e01b81526001600160a01b0382169063e838dfbb90613178908590600401614d80565b602060405180830381865afa158015613195573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131b991906157fd565b156131d9578160405163e7d05e2760e01b8152600401610d0e9190614d80565b505050565b600061166b8261345b565b60006131f58333613415565b90508181101561323757604051637b936de360e01b81526001600160a01b03841660048201523360248201526044810182905260648101839052608401610d0e565b60001981146131d9576131d9833361165385856152d6565b613258816137cb565b6112856123c36001600080516020615c8b8339815191526152d6565b61327d81614776565b6112856123c36001600080516020615beb8339815191526152d6565b6132a2816137cb565b6112856123c36001600080516020615cab8339815191526152d6565b6132c7816137cb565b6112856123c36001600080516020615ccb8339815191526152d6565b6132ec82614799565b6040516001600160a01b038316907e043cf7635f276413ae358250286a479a631abd9d74d57d4aa0bb87ebc7d11790600090a2613328816147be565b6040518181527f4c86ba184ea1a1558f84835ca34f6d67e222e8ee5cc4f324b8861dda4cf1740c9060200160405180910390a15050565b6000610e6a6123ea6001600080516020615d6b8339815191526152d6565b6000610e6a6123ea6001600080516020615d0b8339815191526152d6565b6133a3614a22565b60006133be6001600080516020615bcb8339815191526152d6565b6040805160a08101825282546001600160401b038082168352600160401b820481166020840152600160801b8204811693830193909352600160c01b90048216606082015260019092015416608082015292915050565b6000806134316001600080516020615dab8339815191526152d6565b6001600160a01b039485166000908152602091825260408082209590961681529390525050205490565b6000806134776001600080516020615deb8339815191526152d6565b6001600160a01b0390931660009081526020939093525050604090205490565b6000806134a2614758565b9050806134b25750600092915050565b806134bb612f72565b6134c590856152b7565b611008919061528d565b600081602001516001600160401b031682604001516001600160401b031683606001516001600160401b03164261350691906152d6565b613510919061528d565b61166b919061528d565b60008183106129f25782611008565b6000610e6a6123ea6001600080516020615c8b8339815191526152d6565b805161128557604051638d46fe0560e01b815260040160405180910390fd5b60006135816001600080516020615c0b8339815191526152d6565b825190915081906135989082906020860190614afc565b50505050565b60006135b96001600080516020615bcb8339815191526152d6565b825181546020850151604086015160608701516001600160401b039485166001600160801b031990941693909317600160401b92851692909202919091176001600160801b0316600160801b918416919091026001600160c01b031617600160c01b91831691909102178255608090930151600190910180546001600160401b031916919093161790915550565b600080613652614758565b9050806136625750600092915050565b61366a612f72565b6134c582856152b7565b61367d816137cb565b6112856123c36001600080516020615c4b8339815191526152d6565b6000610e6a6123ea6001600080516020615c4b8339815191526152d6565b606060006136d46001600080516020615c0b8339815191526152d6565b8054909150819081906136e690615a14565b80601f016020809104026020016040519081016040528092919081815260200182805461371290615a14565b801561375f5780601f106137345761010080835404028352916020019161375f565b820191906000526020600020905b81548152906001019060200180831161374257829003601f168201915b50505050509250505090565b6000610e6a6123ea6001600080516020615ccb8339815191526152d6565b613791614a50565b60006137ac6001600080516020615e8b8339815191526152d6565b6040805180820190915281548152600190910154602082015292915050565b6001600160a01b0381166112855760405163f6b2911f60e01b815260040160405180910390fd5b6137fa614a6a565b60006138156001600080516020615ecb8339815191526152d6565b6040805180820190915290546001600160801b038082168352600160801b90910416602082015292915050565b600082608001516001600160401b03168261385d91906151d3565b613866846134cf565b1015801561387b5750613877612984565b5482115b801561100857508251613897906001600160401b031683615339565b159392505050565b6000836020015184604001516138b59190615a49565b6001600160401b03166138c884846152d6565b6138d291906152b7565b949350505050565b4760006138e783856151d3565b90506138f1612a80565b6001600160a01b031663ea74f479826040518263ffffffff1660e01b815260040161391e91815260200190565b600060405180830381600087803b15801561393857600080fd5b505af115801561394c573d6000803e3d6000fd5b505050506000824761395e91906152d6565b905061396a84866151d3565b81146139965761397a84866151d3565b816040516349a1938b60e01b8152600401610d0e9291906151eb565b84156139a8576139a885610c766123cc565b83156139c9576139c9846139ba61337d565b6139c491906151d3565b6147f8565b7fcb5410dc8f29b2f498e023c3f9237dbd600255a717edf94a6072bcd03b0c773c85856040516123079291906151eb565b6000613a156001600080516020615b0b8339815191526152d6565b825181556020830151600182015560408301516002820155606083015160038201556080830151600482015560a08301516005909101805460c085015160e0909501511515600160281b0260ff60281b19951515600160201b0264ffffffffff1990921663ffffffff9094169390931717939093161790915550565b6000613aa36301e133806127106152b7565b84518390613ab190866152b7565b613abb91906152b7565b6138d2919061528d565b60006127108360200151836134c591906152b7565b600080613ae561335f565b60405163c8a6dfd360e01b81526004810185905290915047906001600160a01b0383169063c8a6dfd390602401600060405180830381600087803b158015613b2c57600080fd5b505af1158015613b40573d6000803e3d6000fd5b5050505060008147613b5291906152d6565b90508015613b6657613b6681610c766123cc565b6040518181527fda841d3042d792e2509a333b9dcbd4b3dd9b9047d382011f8788fab90ca7e3c7906020015b60405180910390a1949350505050565b600047613bad612839565b6001600160a01b0316630c779401846040518263ffffffff1660e01b8152600401613bda91815260200190565b600060405180830381600087803b158015613bf457600080fd5b505af1158015613c08573d6000803e3d6000fd5b5050505060008147613c1a91906152d6565b90508015613c2e57613c2e81610c766123cc565b6040518181527f4e484734eb4d444bfa106f917d05d9ceb8ce18bf516c85d7aeb9b322925339f99060200160405180910390a19392505050565b600080613c73613031565b90506001600160a01b038116613c8c5750600092915050565b604051638ede6b6b60e01b81526004810184905247906001600160a01b03831690638ede6b6b90602401600060405180830381600087803b158015613cd057600080fd5b505af1158015613ce4573d6000803e3d6000fd5b5050505060008147613cf691906152d6565b90508015613d0a57613d0a81610c766123cc565b6040518181527fd500b67e5bd8019c0af744cadeec120d1b5e3d3a3a011f18cf182aa4c97947b690602001613b92565b6000613d4461308a565b905080613d6457604051630d35acd760e21b815260040160405180910390fd5b6000613d6e612f72565b90506000613d7a613094565b9050600081613d8985876152b7565b613d9391906152b7565b90506000613da183876152b7565b613dad612710866152b7565b613db791906152d6565b905060008115613dd057613dcb828461528d565b613dd3565b60005b90508015613e56576000613de5613529565b9050613df18183614841565b6000613dfb61308a565b90506000613e098a896152d6565b9050826001600160a01b03167f3d1669e813a9845c288f0e1f642a4343a451103b87886d12de37e63b39bbd942828b8b86604051613e4a949392919061567d565b60405180910390a25050505b50505050505050565b613e6761376b565b6001600160a01b031663b405e17484613e7e612f38565b6040518363ffffffff1660e01b8152600401613e9b929190615a78565b600060405180830381600087803b158015613eb557600080fd5b505af1158015613ec9573d6000803e3d6000fd5b505050508015613ed857613598565b6000613ee261308a565b905080156125c8576000613ef461337d565b90506000613f006123cc565b90506000613f70613f0f612839565b6001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611666919061598e565b905080613f7d89856151d3565b10156127c057858015613f905750600082115b15613fe1576000613fb58385613fa68c866152d6565b613fb091906152d6565b6129e3565b90508015613fdf57613fc781856151d3565b9350613fd2846147f8565b613fdf610c8082856152d6565b505b6000613feb61376b565b9050600080826001600160a01b0316634a3c63bb6040518163ffffffff1660e01b81526004016040805180830381865afa15801561402d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140519190615ac6565b915063ffffffff16915060006801bc16d674ec80000083831161407557600061407f565b61407f84846152d6565b61408991906152b7565b905084816140978e8a6151d3565b6140a191906151d3565b10156141455760006140da826140b78f8b6151d3565b6140c191906151d3565b6140cb90886152d6565b6801bc16d674ec80000061489e565b9050846001600160a01b0316632d1fc39d826140f4612f38565b6040518363ffffffff1660e01b81526004016141119291906151eb565b600060405180830381600087803b15801561412b57600080fd5b505af115801561413f573d6000803e3d6000fd5b50505050505b505050505050505050505050565b600061415d612839565b90506000614169612f72565b9050600061417561308a565b90506000821180156141875750600081115b156131d9576000836001600160a01b0316630d8d2a546040518163ffffffff1660e01b8152600401602060405180830381865afa1580156141cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f0919061598e565b90508060006141fe82613497565b9050600061420a61337d565b9050808211156142235780915061422082613647565b92505b60408051858152602081018590529081018390527f709263092d8d9fef472d907900405b5edae3d76f8ff4354858025b18424d71019060600160405180910390a18115613e56576142776139c483836152d6565b61428187846148d1565b60405163b30d8bb760e01b8152600481018490526001600160a01b0388169063b30d8bb79084906024016000604051808303818588803b1580156142c457600080fd5b505af1158015614145573d6000803e3d6000fd5b60006142e261337d565b90508015611285576142f681610c766123cc565b61128560006147f8565b600061430a612f72565b905060006143166123cc565b905060006143226137f2565b8051909150600090614366906001600160801b031661271061434486886152d6565b85602001516001600160801b031661435c91906152b7565b6116e1919061528d565b9050600061438b6201518061437b88856152b7565b614385919061528d565b856129e3565b90506801bc16d674ec8000006143a1818361528d565b6143ab91906152b7565b905080156125c6576143c9816143bf6129c5565b6111c891906151d3565b6125c6610c8082866152d6565b6112856123c36001600080516020615e4b8339815191526152d6565b600080826143fe612f72565b61440891906152d6565b9050806144215782915061441c8484614841565b61444a565b8061442a61308a565b61443490856152b7565b61443e919061528d565b915061444a8483614841565b5092915050565b6000610e6a6123ea6001600080516020615c2b8339815191526152d6565b600061448a6001600080516020615ecb8339815191526152d6565b82516020909301516001600160801b03908116600160801b0293169290921790915550565b6000610e6a6123ea60017fd7f2d45e512a86049f7a113657b39731b6b558609584243063a52cd31a8eb5296152d6565b6000610e6a6123ea60017ffedfd2c285a57fb23bf45a3fe9ac02d36a76ebb72801b1c8aaf553d74e9d46536152d6565b6000610e6a6123ea60017f0f1e7733641e4d843128fea0d2ec90d3d06a40b0fe244ff603d8c1aa200dc0f96152d6565b600061455a6001600080516020615dab8339815191526152d6565b6001600160a01b039485166000908152602091825260408082209590961681529390525091902055565b6000610e6a6123ea6001600080516020615f0b8339815191526152d6565b61128581614921565b61128581614946565b60006145cf6001600080516020615deb8339815191526152d6565b6001600160a01b03909316600090815260209390935250604090912055565b60608182601f011015614614576040516323d5783d60e11b815260040160405180910390fd5b61461e82846151d3565b8451101561463f57604051633b99b53d60e01b815260040160405180910390fd5b60608215801561465e57604051915060008252602082016040526146a8565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561469757805183526020928301920161467f565b5050858452601f01601f1916604052505b50949350505050565b603881901c60ff908116603083901c8216602884901c8316602085901c8416601886901c8516601087901c8616600888811c9790971688881b61ff001617871b17861b17851b17841b17831b1790911b17604082901c801561471557614715615af4565b5060c01b919050565b6000610e6a6123ea6001600080516020615bab8339815191526152d6565b6112856123c36001600080516020615d4b8339815191526152d6565b6000610e6a6123ea6001600080516020615b4b8339815191526152d6565b612710811115611285576040516358d620b360e01b815260040160405180910390fd5b6147a2816137cb565b6112856123c36001600080516020615bab8339815191526152d6565b806147dc5760405163a9cb9e0d60e01b815260040160405180910390fd5b6112856123c36001600080516020615e2b8339815191526152d6565b7f215c2b83e8c232e42091088056ab75d2ff643855c32997024f786cddb22d229061482161337d565b826040516148309291906151eb565b60405180910390a161128581614962565b61485c8161484d614758565b61485791906151d3565b61497e565b61486a82826129358561345b565b6040518181526001600160a01b03831690600090600080516020615e0b833981519152906020015b60405180910390a35050565b6000806148ab8385615339565b116148b75760006148ba565b60015b60ff166148c7838561528d565b61100891906151d3565b6148e7816148dd614758565b61485791906152d6565b6148f582826129188561345b565b6040518181526000906001600160a01b03841690600080516020615e0b83398151915290602001614892565b61492a816137cb565b6112856123c36001600080516020615c2b8339815191526152d6565b6112856123c36001600080516020615f0b8339815191526152d6565b6112856123c36001600080516020615d0b8339815191526152d6565b614987816149b7565b6040518181527fc80ea35a3f9016535e5b7c87746740c5045afe42188d02c5786eb97495c2f42990602001611309565b6112856123c36001600080516020615b4b8339815191526152d6565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600063ffffffff1681526020016000151581526020016000151581525090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604051806040016040528060008152602001600081525090565b604080518082019091526000808252602082015290565b604051806101400160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001614af76040518060800160405280600081526020016000815260200160008152602001600081525090565b905290565b828054614b0890615a14565b90600052602060002090601f016020900481019282614b2a5760008555614b70565b82601f10614b4357805160ff1916838001178555614b70565b82800160010185558215614b70579182015b82811115614b70578251825591602001919060010190614b55565b50614b7c929150614b80565b5090565b5b80821115614b7c5760008155600101614b81565b80356001600160a01b0381168114614bac57600080fd5b919050565b600060208284031215614bc357600080fd5b61100882614b95565b80356001600160401b0381168114614bac57600080fd5b80356001600160801b0381168114614bac57600080fd5b6000806000806000806000806000806101408b8d031215614c1a57600080fd5b614c238b614b95565b9950614c3160208c01614bcc565b9850614c3f60408c01614bcc565b9750614c4d60608c01614bcc565b9650614c5b60808c01614bcc565b9550614c6960a08c01614bcc565b945060c08b0135935060e08b01359250614c866101008c01614be3565b9150614c956101208c01614be3565b90509295989b9194979a5092959850565b60005b83811015614cc1578181015183820152602001614ca9565b838111156135985750506000910152565b60008151808452614cea816020860160208601614ca6565b601f01601f19169290920160200192915050565b6020815260006110086020830184614cd2565b60008060408385031215614d2457600080fd5b614d2d83614b95565b946020939093013593505050565b60008060408385031215614d4e57600080fd5b82359150614d5e60208401614b95565b90509250929050565b600060208284031215614d7957600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6000604082840312156129f257600080fd5b600080600060608486031215614dbb57600080fd5b614dc484614b95565b9250614dd260208501614b95565b9150604084013590509250925092565b60008060008060008060008060006101208a8c031215614e0157600080fd5b614e0a8a614b95565b9850614e1860208b01614b95565b975060408a01359650614e2d60608b01614b95565b9550614e3b60808b01614b95565b9450614e4960a08b01614b95565b9350614e5760c08b01614b95565b9250614e6560e08b01614b95565b91506101008a013590509295985092959850929598565b60008083601f840112614e8e57600080fd5b5081356001600160401b03811115614ea557600080fd5b6020830191508360208260051b8501011115614ec057600080fd5b9250929050565b60008060208385031215614eda57600080fd5b82356001600160401b03811115614ef057600080fd5b614efc85828601614e7c565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b81811015614f4357835160070b83529284019291840191600101614f24565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614f8757614f87614f4f565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614fb557614fb5614f4f565b604052919050565b60006001600160401b03821115614fd657614fd6614f4f565b50601f01601f191660200190565b600060208284031215614ff657600080fd5b81356001600160401b0381111561500c57600080fd5b8201601f8101841361501d57600080fd5b803561503061502b82614fbd565b614f8d565b81815285602083850101111561504557600080fd5b81602084016020830137600091810160200191909152949350505050565b600060a082840312156129f257600080fd5b6000806000806040858703121561508b57600080fd5b84356001600160401b03808211156150a257600080fd5b6150ae88838901614e7c565b909650945060208701359150808211156150c757600080fd5b506150d487828801614e7c565b95989497509550505050565b6020808252825182820181905260009190848201906040850190845b81811015614f4357835160ff16835292840192918401916001016150fc565b60006040828403121561512d57600080fd5b615135614f65565b61513e83614be3565b815261514c60208401614be3565b60208201529392505050565b6000806040838503121561516b57600080fd5b61517483614b95565b9150614d5e60208401614b95565b60006020828403121561519457600080fd5b81356001600160401b038111156151aa57600080fd5b8201610120818503121561100857600080fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156151e6576151e66151bd565b500190565b918252602082015260400190565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b6001600160a01b03929092168252602082015260400190565b63ffffffff8116811461128557600080fd5b60006020828403121561526c57600080fd5b815161100881615248565b634e487b7160e01b600052601260045260246000fd5b60008261529c5761529c615277565b500490565b634e487b7160e01b600052603260045260246000fd5b60008160001904831182151516156152d1576152d16151bd565b500290565b6000828210156152e8576152e86151bd565b500390565b6000604082840312156152ff57600080fd5b615307614f65565b82358152602083013560208201528091505092915050565b6001600160a01b0392831681529116602082015260400190565b60008261534857615348615277565b500690565b8035614bac81615248565b8183526000602080850194508260005b8581101561539357813561537b81615248565b63ffffffff1687529582019590820190600101615368565b509495945050505050565b6020815260006138d2602083018486615358565b60006001600160401b038211156153cb576153cb614f4f565b5060051b60200190565b600060208083850312156153e857600080fd5b82516001600160401b038111156153fe57600080fd5b8301601f8101851361540f57600080fd5b805161541d61502b826153b2565b81815260059190911b8201830190838101908783111561543c57600080fd5b928401925b8284101561546a5783518060070b811461545b5760008081fd5b82529284019290840190615441565b979650505050505050565b600060a0828403121561548757600080fd5b60405160a081016001600160401b03811182821017156154a9576154a9614f4f565b6040526154b583614bcc565b81526154c360208401614bcc565b60208201526154d460408401614bcc565b60408201526154e560608401614bcc565b60608201526154f660808401614bcc565b60808201529392505050565b60006020828403121561551457600080fd5b61100882614bcc565b6001600160401b0395861681529385166020850152918416604084015283166060830152909116608082015260a00190565b60808152600061556360808301888a615358565b8281036020840152615576818789615358565b9415156040840152505061ffff91909116606090910152949350505050565b600060208083850312156155a857600080fd5b82516001600160401b038111156155be57600080fd5b8301601f810185136155cf57600080fd5b80516155dd61502b826153b2565b81815260059190911b820183019083810190878311156155fc57600080fd5b928401925b8284101561546a57835160ff8116811461561b5760008081fd5b82529284019290840190615601565b60006020828403121561563c57600080fd5b813561100881615248565b801515811461128557600080fd5b8035614bac81615647565b60006020828403121561567257600080fd5b813561100881615647565b93845260208401929092526040830152606082015260800190565b6000808335601e198436030181126156af57600080fd5b8301803591506001600160401b038211156156c957600080fd5b6020019150600581901b3603821315614ec057600080fd5b6000808335601e198436030181126156f857600080fd5b83016020810192503590506001600160401b0381111561571757600080fd5b8060051b3603831315614ec057600080fd5b60a08152823560a0820152602083013560c0820152604083013560e0820152600061010060608501358184015261012060808601358185015261576e60a0870161534d565b63ffffffff1661014085015261578760c08701876156e1565b8261016087015261579d6101c087018284615358565b925050506157ad60e08701615655565b15156101808501526157c0868301615655565b8015156101a08601529150915061100890506020830184805182526020810151602083015260408101516040830152606081015160608301525050565b60006020828403121561580f57600080fd5b815161100881615647565b600082601f83011261582b57600080fd5b8151602061583b61502b836153b2565b82815260059290921b8401810191818101908684111561585a57600080fd5b8286015b848110156158d55780516001600160401b0381111561587d5760008081fd5b8701603f8101891361588f5760008081fd5b8481015160406158a161502b83614fbd565b8281528b828486010111156158b65760008081fd5b6158c583898301848701614ca6565b865250505091830191830161585e565b509695505050505050565b600080604083850312156158f357600080fd5b82516001600160401b038082111561590a57600080fd5b6159168683870161581a565b9350602085015191508082111561592c57600080fd5b506159398582860161581a565b9150509250929050565b60008351615955818460208801614ca6565b6001600160801b0319939093169190920190815260100192915050565b60008251615984818460208701614ca6565b9190910192915050565b6000602082840312156159a057600080fd5b5051919050565b600083516159b9818460208801614ca6565b9190910191825250602001919050565b6080815260006159dc6080830187614cd2565b82810360208401526159ee8187614cd2565b90508281036040840152615a028186614cd2565b91505082606083015295945050505050565b600181811c90821680615a2857607f821691505b602082108114156129f257634e487b7160e01b600052602260045260246000fd5b60006001600160401b0382811684821681151582840482111615615a6f57615a6f6151bd565b02949350505050565b604080825283519082018190526000906020906060840190828701845b82811015615ab757815163ffffffff1684529284019290840190600101615a95565b50505092019290925292915050565b60008060408385031215615ad957600080fd5b8251615ae481615248565b6020939093015192949293505050565b634e487b7160e01b600052600160045260246000fdfedbc0527c99b54cd325d6ce9eaae3a8413cd447b5205f37385f0ebc6551033c6d1809e49bba43f2d39fa57894b50cd6ccb428cc438230e065cac3eb24a1355a716b842b424335d94ccad97e54548dfa02673c1268aba38d3c3c32d28c8988b70bf4271262f3552a4108cde54dc75061de8de495709221d793b126e448522d6a80c77078e3530c08cdb2440817c81de4836500b4708ea4d15672b7fe98956423a835efb61d8784060218d9d6aa40eae55904de43779c1afc79c74dfefcfdf91260d84ee2c84c954c65bef1459fe03b761a42f49234527e3cd8fd9dce87cb83742b094efef62d2ce60c14ffacd35a1b50546d3a9d503aff1df040176fffd6c92a37b63f3482ec84cb93d74a71645ad2e9e896fa02723e42170b4aad20a4bed6cdd6b5b37715a3e346e996104f0086703f19825def429233930fd9399c38e05fb113c8cbea9407c380ae944f052b5a442330057683c5abdbd453493f9750806afecb0cc5437d7c9c1d9eab549acbb533eea3e9868e9443dd75309ed5820b33a3774e082b6d18de7b10e438e6b1002141db737519cb4ceed679bc815e3aac00cd2227867d8f1a5e39d11d5bebde854d5359a509530ad32450f581da63c06ec8d1a7803f075dea7ef99b1e5db245018e5e4ed8d2a0d93953f5932b2176bef59bd69061bd533e726baaf59b36f3914d950053f7e78f527057c97cd3f0043257fc0fc884850308dd4e453a2a1bc3efb444560401d95c1a8bdea5b35c5c79531cd2241f1d25777eb44be046f64180acf8275f0ac2ec51e63a65a5f8a0f2f6d86ba25b74cfbcfa5a69252c74010ad3e9ab18cfbdc116fcf85f084db1a8dc577a339fbee58b8e9e2a1d30fed357d8a000c1131fc77ed65d2052918caf1ccc6eb1e7af3d13b65ab79ffcd89b6380c7fbdd89d02cfe3d9c53c99a85e150c2319075018d1aac5cc852254d5b703a16bb13b3e233a335d6459c5da5db0ca732d7a684ee054078471da4c245099590dc40be61880c9b97792f3694d970acc1e67ac0e6cc90f3780d0fb4a5ac9287f4f508aa7253ee2d57c6a228b1b30e210d73fffd59389d3a8838ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efb649e50315f962b32d487e696a81b4828631b11f8424daaaa37e9e97766a2c422b6136e423ab70d76431e2a635e877e16ea2dd9a895e054ad7f35f89d6c7b711e458cbedf69109e7d57b7f8c96816615aac0017187d87abab9001d22db32bae4f81b149de6749a3f46464b2cce61e24462f67599ea4a5ce028aaf4ab1521f96e30f015a5d3c72c0a9414538199baa022323a483fa9e4ba2cd581596cf8ca0424c305db9f63aeed94a45229ff5ab4174e72b223a38ab4c5e8f518ee4f437918d182055909238c0f5e63d6f174068ebb8f51bcec9bd37de63bb68f6551feec0cfd6e6ab8b7c7aaba79eef8cc633522d606bb008c101cf9832c9ad05d10a9847281a2646970667358221220e02de5da910f2e302ce88e1d383cfbca158bb52fff77f76d823f8ce65ed1a89164736f6c634300080a0033

Deployed Bytecode Sourcemap

1247:26087:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1276:20:6;1285:10;1276:8;:20::i;:::-;1247:26087:2;;1396:23:6;;-1:-1:-1;;;1396:23:6;;;;;;;;;;;7691:176:2;;;;;;;;;;-1:-1:-1;7691:176:2;;;;;:::i;:::-;;:::i;2647:1145::-;;;;;;;;;;-1:-1:-1;2647:1145:2;;;;;:::i;:::-;;:::i;3105:109:3:-;;;;;;;;;;;;;:::i;:::-;;;1725:25:60;;;1713:2;1698:18;3105:109:3;;;;;;;;8923:188:2;;;:::i;1945:97:5:-;;;;;;;;;;-1:-1:-1;2009:26:5;;;;;;;;;;;;-1:-1:-1;;;2009:26:5;;;;1945:97;;;;;;;:::i;4385:151::-;;;;;;;;;;-1:-1:-1;4385:151:5;;;;;:::i;:::-;;:::i;:::-;;;3032:14:60;;3025:22;3007:41;;2995:2;2980:18;4385:151:5;2867:187:60;1276:150:0;;;;;;;;;;;;;:::i;6120:377:2:-;;;;;;;;;;-1:-1:-1;6120:377:2;;;;;:::i;:::-;;:::i;:::-;;;3591:10:60;3579:23;;;3561:42;;3549:2;3534:18;6120:377:2;3417:192:60;7120:133:4;;;;;;;;;;;;;:::i;7468:188:2:-;;;;;;;;;;-1:-1:-1;7468:188:2;;;;;:::i;:::-;;:::i;3630:1658:3:-;;;;;;;;;;-1:-1:-1;3630:1658:3;;;;;:::i;:::-;;:::i;2470:104:5:-;;;;;;;;;;;;;:::i;1131::0:-;;;;;;;;;;-1:-1:-1;1131:104:0;;;;;:::i;:::-;;:::i;4794:108:2:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;10165:230:4:-;;;;;;;;;;-1:-1:-1;10165:230:4;;;;;:::i;:::-;;:::i;9363:168::-;;;;;;;;;;;;;:::i;:::-;;;;;;4396:4:60;4438:3;4427:9;4423:19;4415:27;;4475:6;4469:13;4458:9;4451:32;4539:4;4531:6;4527:17;4521:24;4514:4;4503:9;4499:20;4492:54;4602:4;4594:6;4590:17;4584:24;4577:4;4566:9;4562:20;4555:54;4665:4;4657:6;4653:17;4647:24;4640:4;4629:9;4625:20;4618:54;4728:4;4720:6;4716:17;4710:24;4703:4;4692:9;4688:20;4681:54;4803:10;4795:4;4787:6;4783:17;4777:24;4773:41;4766:4;4755:9;4751:20;4744:71;4885:4;4877:6;4873:17;4867:24;4860:32;4853:40;4846:4;4835:9;4831:20;4824:70;4964:4;4956:6;4952:17;4946:24;4939:32;4932:40;4925:4;4914:9;4910:20;4903:70;4216:763;;;;;2334:93:5;;;;;;;;;;;;;:::i;4243:95:2:-;;;;;;;;;;;;;:::i;3942:400:5:-;;;;;;;;;;-1:-1:-1;3942:400:5;;;;;:::i;:::-;;:::i;1457:1155:2:-;;;;;;;;;;-1:-1:-1;1457:1155:2;;;;;:::i;:::-;;:::i;6914:133::-;;;;;;;;;;-1:-1:-1;6914:133:2;;;;;:::i;:::-;;:::i;4647:112::-;;;;;;;;;;;;;:::i;5680:107::-;;;;;;;;;;;;;:::i;8317:108:4:-;;;;;;;;;;;;;:::i;:::-;;;;;;6360:13:60;;-1:-1:-1;;;;;6356:22:60;;;6338:41;;6439:4;6427:17;;;6421:24;6417:33;;6395:20;;;6388:63;6319:2;6499:17;;;6493:24;6489:33;;6467:20;;;6460:63;6583:4;6571:17;;;6565:24;6561:33;;6539:20;;;6532:63;6655:4;6643:17;;;6637:24;6633:33;6611:20;;;6604:63;;;;6288:3;6273:19;;6094:579;2215:76:5;;;;;;;;;;-1:-1:-1;2215:76:5;;2282:2;6820:36:60;;6808:2;6793:18;2215:76:5;6678:184:60;1438:47:3;;;;;;;;;;;;1477:8;1438:47;;4579:227:5;;;;;;;;;;-1:-1:-1;4579:227:5;;;;;:::i;:::-;;:::i;2769:145::-;;;;;;;;;;-1:-1:-1;2769:145:5;;;;;:::i;:::-;;:::i;6935:142:4:-;;;;;;;;;;;;;:::i;7296:351::-;;;;;;;;;;;;;:::i;4510:102:2:-;;;;;;;;;;;;;:::i;1346:45:3:-;;;;;;;;;;;;1389:2;1346:45;;3827:381:2;;;;;;;;;;;;;:::i;7859:90:4:-;;;;;;;;;;-1:-1:-1;7927:15:4;7859:90;;3272:119:3;;;;;;;;;;;;;:::i;8990:155:4:-;;;;;;;;;;-1:-1:-1;8990:155:4;;;;;:::i;:::-;;:::i;7082:158:2:-;;;;;;;;;;-1:-1:-1;7082:158:2;;;;;:::i;:::-;;:::i;8504:176::-;;;:::i;5822:263::-;;;;;;;;;;-1:-1:-1;5822:263:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4937:110::-;;;;;;;;;;;;;:::i;827:104:0:-;;;;;;;;;;;;;:::i;2617:109:5:-;;;;;;;;;;-1:-1:-1;2617:109:5;;;;;:::i;:::-;;:::i;8468:479:4:-;;;;;;;;;;;;;:::i;:::-;;;;8710:25:60;;;8766:2;8751:18;;8744:34;;;;8794:18;;;8787:34;8698:2;8683:18;8468:479:4;8508:319:60;7902:211:2;;;;;;;;;;-1:-1:-1;7902:211:2;;;;;:::i;:::-;;:::i;9774:348:4:-;;;;;;;;;;-1:-1:-1;9774:348:4;;;;;:::i;:::-;;:::i;3137:167:5:-;;;;;;;;;;-1:-1:-1;3137:167:5;;;;;:::i;:::-;;:::i;9574:157:4:-;;;;;;;;;;-1:-1:-1;9574:157:4;;;;;:::i;:::-;;:::i;6796:96::-;;;;;;;;;;;;;:::i;5082:105:2:-;;;;;;;;;;;;;:::i;3449:123:3:-;;;;;;;;;;;;;:::i;7992:127:4:-;;;;;;;;;;;;;:::i;6532:347:2:-;;;;;;;;;;-1:-1:-1;6532:347:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2085:87:5:-;;;;;;;;;;-1:-1:-1;2151:14:5;;;;;;;;;;;;-1:-1:-1;;;2151:14:5;;;;2085:87;;8148:118:2;;;;;;;;;;;;;:::i;9188:132:4:-;;;;;;;;;;;;;:::i;:::-;;;;12228:13:60;;12210:32;;12298:4;12286:17;;;12280:24;12258:20;;;12251:54;;;;12183:18;9188:132:4;11992:319:60;8162:112:4;;;;;;;;;;;;;:::i;4849:231:5:-;;;;;;;;;;-1:-1:-1;4849:231:5;;;;;:::i;:::-;;:::i;3538:361::-;;;;;;;;;;-1:-1:-1;3538:361:5;;;;;:::i;:::-;;:::i;1040:151:6:-;;;;;;:::i;:::-;;:::i;5457:188:2:-;;;;;;;;;;-1:-1:-1;5457:188:2;;;;;:::i;:::-;;:::i;1245:46:3:-;;;;;;;;;;;;1289:2;1245:46;;4373:102:2;;;;;;;;;;;;;:::i;972:118:0:-;;;;;;;;;;;;;:::i;919:73:6:-;;;:::i;8715:173:2:-;;;:::i;3347:148:5:-;;;;;;;;;;-1:-1:-1;3347:148:5;;;;;:::i;:::-;;:::i;5222:200:2:-;;;;;;;;;;;;;:::i;:::-;;;;13260:13:60;;-1:-1:-1;;;;;13256:22:60;;;13238:41;;13339:4;13327:17;;;13321:24;13317:33;13295:20;;;13288:63;;;;13173:18;5222:200:2;12962:395:60;8301:168:2;;;:::i;10993:9597:4:-;;;;;;;;;;-1:-1:-1;10993:9597:4;;;;;:::i;:::-;;:::i;2957:137:5:-;;;;;;;;;;-1:-1:-1;2957:137:5;;;;;:::i;:::-;;:::i;7690:126:4:-;;;;;;;;;;-1:-1:-1;7690:126:4;;;;;:::i;:::-;;:::i;7275:158:2:-;;;;;;;;;;-1:-1:-1;7275:158:2;;;;;:::i;:::-;;:::i;2938:109:3:-;;;;;;;;;;;;;:::i;1592:314:6:-;1653:9;1649:66;;1690:14;;-1:-1:-1;;;1690:14:6;;;;;;;;;;;1649:66;1725:56;1771:9;1746:22;:20;:22::i;:::-;:34;;;;:::i;:::-;1725:20;:56::i;:::-;1792:45;1803:10;1815;1827:9;1792:10;:45::i;:::-;1853:46;;1889:9;1725:25:60;;-1:-1:-1;;;;;1853:46:6;;;1865:10;;1853:46;;1713:2:60;1698:18;1853:46:6;;;;;;;1592:314;:::o;7691:176:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;:::-;;;;;;;;429:114;7771:41:2::1;7795:16;7771:23;:41::i;:::-;7827:33;::::0;-1:-1:-1;;;;;7827:33:2;::::1;::::0;::::1;::::0;;;::::1;7691:176:::0;:::o;2647:1145::-;3063:1;1146:13:1;:11;:13::i;:::-;1134:8;:25;1130:109;;1204:8;1214:13;:11;:13::i;:::-;1182:46;;-1:-1:-1;;;1182:46:1;;;;;;;;;:::i;1130:109::-;1248:25;1260:12;:8;1271:1;1260:12;:::i;:::-;1248:11;:25::i;:::-;3076:40:2::1;3101:14;3076:24;:40::i;:::-;3131:32;3148:14;3131:32;;;;;;:::i;:::-;;;;;;;;3174:283;3214:233;;;;;;;;3314:30;-1:-1:-1::0;;;;;3214:233:2::1;;;;;3397:35;-1:-1:-1::0;;;;;3214:233:2::1;;;::::0;3174:26:::1;:283::i;:::-;3468:248;3503:15;3532:14;3560:15;3589:12;3615:24;3653:20;3687:19;3468:21;:248::i;:::-;3727:58;3744:4;3751:14;-1:-1:-1::0;;3727:8:2::1;:58::i;:::-;-1:-1:-1::0;;;;;;;;;;;1354:8:1;1364;;1343:30;;;;;;;;:::i;:::-;;;;;;;;2647:1145:2;;;;;;;;;;;:::o;3105:109:3:-;3159:7;3185:22;:20;:22::i;:::-;3178:29;;3105:109;:::o;8923:188:2:-;9011:26;:24;:26::i;:::-;-1:-1:-1;;;;;8997:40:2;:10;-1:-1:-1;;;;;8997:40:2;;8993:112;;9083:10;9060:34;;-1:-1:-1;;;9060:34:2;;;;;;;;:::i;8993:112::-;8923:188::o;4385:151:5:-;4454:4;4470:38;4479:10;4491:8;4501:6;4470:8;:38::i;:::-;-1:-1:-1;4525:4:5;4385:151;;;;:::o;1276:150:0:-;666:35;:33;:35::i;:::-;-1:-1:-1;;;;;652:49:0;:10;-1:-1:-1;;;;;652:49:0;;648:121;;747:10;724:34;;-1:-1:-1;;;724:34:0;;;;;;;;:::i;648:121::-;1335:46:::1;1345:35;:33;:35::i;:::-;1335:9;:46::i;:::-;1391:28;1416:1;1391:16;:28::i;6120:377:2:-:0;6203:23;6251:22;:20;:22::i;:::-;-1:-1:-1;;;;;6238:48:2;;6287:10;547:8:21;6238:91:2;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6339:50;6349:10;6369:4;6376:12;6339:9;:50::i;:::-;;6423:26;:24;:26::i;:::-;6406:84;;-1:-1:-1;;;6406:84:2;;;;;15202:25:60;;;-1:-1:-1;;;;;15263:32:60;;;15243:18;;;15236:60;6406:58:2;;;;;;;15175:18:60;;6406:84:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6399:91;6120:377;-1:-1:-1;;;6120:377:2:o;7120:133:4:-;7174:7;7200:30;:28;:30::i;:::-;:46;;;;;;7120:133;-1:-1:-1;7120:133:4:o;7468:188:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7552:45:2::1;7578:18;7552:25;:45::i;:::-;7612:37;::::0;-1:-1:-1;;;;;7612:37:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;7612:37:2;;;::::1;7468:188:::0;:::o;3630:1658:3:-;3701:24;3728:22;:20;:22::i;:::-;3701:49;-1:-1:-1;3760:25:3;3788:58;3803:31;1477:8;3701:49;3803:31;:::i;:::-;3836:9;3788:14;:58::i;:::-;3760:86;-1:-1:-1;3861:22:3;3857:76;;3906:16;;-1:-1:-1;;;3906:16:3;;;;;;;;;;;3857:76;4102:25;4129;4158:37;4177:17;4158:18;:37::i;:::-;4239:17;;4101:94;;-1:-1:-1;4101:94:3;-1:-1:-1;4271:27:3;4267:91;;4321:26;;-1:-1:-1;;;4321:26:3;;;;;;;;;;;4267:91;4397:17;4372:22;:42;4368:103;;;4437:23;;-1:-1:-1;;;4437:23:3;;;;;;;;;;;4368:103;4481:29;4513:27;:25;:27::i;:::-;4481:59;-1:-1:-1;4555:26:3;4551:94;;4604:30;;-1:-1:-1;;;4604:30:3;;;;;;;;;;;4551:94;4660:11;4655:213;4683:22;4677:3;:28;4655:213;;;4722:74;4740:10;4751:3;4740:15;;;;;;;;:::i;:::-;;;;;;;4757:10;4768:3;4757:15;;;;;;;;:::i;:::-;;;;;;;4774:21;4722:17;:74::i;:::-;4838:5;;4655:213;;;-1:-1:-1;4877:78:3;4917:37;4932:22;1477:8;4917:37;:::i;:::-;4898:56;;:16;:56;:::i;:::-;4877:20;:78::i;:::-;4965:38;5006:29;:27;:29::i;:::-;4965:70;-1:-1:-1;5045:84:3;5073:55;5106:22;4965:70;5073:55;:::i;:::-;5045:27;:84::i;:::-;5144:137;5184:30;5216:55;5249:22;5184:30;5216:55;:::i;:::-;5144:137;;;;;;;:::i;:::-;;;;;;;;3691:1597;;;;;;;3630:1658;:::o;2470:104:5:-;2526:7;2552:15;:13;:15::i;1131:104:0:-;447:28;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;1201:27:::1;1218:9;1201:16;:27::i;:::-;1131:104:::0;:::o;4794:108:2:-;4844:7;4870:25;:23;:25::i;10165:230:4:-;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;10276:27:::1;;;::::0;;::::1;::::0;::::1;10293:9:::0;10276:27:::1;:::i;:::-;:16;:27::i;:::-;10318:70;::::0;-1:-1:-1;;;;;;;;;;;10318:70:4;::::1;::::0;10328:29;::::1;::::0;10359:28:::1;::::0;::::1;;::::0;10318:70:::1;:::i;:::-;;;;;;;;10165:230:::0;:::o;9363:168::-;9425:50;;:::i;:::-;9494:30;:28;:30::i;:::-;9487:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;9487:37:4;;;;;;;;;;-1:-1:-1;;;9487:37:4;;;;;;;;;;;9363:168;-1:-1:-1;9363:168:4:o;2334:93:5:-;2380:7;2406:14;:12;:14::i;4243:95:2:-;4290:7;4316:15;:13;:15::i;3942:400:5:-;4136:4;4049:5;4056:3;1267:23;1279:5;1286:3;1267:11;:23::i;:::-;4079:6;1473:11;1469:63:::1;;1507:14;;-1:-1:-1::0;;;1507:14:5::1;;;;;;;;;;;1469:63;4104:5:::2;4111:6;1830;1809:18;1820:6;1809:10;:18::i;:::-;:27;1805:80;;;1859:15;;-1:-1:-1::0;;;1859:15:5::2;;;;;;;;;;;1805:80;-1:-1:-1::0;;;;;4160:17:5;::::3;4156:94;;4221:5;4236:1;4200:39;;-1:-1:-1::0;;;4200:39:5::3;;;;;;;;;:::i;4156:94::-;4259:30;4275:5;4282:6;4259:15;:30::i;:::-;4306:29;4316:5;4323:3;4328:6;4306:9;:29::i;:::-;4299:36:::0;3942:400;-1:-1:-1;;;;;;;;;3942:400:5:o;1457:1155:2:-;1836:1;1146:13:1;:11;:13::i;:::-;1134:8;:25;1130:109;;1204:8;1214:13;:11;:13::i;1130:109::-;1248:25;1260:12;:8;1271:1;1260:12;:::i;1248:25::-;1849:38:2::1;1859:27;1849:9;:38::i;:::-;1898:39;1919:17;1898:20;:39::i;:::-;1952:31;::::0;-1:-1:-1;;;;;1952:31:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;1952:31:2;;;::::1;1994:25;2008:10;1994:13;:25::i;:::-;2034:24;::::0;1725:25:60;;;-1:-1:-1;;;;;;;;;;;2034:24:2;1713:2:60;1698:18;2034:24:2::1;;;;;;;2069:49;2095:22;2069:25;:49::i;:::-;2133:41;::::0;-1:-1:-1;;;;;2133:41:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;2133:41:2;;;::::1;2185:39;2206:17;2185:20;:39::i;:::-;2239:31;::::0;-1:-1:-1;;;;;2239:31:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;2239:31:2;;;::::1;2281:54;2310:24;2281:28;:54::i;:::-;2350:46;::::0;-1:-1:-1;;;;;2350:46:2;::::1;::::0;::::1;::::0;;;::::1;2407:136;2486:23;2511:22;2407:65;:136::i;:::-;2554:51;2590:14;2554:35;:51::i;:::-;-1:-1:-1::0;;;;;;;;;;;1354:8:1;1364;;1343:30;;;;;;;;:::i;:::-;;;;;;;;1457:1155:2;;;;;;;;;;:::o;6914:133::-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;6982:22:2::1;6996:7;6982:13;:22::i;:::-;7019:21;::::0;1725:25:60;;;-1:-1:-1;;;;;;;;;;;7019:21:2;1713:2:60;1698:18;7019:21:2::1;1579:177:60::0;4647:112:2;4699:7;4725:27;:25;:27::i;5680:107::-;5733:7;5759:21;:19;:21::i;8317:108:4:-;8361:26;;:::i;:::-;8406:12;:10;:12::i;4579:227:5:-;4668:4;4684:94;4693:10;4705:8;4761:16;4715:43;4737:10;4749:8;4715:21;:43::i;:::-;:62;;;;:::i;:::-;4684:8;:94::i;2769:145::-;2835:7;2861:46;2880:26;2899:6;2880:18;:26::i;:::-;2861:18;:46::i;:::-;2854:53;2769:145;-1:-1:-1;;2769:145:5:o;6935:142:4:-;6996:7;7022:30;:28;:30::i;:::-;:48;;;7015:55;;6935:142;:::o;7296:351::-;7349:7;7368:30;7401:12;:10;:12::i;:::-;7368:45;;7423:20;7446:18;7460:3;7446:13;:18::i;:::-;7423:41;;7481:159;7548:3;:18;;;-1:-1:-1;;;;;7509:57:4;:30;:28;:30::i;:::-;:36;:57;;;;:::i;:::-;7611:18;;7596:33;;-1:-1:-1;;;;;7596:33:4;:12;:33;:::i;:::-;7580:50;;:12;:50;:::i;:::-;7481:14;:159::i;:::-;7474:166;;;;7296:351;:::o;4510:102:2:-;4557:7;4583:22;:20;:22::i;3827:381::-;3866:1;1146:13:1;:11;:13::i;:::-;1134:8;:25;1130:109;;1204:8;1214:13;:11;:13::i;1130:109::-;1248:25;1260:12;:8;1271:1;1260:12;:::i;1248:25::-;3997:22:2::1;1477:8:3;4022:22:2;:20;:22::i;:::-;:37;;;;:::i;:::-;3997:62;;4069:61;4115:14;4090:22;:20;:22::i;:::-;:39;;;;:::i;4069:61::-;4140;4186:14;4161:22;:20;:22::i;4140:61::-;3869:339;-1:-1:-1::0;;;;;;;;;;;1354:8:1;1364;;1343:30;;;;;;;;:::i;3272:119:3:-;3331:7;3357:27;:25;:27::i;8990:155:4:-;9061:7;9110:12;:10;:12::i;:::-;:27;9099:38;;-1:-1:-1;;;;;9099:38:4;:8;:38;:::i;:::-;9087:51;;:8;:51;:::i;7082:158:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7156:35:2::1;7177:13;7156:20;:35::i;:::-;7206:27;::::0;-1:-1:-1;;;;;7206:27:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;7206:27:2;;;::::1;7082:158:::0;:::o;8504:176::-;8572:34;:32;:34::i;5822:263::-;5937:33;6010:26;:24;:26::i;:::-;-1:-1:-1;;;;;5993:66:2;;6060:17;;5993:85;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;5993:85:2;;;;;;;;;;;;:::i;4937:110::-;4988:7;5014:26;:24;:26::i;827:104:0:-;870:7;896:28;:26;:28::i;2617:109:5:-;2675:7;2701:18;2712:6;2701:10;:18::i;8468:479:4:-;8518:21;8541:18;8561:16;8589:30;8622:12;:10;:12::i;:::-;8589:45;;8644:20;8667:18;8681:3;8667:13;:18::i;:::-;8742;;8644:41;;-1:-1:-1;8727:33:4;;-1:-1:-1;;;;;8727:33:4;8644:41;8727:33;:::i;:::-;8711:50;;:12;:50;:::i;:::-;8695:66;;8820:3;:18;;;-1:-1:-1;;;;;8784:54:4;8800:3;:17;;;-1:-1:-1;;;;;8784:33:4;:13;:33;;;;:::i;:::-;:54;;;;:::i;:::-;8771:67;;8939:1;8918:3;:18;;;-1:-1:-1;;;;;8859:77:4;8898:3;:17;;;-1:-1:-1;;;;;8859:56:4;8876:3;:18;;;-1:-1:-1;;;;;8860:34:4;:13;:34;;;;:::i;:::-;8859:56;;;;:::i;:::-;:77;;;;:::i;:::-;:81;;;;:::i;:::-;8848:92;;8579:368;;8468:479;;;:::o;7902:211:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7983:41:2::1;8011:12;7983:27;:41::i;:::-;8034:29;8050:12;8034:15;:29::i;:::-;8078:28;8093:12;8078:28;;;;;;:::i;9774:348:4:-:0;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;9867:21:::1;;;::::0;;::::1;::::0;::::1;9878:9:::0;9867:21:::1;:::i;:::-;:10;:21::i;:::-;-1:-1:-1::0;;;;;;;;;;;9924:24:4::1;;::::0;::::1;:9:::0;:24:::1;:::i;:::-;9962:23;::::0;;;::::1;::::0;::::1;;:::i;:::-;9999:24;::::0;;;::::1;::::0;::::1;;:::i;:::-;10037:21;::::0;;;::::1;::::0;::::1;;:::i;:::-;10072:33;::::0;;;::::1;::::0;::::1;;:::i;:::-;9903:212;;;;;;;;;;:::i;3137:167:5:-:0;3229:7;3255:42;3274:22;3255:18;:42::i;9574:157:4:-;4283:16;:14;:16::i;:::-;-1:-1:-1;;;;;4269:30:4;:10;-1:-1:-1;;;;;4269:30:4;;4265:102;;4345:10;4322:34;;-1:-1:-1;;;4322:34:4;;;;;;;;:::i;4265:102::-;9651:33:::1;9669:14;9651:17;:33::i;:::-;9699:25;::::0;-1:-1:-1;;;;;9699:25:4;::::1;::::0;::::1;::::0;;;::::1;9574:157:::0;:::o;6796:96::-;6840:7;6866:19;:17;:19::i;5082:105:2:-;5131:13;5163:17;:15;:17::i;3449:123:3:-;3510:7;3536:29;:27;:29::i;7992:127:4:-;8050:7;8076:30;:28;:30::i;:::-;:36;;7992:127;-1:-1:-1;7992:127:4:o;6532:347:2:-;6671:28;6739:26;:24;:26::i;:::-;-1:-1:-1;;;;;6722:64:2;;6800:17;;6819:19;;6840:4;6846:16;6722:150;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6722:150:2;;;;;;;;;;;;:::i;:::-;6715:157;6532:347;-1:-1:-1;;;;;6532:347:2:o;8148:118::-;8203:7;8229:30;:28;:30::i;9188:132:4:-;9238:38;;:::i;:::-;9295:18;:16;:18::i;8162:112::-;8214:7;8240:27;8254:12;:10;:12::i;:::-;8240:13;:27::i;4849:231:5:-;4940:4;4956:96;4965:10;4977:8;5033:18;4987:43;5009:10;5021:8;4987:21;:43::i;:::-;:64;;;;:::i;3538:361::-;3723:4;3626:10;3638:3;1267:23;1279:5;1286:3;1267:11;:23::i;:::-;3661:6;1473:11;1469:63:::1;;1507:14;;-1:-1:-1::0;;;1507:14:5::1;;;;;;;;;;;1469:63;3686:10:::2;3698:6;1830;1809:18;1820:6;1809:10;:18::i;:::-;:27;1805:80;;;1859:15;;-1:-1:-1::0;;;1859:15:5::2;;;;;;;;;;;1805:80;-1:-1:-1::0;;;;;3747:17:5;::::3;3743:99;;3808:10;3828:1;3787:44;;-1:-1:-1::0;;;3787:44:5::3;;;;;;;;;:::i;3743:99::-;3858:34;3868:10;3880:3;3885:6;3858:9;:34::i;:::-;3851:41:::0;3538:361;-1:-1:-1;;;;;;;;3538:361:5:o;1040:151:6:-;1115:39;1143:10;1115:27;:39::i;:::-;1164:20;1173:10;1164:8;:20::i;5457:188:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;5606:32:2::1;5633:4;5606:26;:32::i;4373:102::-:0;4420:7;4446:22;:20;:22::i;972:118:0:-;1022:7;1048:35;:33;:35::i;919:73:6:-;965:20;974:10;965:8;:20::i;8715:173:2:-;8789:25;:23;:25::i;3347:148:5:-;3423:7;3449:39;3471:6;3479:8;3449:21;:39::i;5222:200:2:-;5306:58;;:::i;:::-;5387:28;:26;:28::i;8301:168::-;8368:27;:25;:27::i;10993:9597:4:-;11177:19;:17;:19::i;:::-;-1:-1:-1;;;;;11163:33:4;:10;-1:-1:-1;;;;;11163:33:4;;11159:105;;11242:10;11219:34;;-1:-1:-1;;;11219:34:4;;;;;;;;:::i;11159:105::-;11274:30;11307:12;:10;:12::i;:::-;11274:45;-1:-1:-1;11435:33:4;11274:45;11454:13;;11435;:33::i;:::-;11430:99;;11491:27;;-1:-1:-1;;;11491:27:4;;11504:13;;11491:27;;;1725:25:60;1698:18;;11491:27:4;1579:177:60;11430:99:4;11539:48;;:::i;:::-;11612:68;11683:30;:28;:30::i;:::-;11759:40;;;;11728:28;;;:71;;;11612:101;;-1:-1:-1;11900:31:4;;;;:62;11896:249;;;12051:4;:28;;;12081:7;:31;;;11989:141;;-1:-1:-1;;;11989:141:4;;;;;;;;;:::i;11896:249::-;12310:28;;;;12276:62;;:31;;;;:62;:::i;:::-;12248:25;;;:90;12385:41;;;;12353:29;;;:73;;;12528:32;;;;:64;12524:254;;;12682:4;:29;;;12713:7;:32;;;12619:144;;-1:-1:-1;;;12619:144:4;;;;;;;;;:::i;12524:254::-;12916:29;:27;:29::i;:::-;12890:23;;;;;;;;:::i;:::-;:55;;;:137;;;-1:-1:-1;12995:32:4;;;;;;12969:23;;;;;;;;:::i;:::-;:58;;;12890:137;12869:368;;;13116:23;;;;;;;;:::i;:::-;13141:29;:27;:29::i;:::-;13172:32;;;;13067:155;;-1:-1:-1;;;13067:155:4;;13172:32;23049:15:60;;;13067:155:4;;;23031:34:60;23081:18;;;23074:34;;;;13172:32:4;;;;23124:18:60;;;23117:43;22975:18;;13067:155:4;22802:364:60;12869:368:4;13400:29;;;;13365:64;;:32;;;;:64;:::i;:::-;13336:26;;;:93;13502:22;;13478:62;;13497:3;;13526:13;;13478:18;:62::i;:::-;13444:31;;;:96;-1:-1:-1;13706:15:4;:13;:15::i;:::-;13672:49;;13871:26;;;;13843:25;;;;13672:31;;13843:54;;;:::i;:::-;:58;13839:240;;;14001:67;14014:4;:26;;;14042:4;:25;;;14001:12;:67::i;:::-;14224:63;;:::i;:::-;14323:13;;14302:34;;14383:25;;;;;14350:30;;;:58;14462:32;;;;;14422:37;;;:72;14547:31;;;;;14508:36;;;:70;14632:32;;;;;14592:37;;;:72;14709:23;;;;;;;;:::i;:::-;14678:54;;:28;;;:54;14790:36;;;;;;;;:::i;:::-;14746:80;;:41;;;:80;14879:31;;;;;;;;:::i;:::-;14840:70;;:36;;;:70;14924:42;14840:12;14924:28;:42::i;:::-;14089:888;14987:41;15031:18;:16;:18::i;:::-;14987:62;;15152:19;15174:82;15187:2;15191:4;:31;;;15224:4;:31;;;15174:12;:82::i;:::-;15152:104;;15394:15;:13;:15::i;:::-;15359:32;;;:50;;;15924:31;;-1:-1:-1;15884:2086:4;;16091:31;;:45;;16125:11;;16091:45;:::i;:::-;16056:4;:32;;;:80;16052:387;;;16224:31;;16277:32;;;;16331:31;;;;16384:22;;16163:261;;-1:-1:-1;;;16163:261:4;;;;16224:31;16277:32;16331:31;16384:22;16163:261;;;:::i;16052:387::-;16573:31;;16538:32;;;;:66;;16573:31;16538:66;:::i;:::-;16517:10;;;;;:87;;;;16808:10;:18;16794:32;;:11;:32;:::i;:::-;16759;;;:67;15884:2086;;;17041:19;17063:49;17076:2;17080:4;:31;;;17063:12;:49::i;:::-;17041:71;;17292:60;17307:11;17320:4;:31;;;17292:14;:60::i;:::-;17258:31;;:94;;;;:::i;:::-;17203:4;:32;;;:149;17182:485;;;17453:31;;17506:32;;;;;17560:31;;;;17613:21;;;;17392:260;;-1:-1:-1;;;17392:260:4;;;;17453:31;17560;17613:21;17392:260;;;:::i;17182:485::-;17926:32;;;;17892:31;;:66;;17926:32;17892:66;:::i;:::-;17877:82;;:11;:82;:::i;:::-;17826:32;;;:133;-1:-1:-1;15884:2086:4;18077:32;;;;:36;18073:437;;18227:45;18239:4;:32;;;18227:11;:45::i;:::-;18201:10;;;;;:23;;;;:71;;;;18345:10;:23;;;;18323:45;;18345:23;;:10;18323:45;;18345:23;;18323:45;:::i;:::-;;;-1:-1:-1;18476:10:4;;;;:23;;;18440:32;;;:59;;;;18476:23;;18440:59;:::i;:::-;;;-1:-1:-1;18073:437:4;18620:32;;;;:36;18616:439;;18824:64;18855:4;:32;;;18824:30;:64::i;:::-;18757:10;;;;;:48;;;;:131;;;;18996:10;:48;;-1:-1:-1;18960:32:4;;:84;;;;18996:48;;18960:84;:::i;:::-;;;-1:-1:-1;18616:439:4;19197:32;;;;:36;19193:407;;19343:52;19362:4;:32;;;19343:18;:52::i;:::-;19310:10;;;;:30;;:85;19193:407;19691:10;;;;:18;:22;19687:84;;19741:10;;;;:18;19729:31;;:11;:31::i;:::-;19781:254;19844:32;;;;19890:40;;;;19844:7;19890:40;:::i;:::-;19781:254;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19944:36:4;;-1:-1:-1;;;19944:36:4;;;;;;;:::i;:::-;19994:31;;;;;;;;:::i;:::-;19781:49;:254::i;:::-;20147:32;:30;:32::i;:::-;20281:28;:26;:28::i;:::-;20395:56;20419:4;:31;;;20395:23;:56::i;:::-;20533:50;20563:7;20572:4;:10;;;20533:50;;;;;;;:::i;:::-;;;;;;;;11089:9501;;;;10993:9597;:::o;2957:137:5:-;3034:7;3060:27;3079:7;3060:18;:27::i;7690:126:4:-;7751:4;7774:35;7788:12;:10;:12::i;:::-;7802:6;7774:13;:35::i;7275:158:2:-;447:28:0;:26;:28::i;:::-;-1:-1:-1;;;;;433:42:0;:10;-1:-1:-1;;;;;433:42:0;;429:114;;521:10;498:34;;-1:-1:-1;;;498:34:0;;;;;;;;:::i;429:114::-;7349:35:2::1;7370:13;7349:20;:35::i;:::-;7399:27;::::0;-1:-1:-1;;;;;7399:27:2;::::1;::::0;-1:-1:-1;;;;;;;;;;;7399:27:2;;;::::1;7275:158:::0;:::o;2938:109:3:-;2992:7;3018:22;:20;:22::i;627:123:58:-;678:65;308:45;352:1;-1:-1:-1;;;;;;;;;;;308:45:58;:::i;:::-;733:9;3024:24:27;;2865:199;;3024:24;;2865:199::o;268:136:32:-;306:7;332:65;206:54;259:1;-1:-1:-1;;;;;;;;;;;206:54:32;:::i;:::-;1622:16:27;;1442:212;15959:239:2;16074:65;16094:22;:20;:22::i;:::-;16118:20;16074:65;;;;;;;:::i;:::-;;;;;;;;16149:42;16170:20;16149;:42::i;10145:741::-;10250:20;10273:48;10301:10;10313:7;10273:27;:48::i;:::-;10250:71;;10331:22;10369;:20;:22::i;:::-;10331:61;;10420:10;-1:-1:-1;;;;;10406:24:2;:10;-1:-1:-1;;;;;10406:24:2;;10402:478;;;10446:65;;-1:-1:-1;;;10446:65:2;;-1:-1:-1;;;;;10446:21:2;;;;;:65;;10468:10;;350:3:21;;10446:65:2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10402:478;;;10589:65;;-1:-1:-1;;;10589:65:2;;-1:-1:-1;;;;;10589:21:2;;;;;:65;;10611:10;;350:3:21;;10589:65:2;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10719:30:2;;-1:-1:-1;;;10719:30:2;;-1:-1:-1;;;;;10719:18:2;;;-1:-1:-1;10719:18:2;;-1:-1:-1;10719:30:2;;10738:10;;10719:30;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10715:94;;;10783:10;10776:18;;-1:-1:-1;;;10776:18:2;;;;;;;;:::i;10715:94::-;10822:47;10832:10;10844;10856:12;10822:9;:47::i;:::-;;10402:478;10240:646;;10145:741;;;:::o;407:103:20:-;451:7;477:26;:24;:26::i;829:185:39:-;880:38;908:9;880:27;:38::i;:::-;928:79;428:57;484:1;-1:-1:-1;;;;;;;;;;;428:57:39;:::i;426:125:58:-;464:7;490:54;308:45;352:1;-1:-1:-1;;;;;;;;;;;308:45:58;:::i;840:186:50:-;891:38;919:9;891:27;:38::i;:::-;939:80;433:58;490:1;-1:-1:-1;;;;;;;;;;;433:58:50;:::i;15539:278:2:-;15659:32;15686:4;15659:26;:32::i;:::-;15736:33;;15771:38;;;;15706:104;;;;;;15736:33;;-1:-1:-1;;;;;27392:15:60;;;27374:34;;27444:15;;27439:2;27424:18;;27417:43;27324:2;27309:18;;27162:304;5137:1616:4;5433:324;5457:290;;;;;;;;5511:15;-1:-1:-1;;;;;5457:290:4;;;;;5559:14;-1:-1:-1;;;;;5457:290:4;;;;;5607:15;-1:-1:-1;;;;;5457:290:4;;;;;5653:12;-1:-1:-1;;;;;5457:290:4;;;;;5708:24;-1:-1:-1;;;;;5457:290:4;;;;5433:10;:324::i;:::-;-1:-1:-1;;;;;;;;;;;5780:15:4;5797:14;5813:15;5830:12;5844:24;5772:97;;;;;;;;;;:::i;:::-;;;;;;;;5879:203;5909:163;;;;;;;;5980:20;5909:163;;;;6038:19;5909:163;;;5879:16;:203::i;:::-;-1:-1:-1;;;;;;;;;;;6107:20:4;6129:19;6097:52;;;;;;;:::i;:::-;;;;;;;;6160:63;;:::i;:::-;6262:23;:21;:23::i;:::-;6233:53;;6329:29;:27;:29::i;:::-;6296:30;;;:62;6408:1;6368:37;;;:41;;;6419:36;;;:40;;;6469:37;;;:41;6558:22;:20;:22::i;:::-;6520:61;;:28;;;:61;6635:5;6591:41;;;:49;;;6650:36;;;:44;6704:42;6520:12;6704:28;:42::i;:::-;5423:1330;5137:1616;;;;;;;:::o;5941:282:5:-;6028:35;6056:6;6028:27;:35::i;:::-;6073:37;6101:8;6073:27;:37::i;:::-;6120:47;6142:6;6150:8;6160:6;6120:21;:47::i;:::-;6199:8;-1:-1:-1;;;;;6182:34:5;6191:6;-1:-1:-1;;;;;6182:34:5;;6209:6;6182:34;;;;1725:25:60;;1713:2;1698:18;;1579:177;6182:34:5;;;;;;;;5941:282;;;:::o;594:140:50:-;632:7;658:69;433:58;490:1;-1:-1:-1;;;;;;;;;;;433:58:50;:::i;621:117:20:-;672:7;698:33;:31;:33::i;1536:171:0:-;1590:35;1618:6;1590:27;:35::i;:::-;1635:34;1662:6;1635:26;:34::i;:::-;1684:16;;-1:-1:-1;;;;;1684:16:0;;;;;;;;1536:171;:::o;1840:168::-;1908:48;1942:13;1908:33;:48::i;:::-;1971:30;;-1:-1:-1;;;;;1971:30:0;;;;;;;;1840:168;:::o;548:135:31:-;586:7;612:64;401:54;454:1;-1:-1:-1;;;;;;;;;;;401:54:31;:::i;6676:298:5:-;6757:4;6773:61;6792:5;6827:6;6799:25;6818:5;6799:18;:25::i;:::-;:34;;;;:::i;:::-;6773:18;:61::i;:::-;6844:57;6863:3;6894:6;6868:23;6887:3;6868:18;:23::i;:::-;:32;;;;:::i;6844:57::-;6933:3;-1:-1:-1;;;;;6917:28:5;6926:5;-1:-1:-1;;;;;6917:28:5;-1:-1:-1;;;;;;;;;;;6938:6:5;6917:28;;;;1725:25:60;;1713:2;1698:18;;1579:177;6917:28:5;;;;;;;;-1:-1:-1;6963:4:5;6676:298;;;;;:::o;789:318:45:-;827:51;;421:62;482:1;-1:-1:-1;;;;;;;;;;;421:62:45;:::i;941:183:43:-;992:38;1020:9;992:27;:38::i;:::-;1040:77;476:59;534:1;-1:-1:-1;;;;;;;;;;;476:59:43;:::i;267:135:38:-;305:7;331:64;205:54;258:1;-1:-1:-1;;;;;;;;;;;205:54:38;:::i;1295:112:26:-;1355:7;1387:2;1382;:7;:17;;1397:2;1382:17;;;-1:-1:-1;1392:2:26;1295:112;-1:-1:-1;1295:112:26:o;11275:285:2:-;11380:25;11407;11476:30;:28;:30::i;:::-;-1:-1:-1;;;;;11455:80:2;;11536:16;11455:98;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;11455:98:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;11455:98:2;;;;;;;;;;;;:::i;:::-;11448:105;;;;11275:285;;;:::o;594:140:54:-;632:7;658:69;432:59;490:1;-1:-1:-1;;;;;;;;;;;432:59:54;:::i;5565:1394:3:-;1289:2;5709:10;:17;:38;5705:100;;5770:24;;-1:-1:-1;;;5770:24:3;;;;;;;;;;;5705:100;1389:2;5819:10;:17;:37;5815:99;;5879:24;;-1:-1:-1;;;5879:24:3;;;;;;;;;;;5815:99;1477:8;5923:13;5986:14;5994:6;1477:8;5986:14;:::i;:::-;5962:38;;6011:18;6032:44;6052:10;6072:1;6064:10;;6039:36;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;6039:36:3;;;;;;;;;;6032:44;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6011:65;;6086:21;6110:220;6160:41;6167:33;6182:10;6194:1;6197:2;6167:14;:33::i;:::-;6160:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6219:87;6239:53;6254:10;6266:2;6270:21;6266:2;1389;6270:21;:::i;:::-;6239:14;:53::i;:::-;6226:79;;;;;6302:1;;6226:79;;;:::i;:::-;;;;-1:-1:-1;;6226:79:3;;;;;;;;;;6219:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6130:190;;;;;;30900:19:60;;;;30935:12;;30928:28;30972:12;;6130:190:3;;;-1:-1:-1;;6130:190:3;;;;;;;;;;6110:220;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6086:244;;6341:23;6367:236;6417:56;6437:10;6449:22;6424:48;;;;;;;;30900:19:60;;;30944:2;30935:12;;30928:28;30981:2;30972:12;;30743:247;6424:48:3;;;;-1:-1:-1;;6424:48:3;;;;;;;;;;6417:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6491:88;6519:42;6547:13;6519:27;:42::i;:::-;6498:80;;;;;;30900:19:60;;;;30935:12;;30928:28;;;30972:12;;6498:80:3;;;-1:-1:-1;;6498:80:3;;;;;;;;;;6491:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6387:206;;;;;;30900:19:60;;;;30935:12;;30928:28;30972:12;;6387:206:3;;;-1:-1:-1;;6387:206:3;;;;;;;;;;6367:236;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6341:262;-1:-1:-1;6614:21:3;6638:29;6662:5;6638:21;:29;:::i;:::-;6614:53;;6695:28;:26;:28::i;:::-;-1:-1:-1;;;;;6678:54:3;;6740:5;6760:10;6789:22;6772:40;;;;;;31124:19:60;;31168:2;31159:12;;30995:182;6772:40:3;;;;;;;;;;;;;6814:10;6826:15;6678:173;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6890:13;6865:21;:38;6861:92;;6926:16;;-1:-1:-1;;;6926:16:3;;;;;;;;;;;6861:92;5695:1264;;;;;;5565:1394;;;:::o;16739:258:2:-;16864:74;16893:22;:20;:22::i;:::-;16917:20;16864:74;;;;;;;:::i;:::-;;;;;;;;16948:42;16969:20;16948;:42::i;576:143:42:-;614:7;640:72;406:61;466:1;-1:-1:-1;;;;;;;;;;;406:61:42;:::i;831:141::-;882:83;406:61;466:1;-1:-1:-1;;;;;;;;;;;406:61:42;:::i;14583:828:2:-;14674:7;14693:64;14760:30;:28;:30::i;:::-;14827:28;;;;14693:97;;-1:-1:-1;14827:28:2;;14800:24;14899:29;:27;:29::i;:::-;14865:63;;14961:23;14942:16;:42;14938:467;;;1477:8:3;15147:42:2;15173:16;15147:23;:42;:::i;:::-;15146:90;;;;:::i;:::-;15106:21;:19;:21::i;:::-;15065:22;:20;:22::i;:::-;15040;:20;:22::i;:::-;15007:12;:30;;;:55;;;;:::i;:::-;:80;;;;:::i;:::-;:120;;;;:::i;:::-;:229;;;;:::i;:::-;15000:236;;;;;14583:828;:::o;14938:467::-;15373:21;:19;:21::i;:::-;15348:22;:20;:22::i;:::-;15323;:20;:22::i;:::-;15290:12;:30;;;:55;;;;:::i;586:139:39:-;624:7;650:68;428:57;484:1;-1:-1:-1;;;;;;;;;;;428:57:39;:::i;9236:201:2:-;9375:7;9405:25;:23;:25::i;1360:291:51:-;1436:12;285:50;334:1;-1:-1:-1;;;;;;;;;;;285:50:51;:::i;:::-;1618:26;;;;;;;;;;;;;;;;;-1:-1:-1;1360:291:51:o;6334:92:5:-;6381:7;6407:12;:10;:12::i;492:128:44:-;530:7;556:57;366:47;412:1;-1:-1:-1;;;;;;;;;;;366:47:44;:::i;9592:316:2:-;9674:22;9712;:20;:22::i;:::-;9749:25;;-1:-1:-1;;;9749:25:2;;9674:61;;-1:-1:-1;;;;;;9749:18:2;;;;;:25;;9768:5;;9749:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9745:76;;;9804:5;9797:13;;-1:-1:-1;;;9797:13:2;;;;;;;;:::i;9745:76::-;9834:23;;-1:-1:-1;;;9834:23:2;;-1:-1:-1;;;;;9834:18:2;;;;;:23;;9853:3;;9834:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9830:72;;;9887:3;9880:11;;-1:-1:-1;;;9880:11:2;;;;;;;;:::i;9830:72::-;9664:244;9592:316;;:::o;9023:118:5:-;9082:7;9108:26;9127:6;9108:18;:26::i;5291:412::-;5366:24;5393:40;5415:5;5422:10;5393:21;:40::i;:::-;5366:67;;5466:6;5447:16;:25;5443:123;;;5495:60;;-1:-1:-1;;;5495:60:5;;-1:-1:-1;;;;;32087:15:60;;5495:60:5;;;32069:34:60;5518:10:5;32119:18:60;;;32112:43;32171:18;;;32164:34;;;32214:18;;;32207:34;;;32003:19;;5495:60:5;31800:447:60;5443:123:5;-1:-1:-1;;5579:16:5;:37;5575:122;;5632:54;5641:5;5648:10;5660:25;5679:6;5660:16;:25;:::i;779:181:37:-;830:38;858:9;830:27;:38::i;:::-;878:75;401:54;454:1;-1:-1:-1;;;;;;;;;;;401:54:37;:::i;702:168:44:-;753:32;775:9;753:21;:32::i;:::-;795:68;366:47;412:1;-1:-1:-1;;;;;;;;;;;366:47:44;:::i;779:181:31:-;830:38;858:9;830:27;:38::i;:::-;878:75;401:54;454:1;-1:-1:-1;;;;;;;;;;;401:54:31;:::i;884:190:48:-;935:38;963:9;935:27;:38::i;:::-;983:84;453:62;514:1;-1:-1:-1;;;;;;;;;;;453:62:48;:::i;2494:386:3:-;2634:51;2661:23;2634:26;:51::i;:::-;2700:50;;-1:-1:-1;;;;;2700:50:3;;;;;;;;2761:49;2787:22;2761:25;:49::i;:::-;2825:48;;1725:25:60;;;2825:48:3;;1713:2:60;1698:18;2825:48:3;;;;;;;2494:386;;:::o;668:137:43:-;706:7;732:66;476:59;534:1;-1:-1:-1;;;;;;;;;;;476:59:43;:::i;265:135:33:-;303:7;329:64;204:53;256:1;-1:-1:-1;;;;;;;;;;;204:53:33;:::i;1241:266:34:-;1279:19;;:::i;:::-;1310:12;294:44;337:1;-1:-1:-1;;;;;;;;;;;294:44:34;:::i;:::-;1486:14;;;;;;;;;;-1:-1:-1;;;;;1486:14:34;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;;;;-1:-1:-1;;;1486:14:34;;;;;;;;;;;;;;;;;;;1241:266;-1:-1:-1;;1241:266:34:o;833:318:56:-;904:7;;322:55;376:1;-1:-1:-1;;;;;;;;;;;322:55:56;:::i;:::-;-1:-1:-1;;;;;1118:15:56;;;314:64;1118:15;;;;;;;;;;;:26;;;;;;;;;-1:-1:-1;;1118:26:56;;;833:318::o;689:285:53:-;741:7;;299:52;350:1;-1:-1:-1;;;;;;;;;;;299:52:53;:::i;:::-;-1:-1:-1;;;;;952:15:53;;;291:61;952:15;;;;;;;;-1:-1:-1;;952:15:53;;;;;689:285::o;7176:272:5:-;7244:7;7263:25;7291:12;:10;:12::i;:::-;7263:40;-1:-1:-1;7318:22:5;7314:61;;-1:-1:-1;7363:1:5;;7176:272;-1:-1:-1;;7176:272:5:o;7314:61::-;7424:17;7404:15;:13;:15::i;:::-;7394:25;;:7;:25;:::i;:::-;7392:49;;;;:::i;20756:193:4:-;20835:7;20924:4;:18;;;-1:-1:-1;;;;;20861:81:4;20901:4;:19;;;-1:-1:-1;;;;;20862:58:4;20881:4;:16;;;-1:-1:-1;;;;;20863:34:4;:15;:34;;;;:::i;:::-;20862:58;;;;:::i;:::-;20861:81;;;;:::i;1560:112:26:-;1620:7;1652:2;1647;:7;:17;;1662:2;1647:17;;548:135:37;586:7;612:64;401:54;454:1;-1:-1:-1;;;;;;;;;;;401:54:37;:::i;543:172:25:-;619:21;;615:94;;668:30;;-1:-1:-1;;;668:30:25;;;;;;;;;;;914:264:47;971:12;276:49;324:1;-1:-1:-1;;;;;;;;;;;276:49:47;:::i;:::-;1152:19;;268:58;;-1:-1:-1;268:58:47;;1152:19;;268:58;;1152:19;;;;;:::i;:::-;;961:217;;914:264;:::o;1633:267:34:-;1697:12;294:44;337:1;-1:-1:-1;;;;;;;;;;;294:44:34;:::i;:::-;1873:20;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1873:20:34;;;-1:-1:-1;;;;;;1873:20:34;;;;;;;-1:-1:-1;;;1873:20:34;;;;;;;;;;;-1:-1:-1;;;;;1873:20:34;-1:-1:-1;;;1873:20:34;;;;;;;-1:-1:-1;;;;;1873:20:34;;-1:-1:-1;;;1873:20:34;;;;;;;;;;;;;;;-1:-1:-1;1873:20:34;;;;;-1:-1:-1;;;;;;1873:20:34;;;;;;;;;-1:-1:-1;1633:267:34:o;7672:272:5:-;7741:7;7760:25;7788:12;:10;:12::i;:::-;7760:40;-1:-1:-1;7815:22:5;7811:61;;-1:-1:-1;7860:1:5;;7672:272;-1:-1:-1;;7672:272:5:o;7811:61::-;7922:15;:13;:15::i;:::-;7890:28;7901:17;7890:8;:28;:::i;746:178:49:-;797:38;825:9;797:27;:38::i;:::-;845:72;386:51;436:1;-1:-1:-1;;;;;;;;;;;386:51:49;:::i;524:132::-;562:7;588:61;386:51;436:1;-1:-1:-1;;;;;;;;;;;386:51:49;:::i;548:265:47:-;586:13;611:12;276:49;324:1;-1:-1:-1;;;;;;;;;;;276:49:47;:::i;:::-;792:14;;268:58;;-1:-1:-1;268:58:47;;;;792:14;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;548:265;:::o;626:144:48:-;664:7;690:73;453:62;514:1;-1:-1:-1;;;;;;;;;;;453:62:48;:::i;967:278:51:-;1005:25;;:::i;:::-;1042:12;285:50;334:1;-1:-1:-1;;;;;;;;;;;285:50:51;:::i;:::-;1224:14;;;;;;;;;;;;;;;;;;;;;;;967:278;-1:-1:-1;;967:278:51:o;292:163:25:-;-1:-1:-1;;;;;363:22:25;;359:90;;408:30;;-1:-1:-1;;;408:30:25;;;;;;;;;;;944:299:40;982:35;;:::i;:::-;1029:12;398:60;457:1;-1:-1:-1;;;;;;;;;;;398:60:40;:::i;:::-;1222:14;;;;;;;;;;;-1:-1:-1;;;;;1222:14:40;;;;;-1:-1:-1;;;1222:14:40;;;;;;;;;944:299;-1:-1:-1;;944:299:40:o;21132:311:4:-;21227:4;21296;:28;;;-1:-1:-1;;;;;21287:37:4;:6;:37;;;;:::i;:::-;21264:19;21278:4;21264:13;:19::i;:::-;:60;;:125;;;;;21353:30;:28;:30::i;:::-;:36;21344:45;;21264:125;:162;;;;-1:-1:-1;21402:19:4;;21393:28;;-1:-1:-1;;;;;21393:28:4;:6;:28;:::i;:::-;:33;;21132:311;-1:-1:-1;;;21132:311:4:o;22903:253::-;23050:7;23130:4;:18;;;23108:4;:19;;;:40;;;;:::i;:::-;-1:-1:-1;;;;;23080:69:4;23081:22;23093:10;23081:9;:22;:::i;:::-;23080:69;;;;:::i;:::-;23073:76;22903:253;-1:-1:-1;;;;22903:253:4:o;17245:885:2:-;17373:21;17348:22;17432:36;17452:16;17432:17;:36;:::i;:::-;17404:64;;17490:34;:32;:34::i;:::-;-1:-1:-1;;;;;17478:55:2;;17534:17;17478:74;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;17478:74:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17562:24;17613:14;17589:21;:38;;;;:::i;:::-;17562:65;-1:-1:-1;17661:36:2;17681:16;17661:17;:36;:::i;:::-;17641:16;:56;17637:176;;17747:36;17767:16;17747:17;:36;:::i;:::-;17785:16;17720:82;;-1:-1:-1;;;17720:82:2;;;;;;;;;:::i;17637:176::-;17826:21;;17822:116;;17863:64;17909:17;17884:22;:20;:22::i;17863:64::-;17951:20;;17947:112;;17987:61;18031:16;18007:21;:19;:21::i;:::-;:40;;;;:::i;:::-;17987:19;:61::i;:::-;18073:50;18087:17;18106:16;18073:50;;;;;;;:::i;1239:316:45:-;1333:12;421:62;482:1;-1:-1:-1;;;;;;;;;;;421:62:45;:::i;:::-;1529:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1529:19:45;-1:-1:-1;;;;1529:19:45;;;-1:-1:-1;;;1529:19:45;-1:-1:-1;;1529:19:45;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1239:316:45:o;21806:298:4:-;21964:7;22054:42;1050:8;273:6:22;22054:42:4;:::i;:::-;22011:23;;22037:12;;21995:39;;:13;:39;:::i;:::-;:54;;;;:::i;:::-;21994:103;;;;:::i;22383:247::-;22519:7;273:6:22;22566:3:4;:22;;;22550:13;:38;;;;:::i;11858:536:2:-;11920:7;11939:22;11964:27;:25;:27::i;:::-;12057:59;;-1:-1:-1;;;12057:59:2;;;;;1725:25:60;;;11939:52:2;;-1:-1:-1;12026:21:2;;-1:-1:-1;;;;;12057:53:2;;;;;1698:18:60;;12057:59:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12126:23;12176:14;12152:21;:38;;;;:::i;:::-;12126:64;-1:-1:-1;12204:19:2;;12200:112;;12239:62;12285:15;12260:22;:20;:22::i;12239:62::-;12326:29;;1725:25:60;;;12326:29:2;;1713:2:60;1698:18;12326:29:2;;;;;;;;12372:15;11858:536;-1:-1:-1;;;;11858:536:2:o;18256:550::-;18337:7;18381:21;18429:26;:24;:26::i;:::-;-1:-1:-1;;;;;18412:61:2;;18474:4;18412:67;;;;;;;;;;;;;1725:25:60;;1713:2;1698:18;;1579:177;18412:67:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18489:29;18545:14;18521:21;:38;;;;:::i;:::-;18489:70;-1:-1:-1;18573:25:2;;18569:124;;18614:68;18660:21;18635:22;:20;:22::i;18614:68::-;18707:54;;1725:25:60;;;18707:54:2;;1713:2:60;1698:18;18707:54:2;;;;;;;18778:21;18256:550;-1:-1:-1;;;18256:550:2:o;12644:658::-;12713:7;12732:20;12755:25;:23;:25::i;:::-;12732:48;-1:-1:-1;;;;;;12794:26:2;;12790:65;;-1:-1:-1;12843:1:2;;12644:658;-1:-1:-1;;12644:658:2:o;12790:65::-;12920:62;;-1:-1:-1;;;12920:62:2;;;;;1725:25:60;;;12889:21:2;;-1:-1:-1;;;;;12920:56:2;;;;;1698:18:60;;12920:62:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12992:30;13049:14;13025:21;:38;;;;:::i;:::-;12992:71;-1:-1:-1;13077:26:2;;13073:126;;13119:69;13165:22;13140;:20;:22::i;13119:69::-;13213:43;;1725:25:60;;;13213:43:2;;1713:2:60;1698:18;13213:43:2;1579:177:60;13498:925:2;13564:22;13589:14;:12;:14::i;:::-;13564:39;-1:-1:-1;13617:19:2;13613:75;;13659:18;;-1:-1:-1;;;13659:18:2;;;;;;;;;;;13613:75;13697:23;13723:15;:13;:15::i;:::-;13697:41;;13748:17;13768:15;:13;:15::i;:::-;13748:35;-1:-1:-1;13793:17:2;13748:35;13813:24;13823:14;13813:7;:24;:::i;:::-;:36;;;;:::i;:::-;13793:56;-1:-1:-1;13859:19:2;13936;13946:9;13936:7;:19;:::i;:::-;13882:49;273:6:22;13882:15:2;:49;:::i;:::-;13881:75;;;;:::i;:::-;13859:97;-1:-1:-1;13966:20:2;13989:16;;:48;;14013:23;14025:11;14013:9;:23;:::i;:::-;13989:48;;;14008:1;13989:48;13966:71;-1:-1:-1;14052:16:2;;14048:369;;14084:17;14104:22;:20;:22::i;:::-;14084:42;;14140:39;14155:9;14166:12;14140:14;:39::i;:::-;14193:22;14218:14;:12;:14::i;:::-;14193:39;-1:-1:-1;14246:23:2;14272:25;14290:7;14272:15;:25;:::i;:::-;14246:51;;14330:9;-1:-1:-1;;;;;14316:90:2;;14341:15;14358:14;14374:15;14391:14;14316:90;;;;;;;;;:::i;:::-;;;;;;;;14070:347;;;14048:369;13554:869;;;;;;13498:925;:::o;21114:3283::-;21405:30;:28;:30::i;:::-;-1:-1:-1;;;;;21384:81:2;;21479:23;21504:29;:27;:29::i;:::-;21384:159;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21558:31;21554:68;;;21605:7;;21554:68;21632:19;21654:14;:12;:14::i;:::-;21632:36;-1:-1:-1;21682:15:2;;21678:2713;;21713:32;21748:21;:19;:21::i;:::-;21713:56;;21783:33;21819:22;:20;:22::i;:::-;21783:58;;21855:32;21906:82;21942:26;:24;:26::i;:::-;-1:-1:-1;;;;;21925:60:2;;:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;21906:82::-;21855:133;-1:-1:-1;21855:133:2;22233:42;22260:15;22233:24;:42;:::i;:::-;:69;22229:2152;;;22475:34;:67;;;;;22541:1;22513:25;:29;22475:67;22471:606;;;22566:25;22594:158;22634:25;22706:24;22661:42;22688:15;22661:24;:42;:::i;:::-;:69;;;;:::i;:::-;22594:14;:158::i;:::-;22566:186;-1:-1:-1;22778:21:2;;22774:285;;22827:45;22855:17;22827:45;;:::i;:::-;;;22898;22918:24;22898:19;:45::i;:::-;22969:67;22990:45;23018:17;22990:25;:45;:::i;22969:67::-;22544:533;22471:606;23095:23;23142:30;:28;:30::i;:::-;23095:78;;23193:34;23229:32;23285:2;-1:-1:-1;;;;;23285:35:2;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23192:130;;;;;;23644:25;1477:8:3;23721:26:2;23694:24;:53;:163;;23856:1;23694:163;;;23775:53;23802:26;23775:24;:53;:::i;:::-;23672:218;;;;:::i;:::-;23644:246;-1:-1:-1;23978:24:2;23644:246;23913:42;23940:15;23913:24;:42;:::i;:::-;:62;;;;:::i;:::-;:89;23909:458;;;24026:28;24057:192;24171:17;24126:42;24153:15;24126:24;:42;:::i;:::-;:62;;;;:::i;:::-;24098:91;;:24;:91;:::i;:::-;1477:8:3;24057:15:2;:192::i;:::-;24026:223;;24272:2;-1:-1:-1;;;;;24272:23:2;;24296:20;24318:29;:27;:29::i;:::-;24272:76;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24004:363;23909:458;22304:2077;;;;21699:2692;;;21374:3023;21114:3283;;;;:::o;18905:1896::-;18975:31;19026:26;:24;:26::i;:::-;18975:78;;19063:30;19096:15;:13;:15::i;:::-;19063:48;;19121:19;19143:14;:12;:14::i;:::-;19121:36;;19197:1;19172:22;:26;:45;;;;;19216:1;19202:11;:15;19172:45;19168:1627;;;19336:27;19366:14;-1:-1:-1;;;;;19366:30:2;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19336:62;-1:-1:-1;19336:62:2;19412:35;19526:47;19336:62;19526:18;:47::i;:::-;19483:90;;19587:32;19622:21;:19;:21::i;:::-;19587:56;;19801:24;19766:32;:59;19762:257;;;19880:24;19845:59;;19952:52;19971:32;19952:18;:52::i;:::-;19922:82;;19762:257;20038:135;;;8710:25:60;;;8766:2;8751:18;;8744:34;;;8794:18;;;8787:34;;;20038:135:2;;8698:2:60;8683:18;20038:135:2;;;;;;;20192:36;;20188:597;;20310:80;20330:59;20357:32;20330:24;:59;:::i;20310:80::-;20512:68;20535:14;20552:27;20512:14;:68::i;:::-;20671:99;;-1:-1:-1;;;20671:99:2;;;;;1725:25:60;;;-1:-1:-1;;;;;20671:29:2;;;;;20708:32;;1698:18:60;;20671:99:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24493:452;24559:32;24594:21;:19;:21::i;:::-;24559:56;-1:-1:-1;24777:28:2;;24773:166;;24821:71;24867:24;24842:22;:20;:22::i;24821:71::-;24906:22;24926:1;24906:19;:22::i;25391:1941::-;25469:30;25502:15;:13;:15::i;:::-;25469:48;;25527:31;25561:22;:20;:22::i;:::-;25527:56;;25593:62;25658:28;:26;:28::i;:::-;26487:32;;25593:93;;-1:-1:-1;26416:40:2;;26459:235;;-1:-1:-1;;;;;26459:235:2;273:6:22;26584:48:2;26609:23;26584:22;:48;:::i;:::-;26542:3;:37;;;-1:-1:-1;;;;;26534:46:2;:99;;;;:::i;:::-;26533:151;;;;:::i;26459:235::-;26416:278;-1:-1:-1;26801:35:2;26851:94;26913:6;26867:42;26902:7;26416:278;26867:42;:::i;:::-;26866:53;;;;:::i;:::-;26921:23;26851:14;:94::i;:::-;26801:144;-1:-1:-1;1477:8:3;27032:42:2;1477:8:3;26801:144:2;27032:42;:::i;:::-;27031:59;;;;:::i;:::-;27001:89;-1:-1:-1;27105:31:2;;27101:225;;27152:74;27198:27;27173:22;:20;:22::i;:::-;:52;;;;:::i;27152:74::-;27240:75;27261:53;27287:27;27261:23;:53;:::i;410:132:32:-;460:75;206:54;259:1;-1:-1:-1;;;;;;;;;;;206:54:32;:::i;8329:515:5:-;8415:20;8447:28;8496:21;8478:15;:13;:15::i;:::-;:39;;;;:::i;:::-;8447:70;-1:-1:-1;8532:25:5;8528:310;;8588:21;8573:36;;8623:45;8638:6;8646:21;8623:14;:45::i;:::-;8528:310;;;8757:20;8739:14;:12;:14::i;:::-;8715:38;;:21;:38;:::i;:::-;8714:63;;;;:::i;:::-;8699:78;;8791:36;8806:6;8814:12;8791:14;:36::i;:::-;8437:407;8329:515;;;;:::o;581:139:55:-;619:7;645:68;422:58;479:1;-1:-1:-1;;;;;;;;;;;422:58:55;:::i;1372:298:40:-;1451:12;398:60;457:1;-1:-1:-1;;;;;;;;;;;398:60:40;:::i;:::-;1644:19;;;;;;;-1:-1:-1;;;;;1644:19:40;;;-1:-1:-1;;;1644:19:40;;;;;;;;;;-1:-1:-1;1372:298:40:o;622:138:46:-;660:7;686:67;468:55;522:1;476:42;468:55;:::i;735:144:36:-;773:7;799:73;537:61;597:1;545:48;537:61;:::i;665:136:35:-;703:7;729:65;490:54;543:1;498:41;490:54;:::i;1393:319:56:-;1479:12;322:55;376:1;-1:-1:-1;;;;;;;;;;;322:55:56;:::i;:::-;-1:-1:-1;;;;;1667:15:56;;;314:64;1667:15;;;;;;;;;;;:26;;;;;;;;;-1:-1:-1;1667:26:56;;;:38;1393:319::o;601:147:57:-;639:7;665:76;419:65;483:1;-1:-1:-1;;;;;;;;;;;419:65:57;:::i;821:93:20:-;875:32;900:6;875:24;:32::i;1020:121::-;1088:46;1120:13;1088:31;:46::i;1148:286:53:-;1215:12;299:52;350:1;-1:-1:-1;;;;;;;;;;;299:52:53;:::i;:::-;-1:-1:-1;;;;;1400:15:53;;;291:61;1400:15;;;;;;;;-1:-1:-1;1400:15:53;;;;:27;1148:286::o;572:2856:23:-;664:12;731:7;716;726:2;716:12;:22;712:83;;;765:15;;-1:-1:-1;;;765:15:23;;;;;;;;;;;712:83;834:16;843:7;834:6;:16;:::i;:::-;818:6;:13;:32;814:88;;;873:18;;-1:-1:-1;;;873:18:23;;;;;;;;;;;814:88;912:22;1031:15;;1059:1931;;;;3131:4;3125:11;3112:24;;3317:1;3306:9;3299:20;3365:4;3354:9;3350:20;3344:4;3337:34;1024:2361;;1059:1931;1241:4;1235:11;1222:24;;1900:2;1891:7;1887:16;2282:9;2275:17;2269:4;2265:28;2253:9;2242;2238:25;2234:60;2330:7;2326:2;2322:16;2582:6;2568:9;2561:17;2555:4;2551:28;2539:9;2531:6;2527:22;2523:57;2519:70;2356:389;2615:3;2611:2;2608:11;2356:389;;;2733:9;;2722:21;;2656:4;2648:13;;;;2688;2356:389;;;-1:-1:-1;;2763:26:23;;;2971:2;2954:11;-1:-1:-1;;2950:25:23;2944:4;2937:39;-1:-1:-1;1024:2361:23;-1:-1:-1;3412:9:23;572:2856;-1:-1:-1;;;;572:2856:23:o;299:838:26:-;955:15;;;;467:4;1007:16;;;876:15;;;;928:16;;797:15;;;;849:16;;718:15;;;;770:16;;639:15;;;;691:16;;560:15;;;;612:16;;495:1;481:15;;;533:16;;;;517:11;;;;;516:34;596:11;;595:34;675:11;;674:34;754:11;;753:34;833:11;;832:34;912:11;;911:34;991:11;;;990:34;1034:15;;;;1067:14;;1060:22;;;;:::i;:::-;-1:-1:-1;1123:6:26;1111:19;;299:838;-1:-1:-1;299:838:26:o;610:142:41:-;648:7;674:71;443:60;502:1;-1:-1:-1;;;;;;;;;;;443:60:41;:::i;408:131:38:-;458:74;205:54;258:1;-1:-1:-1;;;;;;;;;;;205:54:38;:::i;450:124:52:-;488:7;514:53;323:44;366:1;-1:-1:-1;;;;;;;;;;;323:44:52;:::i;796:161:25:-;273:6:22;857:4:25;:38;853:98;;;918:22;;-1:-1:-1;;;918:22:25;;;;;;;;;;;862:188:41;913:38;941:9;913:27;:38::i;:::-;961:82;443:60;502:1;-1:-1:-1;;;;;;;;;;;443:60:41;:::i;1134:235:54:-;1189:23;1185:88;;1235:27;;-1:-1:-1;;;1235:27:54;;;;;;;;;;;1185:88;1282:80;432:59;490:1;-1:-1:-1;;;;;;;;;;;432:59:54;:::i;16375:201:2:-;16457:62;16476:21;:19;:21::i;:::-;16499:19;16457:62;;;;;;;:::i;:::-;;;;;;;;16529:40;16549:19;16529;:40::i;9363:244:5:-;9438:38;9469:6;9454:12;:10;:12::i;:::-;:21;;;;:::i;:::-;9438:15;:38::i;:::-;9486:63;9505:6;9542;9513:26;9532:6;9513:18;:26::i;9486:63::-;9564:36;;1725:25:60;;;-1:-1:-1;;;;;9564:36:5;;;9581:1;;-1:-1:-1;;;;;;;;;;;9564:36:5;1713:2:60;1698:18;9564:36:5;;;;;;;;9363:244;;:::o;1809:127:26:-;1870:7;;1909;1914:2;1909;:7;:::i;:::-;:11;:19;;1927:1;1909:19;;;1923:1;1909:19;1896:33;;1897:7;1902:2;1897;:7;:::i;:::-;1896:33;;;;:::i;9822:244:5:-;9897:38;9928:6;9913:12;:10;:12::i;:::-;:21;;;;:::i;9897:38::-;9945:63;9964:6;10001;9972:26;9991:6;9972:18;:26::i;9945:63::-;10023:36;;1725:25:60;;;10048:1:5;;-1:-1:-1;;;;;10023:36:5;;;-1:-1:-1;;;;;;;;;;;10023:36:5;1713:2:60;1698:18;10023:36:5;1579:177:60;824:185:55;875:38;903:9;875:27;:38::i;:::-;923:79;422:58;479:1;-1:-1:-1;;;;;;;;;;;422:58:55;:::i;868:145:57:-;919:87;419:65;483:1;-1:-1:-1;;;;;;;;;;;419:65:57;:::i;406:131:33:-;456:74;204:53;256:1;-1:-1:-1;;;;;;;;;;;204:53:33;:::i;10204:146:5:-;10272:26;10283:14;10272:10;:26::i;:::-;10313:30;;1725:25:60;;;10313:30:5;;1713:2:60;1698:18;10313:30:5;1579:177:60;660:122:52;711:64;323:44;366:1;-1:-1:-1;;;;;;;;;;;323:44:52;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:173:60;82:20;;-1:-1:-1;;;;;131:31:60;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;383:171::-;450:20;;-1:-1:-1;;;;;499:30:60;;489:41;;479:69;;544:1;541;534:12;559:173;627:20;;-1:-1:-1;;;;;676:31:60;;666:42;;656:70;;722:1;719;712:12;737:837;872:6;880;888;896;904;912;920;928;936;944;997:3;985:9;976:7;972:23;968:33;965:53;;;1014:1;1011;1004:12;965:53;1037:29;1056:9;1037:29;:::i;:::-;1027:39;;1085:37;1118:2;1107:9;1103:18;1085:37;:::i;:::-;1075:47;;1141:37;1174:2;1163:9;1159:18;1141:37;:::i;:::-;1131:47;;1197:37;1230:2;1219:9;1215:18;1197:37;:::i;:::-;1187:47;;1253:38;1286:3;1275:9;1271:19;1253:38;:::i;:::-;1243:48;;1310:38;1343:3;1332:9;1328:19;1310:38;:::i;:::-;1300:48;;1395:3;1384:9;1380:19;1367:33;1357:43;;1447:3;1436:9;1432:19;1419:33;1409:43;;1471:39;1505:3;1494:9;1490:19;1471:39;:::i;:::-;1461:49;;1529:39;1563:3;1552:9;1548:19;1529:39;:::i;:::-;1519:49;;737:837;;;;;;;;;;;;;:::o;1761:258::-;1833:1;1843:113;1857:6;1854:1;1851:13;1843:113;;;1933:11;;;1927:18;1914:11;;;1907:39;1879:2;1872:10;1843:113;;;1974:6;1971:1;1968:13;1965:48;;;-1:-1:-1;;2009:1:60;1991:16;;1984:27;1761:258::o;2024:::-;2066:3;2104:5;2098:12;2131:6;2126:3;2119:19;2147:63;2203:6;2196:4;2191:3;2187:14;2180:4;2173:5;2169:16;2147:63;:::i;:::-;2264:2;2243:15;-1:-1:-1;;2239:29:60;2230:39;;;;2271:4;2226:50;;2024:258;-1:-1:-1;;2024:258:60:o;2287:220::-;2436:2;2425:9;2418:21;2399:4;2456:45;2497:2;2486:9;2482:18;2474:6;2456:45;:::i;2512:254::-;2580:6;2588;2641:2;2629:9;2620:7;2616:23;2612:32;2609:52;;;2657:1;2654;2647:12;2609:52;2680:29;2699:9;2680:29;:::i;:::-;2670:39;2756:2;2741:18;;;;2728:32;;-1:-1:-1;;;2512:254:60:o;3059:::-;3127:6;3135;3188:2;3176:9;3167:7;3163:23;3159:32;3156:52;;;3204:1;3201;3194:12;3156:52;3240:9;3227:23;3217:33;;3269:38;3303:2;3292:9;3288:18;3269:38;:::i;:::-;3259:48;;3059:254;;;;;:::o;3614:180::-;3673:6;3726:2;3714:9;3705:7;3701:23;3697:32;3694:52;;;3742:1;3739;3732:12;3694:52;-1:-1:-1;3765:23:60;;3614:180;-1:-1:-1;3614:180:60:o;3799:203::-;-1:-1:-1;;;;;3963:32:60;;;;3945:51;;3933:2;3918:18;;3799:203::o;4007:204::-;4104:6;4157:2;4145:9;4136:7;4132:23;4128:32;4125:52;;;4173:1;4170;4163:12;4984:328;5061:6;5069;5077;5130:2;5118:9;5109:7;5105:23;5101:32;5098:52;;;5146:1;5143;5136:12;5098:52;5169:29;5188:9;5169:29;:::i;:::-;5159:39;;5217:38;5251:2;5240:9;5236:18;5217:38;:::i;:::-;5207:48;;5302:2;5291:9;5287:18;5274:32;5264:42;;4984:328;;;;;:::o;5317:772::-;5448:6;5456;5464;5472;5480;5488;5496;5504;5512;5565:3;5553:9;5544:7;5540:23;5536:33;5533:53;;;5582:1;5579;5572:12;5533:53;5605:29;5624:9;5605:29;:::i;:::-;5595:39;;5653:38;5687:2;5676:9;5672:18;5653:38;:::i;:::-;5643:48;;5738:2;5727:9;5723:18;5710:32;5700:42;;5761:38;5795:2;5784:9;5780:18;5761:38;:::i;:::-;5751:48;;5818:39;5852:3;5841:9;5837:19;5818:39;:::i;:::-;5808:49;;5876:39;5910:3;5899:9;5895:19;5876:39;:::i;:::-;5866:49;;5934:39;5968:3;5957:9;5953:19;5934:39;:::i;:::-;5924:49;;5992:39;6026:3;6015:9;6011:19;5992:39;:::i;:::-;5982:49;;6078:3;6067:9;6063:19;6050:33;6040:43;;5317:772;;;;;;;;;;;:::o;7049:366::-;7111:8;7121:6;7175:3;7168:4;7160:6;7156:17;7152:27;7142:55;;7193:1;7190;7183:12;7142:55;-1:-1:-1;7216:20:60;;-1:-1:-1;;;;;7248:30:60;;7245:50;;;7291:1;7288;7281:12;7245:50;7328:4;7320:6;7316:17;7304:29;;7388:3;7381:4;7371:6;7368:1;7364:14;7356:6;7352:27;7348:38;7345:47;7342:67;;;7405:1;7402;7395:12;7342:67;7049:366;;;;;:::o;7420:435::-;7505:6;7513;7566:2;7554:9;7545:7;7541:23;7537:32;7534:52;;;7582:1;7579;7572:12;7534:52;7609:23;;-1:-1:-1;;;;;7644:30:60;;7641:50;;;7687:1;7684;7677:12;7641:50;7726:69;7787:7;7778:6;7767:9;7763:22;7726:69;:::i;:::-;7814:8;;7700:95;;-1:-1:-1;7420:435:60;-1:-1:-1;;;;7420:435:60:o;7860:643::-;8027:2;8079:21;;;8149:13;;8052:18;;;8171:22;;;7998:4;;8027:2;8250:15;;;;8224:2;8209:18;;;7998:4;8293:184;8307:6;8304:1;8301:13;8293:184;;;8382:13;;8379:1;8368:28;8356:41;;8452:15;;;;8417:12;;;;8329:1;8322:9;8293:184;;;-1:-1:-1;8494:3:60;;7860:643;-1:-1:-1;;;;;;7860:643:60:o;8832:127::-;8893:10;8888:3;8884:20;8881:1;8874:31;8924:4;8921:1;8914:15;8948:4;8945:1;8938:15;8964:251;9036:2;9030:9;;;9066:15;;-1:-1:-1;;;;;9096:34:60;;9132:22;;;9093:62;9090:88;;;9158:18;;:::i;:::-;9194:2;9187:22;8964:251;:::o;9220:275::-;9291:2;9285:9;9356:2;9337:13;;-1:-1:-1;;9333:27:60;9321:40;;-1:-1:-1;;;;;9376:34:60;;9412:22;;;9373:62;9370:88;;;9438:18;;:::i;:::-;9474:2;9467:22;9220:275;;-1:-1:-1;9220:275:60:o;9500:187::-;9549:4;-1:-1:-1;;;;;9571:30:60;;9568:56;;;9604:18;;:::i;:::-;-1:-1:-1;9670:2:60;9649:15;-1:-1:-1;;9645:29:60;9676:4;9641:40;;9500:187::o;9692:673::-;9761:6;9814:2;9802:9;9793:7;9789:23;9785:32;9782:52;;;9830:1;9827;9820:12;9782:52;9857:23;;-1:-1:-1;;;;;9892:30:60;;9889:50;;;9935:1;9932;9925:12;9889:50;9958:22;;10011:4;10003:13;;9999:27;-1:-1:-1;9989:55:60;;10040:1;10037;10030:12;9989:55;10076:2;10063:16;10101:49;10117:32;10146:2;10117:32;:::i;:::-;10101:49;:::i;:::-;10173:2;10166:5;10159:17;10213:7;10208:2;10203;10199;10195:11;10191:20;10188:33;10185:53;;;10234:1;10231;10224:12;10185:53;10289:2;10284;10280;10276:11;10271:2;10264:5;10260:14;10247:45;10333:1;10312:14;;;10328:2;10308:23;10301:34;;;;10316:5;9692:673;-1:-1:-1;;;;9692:673:60:o;10370:199::-;10461:6;10514:3;10502:9;10493:7;10489:23;10485:33;10482:53;;;10531:1;10528;10521:12;10574:769;10694:6;10702;10710;10718;10771:2;10759:9;10750:7;10746:23;10742:32;10739:52;;;10787:1;10784;10777:12;10739:52;10814:23;;-1:-1:-1;;;;;10886:14:60;;;10883:34;;;10913:1;10910;10903:12;10883:34;10952:69;11013:7;11004:6;10993:9;10989:22;10952:69;:::i;:::-;11040:8;;-1:-1:-1;10926:95:60;-1:-1:-1;11128:2:60;11113:18;;11100:32;;-1:-1:-1;11144:16:60;;;11141:36;;;11173:1;11170;11163:12;11141:36;;11212:71;11275:7;11264:8;11253:9;11249:24;11212:71;:::i;:::-;10574:769;;;;-1:-1:-1;11302:8:60;-1:-1:-1;;;;10574:769:60:o;11348:639::-;11515:2;11567:21;;;11637:13;;11540:18;;;11659:22;;;11486:4;;11515:2;11738:15;;;;11712:2;11697:18;;;11486:4;11781:180;11795:6;11792:1;11789:13;11781:180;;;11860:13;;11875:4;11856:24;11844:37;;11936:15;;;;11901:12;;;;11817:1;11810:9;11781:180;;12316:376;12421:6;12474:2;12462:9;12453:7;12449:23;12445:32;12442:52;;;12490:1;12487;12480:12;12442:52;12516:22;;:::i;:::-;12561:29;12580:9;12561:29;:::i;:::-;12554:5;12547:44;12623:38;12657:2;12646:9;12642:18;12623:38;:::i;:::-;12618:2;12607:14;;12600:62;12611:5;12316:376;-1:-1:-1;;;12316:376:60:o;12697:260::-;12765:6;12773;12826:2;12814:9;12805:7;12801:23;12797:32;12794:52;;;12842:1;12839;12832:12;12794:52;12865:29;12884:9;12865:29;:::i;:::-;12855:39;;12913:38;12947:2;12936:9;12932:18;12913:38;:::i;13362:400::-;13461:6;13514:2;13502:9;13493:7;13489:23;13485:32;13482:52;;;13530:1;13527;13520:12;13482:52;13557:23;;-1:-1:-1;;;;;13592:30:60;;13589:50;;;13635:1;13632;13625:12;13589:50;13658:22;;13714:3;13696:16;;;13692:26;13689:46;;;13731:1;13728;13721:12;13767:127;13828:10;13823:3;13819:20;13816:1;13809:31;13859:4;13856:1;13849:15;13883:4;13880:1;13873:15;13899:128;13939:3;13970:1;13966:6;13963:1;13960:13;13957:39;;;13976:18;;:::i;:::-;-1:-1:-1;14012:9:60;;13899:128::o;14032:248::-;14206:25;;;14262:2;14247:18;;14240:34;14194:2;14179:18;;14032:248::o;14285:459::-;14470:6;14459:9;14452:25;14513:2;14508;14497:9;14493:18;14486:30;14552:6;14547:2;14536:9;14532:18;14525:34;14609:6;14601;14596:2;14585:9;14581:18;14568:48;14665:1;14636:22;;;14660:2;14632:31;;;14625:42;;;;14728:2;14707:15;;;-1:-1:-1;;14703:29:60;14688:45;14684:54;;14285:459;-1:-1:-1;;14285:459:60:o;14749:274::-;-1:-1:-1;;;;;14941:32:60;;;;14923:51;;15005:2;14990:18;;14983:34;14911:2;14896:18;;14749:274::o;15307:121::-;15392:10;15385:5;15381:22;15374:5;15371:33;15361:61;;15418:1;15415;15408:12;15433:249;15502:6;15555:2;15543:9;15534:7;15530:23;15526:32;15523:52;;;15571:1;15568;15561:12;15523:52;15603:9;15597:16;15622:30;15646:5;15622:30;:::i;15687:127::-;15748:10;15743:3;15739:20;15736:1;15729:31;15779:4;15776:1;15769:15;15803:4;15800:1;15793:15;15819:120;15859:1;15885;15875:35;;15890:18;;:::i;:::-;-1:-1:-1;15924:9:60;;15819:120::o;15944:127::-;16005:10;16000:3;15996:20;15993:1;15986:31;16036:4;16033:1;16026:15;16060:4;16057:1;16050:15;16076:168;16116:7;16182:1;16178;16174:6;16170:14;16167:1;16164:21;16159:1;16152:9;16145:17;16141:45;16138:71;;;16189:18;;:::i;:::-;-1:-1:-1;16229:9:60;;16076:168::o;16249:125::-;16289:4;16317:1;16314;16311:8;16308:34;;;16322:18;;:::i;:::-;-1:-1:-1;16359:9:60;;16249:125::o;16379:354::-;16474:6;16527:2;16515:9;16506:7;16502:23;16498:32;16495:52;;;16543:1;16540;16533:12;16495:52;16569:22;;:::i;:::-;16627:9;16614:23;16607:5;16600:38;16698:2;16687:9;16683:18;16670:32;16665:2;16658:5;16654:14;16647:56;16722:5;16712:15;;;16379:354;;;;:::o;16738:304::-;-1:-1:-1;;;;;16968:15:60;;;16950:34;;17020:15;;17015:2;17000:18;;16993:43;16900:2;16885:18;;16738:304::o;17047:112::-;17079:1;17105;17095:35;;17110:18;;:::i;:::-;-1:-1:-1;17144:9:60;;17047:112::o;17164:132::-;17231:20;;17260:30;17231:20;17260:30;:::i;17301:511::-;17400:6;17395:3;17388:19;17370:3;17426:4;17455:2;17450:3;17446:12;17439:19;;17481:5;17504:1;17514:273;17528:6;17525:1;17522:13;17514:273;;;17605:6;17592:20;17625:32;17649:7;17625:32;:::i;:::-;17695:10;17682:24;17670:37;;17727:12;;;;17762:15;;;;17550:1;17543:9;17514:273;;;-1:-1:-1;17803:3:60;;17301:511;-1:-1:-1;;;;;17301:511:60:o;17817:285::-;18004:2;17993:9;17986:21;17967:4;18024:72;18092:2;18081:9;18077:18;18069:6;18061;18024:72;:::i;18107:181::-;18165:4;-1:-1:-1;;;;;18187:30:60;;18184:56;;;18220:18;;:::i;:::-;-1:-1:-1;18265:1:60;18261:14;18277:4;18257:25;;18107:181::o;18293:1050::-;18386:6;18417:2;18460;18448:9;18439:7;18435:23;18431:32;18428:52;;;18476:1;18473;18466:12;18428:52;18503:16;;-1:-1:-1;;;;;18531:30:60;;18528:50;;;18574:1;18571;18564:12;18528:50;18597:22;;18650:4;18642:13;;18638:27;-1:-1:-1;18628:55:60;;18679:1;18676;18669:12;18628:55;18708:2;18702:9;18731:58;18747:41;18785:2;18747:41;:::i;18731:58::-;18823:15;;;18905:1;18901:10;;;;18893:19;;18889:28;;;18854:12;;;;18929:19;;;18926:39;;;18961:1;18958;18951:12;18926:39;18985:11;;;;19005:308;19021:6;19016:3;19013:15;19005:308;;;19094:3;19088:10;19145:5;19142:1;19131:20;19124:5;19121:31;19111:129;;19194:1;19223:2;19219;19212:14;19111:129;19253:18;;19038:12;;;;19291;;;;19005:308;;;19332:5;18293:1050;-1:-1:-1;;;;;;;18293:1050:60:o;19348:736::-;19437:6;19490:3;19478:9;19469:7;19465:23;19461:33;19458:53;;;19507:1;19504;19497:12;19458:53;19540:2;19534:9;19582:3;19570:16;;-1:-1:-1;;;;;19601:34:60;;19637:22;;;19598:62;19595:88;;;19663:18;;:::i;:::-;19699:2;19692:22;19738:28;19756:9;19738:28;:::i;:::-;19730:6;19723:44;19800:37;19833:2;19822:9;19818:18;19800:37;:::i;:::-;19795:2;19787:6;19783:15;19776:62;19871:37;19904:2;19893:9;19889:18;19871:37;:::i;:::-;19866:2;19858:6;19854:15;19847:62;19942:37;19975:2;19964:9;19960:18;19942:37;:::i;:::-;19937:2;19929:6;19925:15;19918:62;20014:38;20047:3;20036:9;20032:19;20014:38;:::i;:::-;20008:3;19996:16;;19989:64;20000:6;19348:736;-1:-1:-1;;;19348:736:60:o;20089:184::-;20147:6;20200:2;20188:9;20179:7;20175:23;20171:32;20168:52;;;20216:1;20213;20206:12;20168:52;20239:28;20257:9;20239:28;:::i;20278:535::-;-1:-1:-1;;;;;20582:15:60;;;20564:34;;20634:15;;;20629:2;20614:18;;20607:43;20686:15;;;20545:2;20666:18;;20659:43;20738:15;;20733:2;20718:18;;20711:43;20791:15;;;20785:3;20770:19;;20763:44;20514:3;20499:19;;20278:535::o;20818:678::-;21139:3;21128:9;21121:22;21102:4;21166:73;21234:3;21223:9;21219:19;21211:6;21203;21166:73;:::i;:::-;21287:9;21279:6;21275:22;21270:2;21259:9;21255:18;21248:50;21315:60;21368:6;21360;21352;21315:60;:::i;:::-;21418:14;;21411:22;21406:2;21391:18;;21384:50;-1:-1:-1;;21482:6:60;21470:19;;;;21465:2;21450:18;;;21443:47;21307:68;20818:678;-1:-1:-1;;;;20818:678:60:o;21501:1046::-;21594:6;21625:2;21668;21656:9;21647:7;21643:23;21639:32;21636:52;;;21684:1;21681;21674:12;21636:52;21711:16;;-1:-1:-1;;;;;21739:30:60;;21736:50;;;21782:1;21779;21772:12;21736:50;21805:22;;21858:4;21850:13;;21846:27;-1:-1:-1;21836:55:60;;21887:1;21884;21877:12;21836:55;21916:2;21910:9;21939:58;21955:41;21993:2;21955:41;:::i;21939:58::-;22031:15;;;22113:1;22109:10;;;;22101:19;;22097:28;;;22062:12;;;;22137:19;;;22134:39;;;22169:1;22166;22159:12;22134:39;22193:11;;;;22213:304;22229:6;22224:3;22221:15;22213:304;;;22302:3;22296:10;22350:4;22343:5;22339:16;22332:5;22329:27;22319:125;;22398:1;22427:2;22423;22416:14;22319:125;22457:18;;22246:12;;;;22495;;;;22213:304;;22552:245;22610:6;22663:2;22651:9;22642:7;22638:23;22634:32;22631:52;;;22679:1;22676;22669:12;22631:52;22718:9;22705:23;22737:30;22761:5;22737:30;:::i;23171:118::-;23257:5;23250:13;23243:21;23236:5;23233:32;23223:60;;23279:1;23276;23269:12;23294:128;23359:20;;23388:28;23359:20;23388:28;:::i;23427:241::-;23483:6;23536:2;23524:9;23515:7;23511:23;23507:32;23504:52;;;23552:1;23549;23542:12;23504:52;23591:9;23578:23;23610:28;23632:5;23610:28;:::i;23673:391::-;23904:25;;;23960:2;23945:18;;23938:34;;;;24003:2;23988:18;;23981:34;24046:2;24031:18;;24024:34;23891:3;23876:19;;23673:391::o;24069:544::-;24161:4;24167:6;24227:11;24214:25;24321:2;24317:7;24306:8;24290:14;24286:29;24282:43;24262:18;24258:68;24248:96;;24340:1;24337;24330:12;24248:96;24367:33;;24419:20;;;-1:-1:-1;;;;;;24451:30:60;;24448:50;;;24494:1;24491;24484:12;24448:50;24527:4;24515:17;;-1:-1:-1;24578:1:60;24574:14;;;24558;24554:35;24544:46;;24541:66;;;24603:1;24600;24593:12;24618:522;24687:5;24694:6;24754:3;24741:17;24840:2;24836:7;24825:8;24809:14;24805:29;24801:43;24781:18;24777:68;24767:96;;24859:1;24856;24849:12;24767:96;24887:33;;24991:4;24978:18;;;-1:-1:-1;24939:21:60;;-1:-1:-1;;;;;;25008:30:60;;25005:50;;;25051:1;25048;25041:12;25005:50;25108:6;25105:1;25101:14;25085;25081:35;25071:8;25067:50;25064:70;;;25130:1;25127;25120:12;25435:1472;25770:3;25759:9;25752:22;25824:6;25811:20;25805:3;25794:9;25790:19;25783:49;25894:4;25886:6;25882:17;25869:31;25863:3;25852:9;25848:19;25841:60;25963:4;25955:6;25951:17;25938:31;25932:3;25921:9;25917:19;25910:60;25733:4;25989:3;26053:4;26045:6;26041:17;26028:31;26023:2;26012:9;26008:18;26001:59;26079:6;26146:4;26138:6;26134:17;26121:31;26116:2;26105:9;26101:18;26094:59;26182:35;26212:3;26204:6;26200:16;26182:35;:::i;:::-;3394:10;3383:22;26273:3;26258:19;;3371:35;26323:67;26385:3;26373:16;;26377:6;26323:67;:::i;:::-;26427:2;26421:3;26410:9;26406:19;26399:31;26453:87;26535:3;26524:9;26520:19;26506:12;26490:14;26453:87;:::i;:::-;26439:101;;;;26571:33;26599:3;26591:6;26587:16;26571:33;:::i;:::-;2841:13;2834:21;26660:3;26645:19;;2822:34;26696:32;26712:15;;;26696:32;:::i;:::-;2841:13;;2834:21;26784:3;26769:19;;2822:34;26674:54;-1:-1:-1;26806:6:60;-1:-1:-1;26821:80:60;;-1:-1:-1;26895:4:60;26880:20;;26872:6;25249:5;25243:12;25238:3;25231:25;25305:4;25298:5;25294:16;25288:23;25281:4;25276:3;25272:14;25265:47;25361:4;25354:5;25350:16;25344:23;25337:4;25332:3;25328:14;25321:47;25417:4;25410:5;25406:16;25400:23;25393:4;25388:3;25384:14;25377:47;;;25145:285;26912:245;26979:6;27032:2;27020:9;27011:7;27007:23;27003:32;27000:52;;;27048:1;27045;27038:12;27000:52;27080:9;27074:16;27099:28;27121:5;27099:28;:::i;27471:1387::-;27534:5;27587:3;27580:4;27572:6;27568:17;27564:27;27554:55;;27605:1;27602;27595:12;27554:55;27634:6;27628:13;27660:4;27684:58;27700:41;27738:2;27700:41;:::i;27684:58::-;27776:15;;;27862:1;27858:10;;;;27846:23;;27842:32;;;27807:12;;;;27886:15;;;27883:35;;;27914:1;27911;27904:12;27883:35;27950:2;27942:6;27938:15;27962:867;27978:6;27973:3;27970:15;27962:867;;;28051:10;;-1:-1:-1;;;;;28077:35:60;;28074:125;;;28153:1;28182:2;28178;28171:14;28074:125;28222:24;;28281:2;28273:11;;28269:21;-1:-1:-1;28259:119:60;;28332:1;28361:2;28357;28350:14;28259:119;28415:2;28411;28407:11;28401:18;28442:2;28472:49;28488:32;28517:2;28488:32;:::i;28472:49::-;28550:2;28541:7;28534:19;28594:3;28589:2;28584;28580;28576:11;28572:20;28569:29;28566:119;;;28639:1;28668:2;28664;28657:14;28566:119;28698:56;28751:2;28746;28737:7;28733:16;28728:2;28724;28720:11;28698:56;:::i;:::-;28767:20;;-1:-1:-1;;;28807:12:60;;;;27995;;27962:867;;;-1:-1:-1;28847:5:60;27471:1387;-1:-1:-1;;;;;;27471:1387:60:o;28863:628::-;29010:6;29018;29071:2;29059:9;29050:7;29046:23;29042:32;29039:52;;;29087:1;29084;29077:12;29039:52;29114:16;;-1:-1:-1;;;;;29179:14:60;;;29176:34;;;29206:1;29203;29196:12;29176:34;29229:70;29291:7;29282:6;29271:9;29267:22;29229:70;:::i;:::-;29219:80;;29345:2;29334:9;29330:18;29324:25;29308:41;;29374:2;29364:8;29361:16;29358:36;;;29390:1;29387;29380:12;29358:36;;29413:72;29477:7;29466:8;29455:9;29451:24;29413:72;:::i;:::-;29403:82;;;28863:628;;;;;:::o;29496:399::-;29653:3;29691:6;29685:13;29707:53;29753:6;29748:3;29741:4;29733:6;29729:17;29707:53;:::i;:::-;-1:-1:-1;;;;;;29821:37:60;;;;29782:16;;;;29807:52;;;29886:2;29875:14;;29496:399;-1:-1:-1;;29496:399:60:o;29900:274::-;30029:3;30067:6;30061:13;30083:53;30129:6;30124:3;30117:4;30109:6;30105:17;30083:53;:::i;:::-;30152:16;;;;;29900:274;-1:-1:-1;;29900:274:60:o;30179:184::-;30249:6;30302:2;30290:9;30281:7;30277:23;30273:32;30270:52;;;30318:1;30315;30308:12;30270:52;-1:-1:-1;30341:16:60;;30179:184;-1:-1:-1;30179:184:60:o;30368:370::-;30525:3;30563:6;30557:13;30579:53;30625:6;30620:3;30613:4;30605:6;30601:17;30579:53;:::i;:::-;30654:16;;;;30679:21;;;-1:-1:-1;30727:4:60;30716:16;;30368:370;-1:-1:-1;30368:370:60:o;31182:613::-;31449:3;31438:9;31431:22;31412:4;31476:46;31517:3;31506:9;31502:19;31494:6;31476:46;:::i;:::-;31570:9;31562:6;31558:22;31553:2;31542:9;31538:18;31531:50;31604:33;31630:6;31622;31604:33;:::i;:::-;31590:47;;31685:9;31677:6;31673:22;31668:2;31657:9;31653:18;31646:50;31713:33;31739:6;31731;31713:33;:::i;:::-;31705:41;;;31782:6;31777:2;31766:9;31762:18;31755:34;31182:613;;;;;;;:::o;32252:380::-;32331:1;32327:12;;;;32374;;;32395:61;;32449:4;32441:6;32437:17;32427:27;;32395:61;32502:2;32494:6;32491:14;32471:18;32468:38;32465:161;;;32548:10;32543:3;32539:20;32536:1;32529:31;32583:4;32580:1;32573:15;32611:4;32608:1;32601:15;32637:270;32676:7;-1:-1:-1;;;;;32746:10:60;;;32776;;;32809:11;;32802:19;32831:12;;;32823:21;;32798:47;32795:73;;;32848:18;;:::i;:::-;32888:13;;32637:270;-1:-1:-1;;;;32637:270:60:o;32912:720::-;33128:2;33140:21;;;33210:13;;33113:18;;;33232:22;;;33080:4;;33307;;33285:2;33270:18;;;33334:15;;;33080:4;33377:186;33391:6;33388:1;33385:13;33377:186;;;33456:13;;33471:10;33452:30;33440:43;;33503:12;;;;33538:15;;;;33413:1;33406:9;33377:186;;;-1:-1:-1;;;33599:18:60;;33592:34;;;;33580:3;32912:720;-1:-1:-1;;32912:720:60:o;33826:310::-;33904:6;33912;33965:2;33953:9;33944:7;33940:23;33936:32;33933:52;;;33981:1;33978;33971:12;33933:52;34013:9;34007:16;34032:30;34056:5;34032:30;:::i;:::-;34126:2;34111:18;;;;34105:25;34081:5;;34105:25;;-1:-1:-1;;;33826:310:60:o;34141:127::-;34202:10;34197:3;34193:20;34190:1;34183:31;34233:4;34230:1;34223:15;34257:4;34254:1;34247:15

Swarm Source

ipfs://e02de5da910f2e302ce88e1d383cfbca158bb52fff77f76d823f8ce65ed1a891

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

Liquid Collective is a secure liquid staking protocol designed to meet the needs of institutions, built and run by a collective of industry-leading Web3 teams and governed in a decentralized manner by a broad and dispersed community.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ 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.