Contract Address Details
contract

0xe557e46057bF120cB91472c66Ee7f3c743bd1419

Sponsored: 

One World Chain Mainnet Utility Token (OWCT) is now Listed on Uniswap

Overview

OWCT Balance

0 OWCT

OWCT Value

$

Token Holdings

Fetching tokens...

More Info

Private Name Tags

Last Balance Update

Blocks Validated

Sponsored

Contract name:
Consensus




Optimization enabled
true
Compiler version
v0.4.26+commit.4563c3fc




Optimization runs
200
EVM Version
default




Verified at
2024-06-20T02:13:32.203898Z

Contract source code

// File: contracts/interfaces/IBlockReward.sol

pragma solidity ^0.4.24;

interface IBlockReward {
    function onCycleEnd() external;
}

// File: contracts/interfaces/IVoting.sol

pragma solidity ^0.4.24;

interface IVoting {
    function onCycleEnd(address[] validators) external;
}

// File: contracts/abstracts/ValidatorSet.sol

pragma solidity ^0.4.24;

/**
 * @title Interface to be implemented by consensus contract
 * @author LiorRabin
 * @dev abstract contract
 */
contract ValidatorSet {
    /// Issue this log event to signal a desired change in validator set.
    /// This will not lead to a change in active validator set until finalizeChange is called.
    ///
    /// Only the last log event of any block can take effect.
    /// If a signal is issued while another is being finalized it may never take effect.
    ///
    /// parentHash here should be the parent block hash, or the signal will not be recognized.
    event InitiateChange(bytes32 indexed parentHash, address[] newSet);

    /// Get current validator set (last enacted or initial if no changes ever made)
    function getValidators() external view returns(address[]);

    /// Called when an initiated change reaches finality and is activated.
    /// Only valid when msg.sender == SYSTEM_ADDRESS (EIP96, 2**160 - 2)
    ///
    /// Also called when the contract is first enabled for consensus.
    /// In this case, the "change" finalized is the activation of the initial set.
    function finalizeChange() external;
}

// File: contracts/eternal-storage/EternalStorage.sol

pragma solidity ^0.4.24;


/**
 * @title EternalStorage
 * @author LiorRabin
 * @dev This contract holds all the necessary state variables to carry out the storage of any contract and to support the upgrade functionality.
 */
contract EternalStorage {
    // Version number of the current implementation
    uint256 internal version;

    // Address of the current implementation
    address internal implementation;

    // Storage mappings
    mapping(bytes32 => uint256) internal uintStorage;
    mapping(bytes32 => string) internal stringStorage;
    mapping(bytes32 => address) internal addressStorage;
    mapping(bytes32 => bytes) internal bytesStorage;
    mapping(bytes32 => bool) internal boolStorage;
    mapping(bytes32 => int256) internal intStorage;

    mapping(bytes32 => uint256[]) internal uintArrayStorage;
    mapping(bytes32 => string[]) internal stringArrayStorage;
    mapping(bytes32 => address[]) internal addressArrayStorage;
    mapping(bytes32 => bytes[]) internal bytesArrayStorage;
    mapping(bytes32 => bool[]) internal boolArrayStorage;
    mapping(bytes32 => int256[]) internal intArrayStorage;
    mapping(bytes32 => bytes32[]) internal bytes32ArrayStorage;

    function isInitialized() public view returns(bool) {
      return boolStorage[keccak256(abi.encodePacked("isInitialized"))];
    }

    function setInitialized(bool _status) internal {
      boolStorage[keccak256(abi.encodePacked("isInitialized"))] = _status;
    }
}

// File: contracts/eternal-storage/EternalStorageProxy.sol

pragma solidity ^0.4.24;

/**
 * @title EternalStorageProxy
 * @author LiorRabin
 * @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set.
 * Besides, it allows to upgrade the token's behaviour towards further implementations, and provides authorization control functionalities
 */
contract EternalStorageProxy is EternalStorage {
    /**
    * @dev This event will be emitted every time the implementation gets upgraded
    * @param version representing the version number of the upgraded implementation
    * @param implementation representing the address of the upgraded implementation
    */
    event Upgraded(uint256 version, address indexed implementation);

    /**
    * @dev This event will be emitted when ownership is renounces
    * @param previousOwner address which is renounced from ownership
    */
    event OwnershipRenounced(address indexed previousOwner);

    /**
    * @dev This event will be emitted when ownership is transferred
    * @param previousOwner address which represents the previous owner
    * @param newOwner address which represents the new owner
    */
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
    * @dev This modifier verifies that msg.sender is the ProxyStorage contract
    */
    modifier onlyProxyStorage() {
      require(msg.sender == getProxyStorage());
      _;
    }

    /**
    * @dev This modifier verifies that msg.sender is the owner of the contract
    */
    modifier onlyOwner() {
      require(msg.sender == getOwner());
      _;
    }

    /**
    * @dev Constructor
    * @param _proxyStorage address representing the ProxyStorage contract
    * @param _implementation address representing the implementation contract
    */
    constructor(address _proxyStorage, address _implementation) public {
      require(_implementation != address(0));
      if (_proxyStorage != address(0)) {
        _setProxyStorage(_proxyStorage);
      } else {
        _setProxyStorage(address(this));
      }
      _setImplementation(_implementation);
      _setOwner(msg.sender);
    }

    /**
    * @dev Fallback function allowing to perform a delegatecall to the given implementation.
    * This function will return whatever the implementation call returns
    */
    // solhint-disable no-complex-fallback, no-inline-assembly
    function() payable public {
      address _impl = getImplementation();
      require(_impl != address(0));

      assembly {
        // Copy msg.data. We take full control of memory in this inline assembly
        // block because it will not return to Solidity code. We overwrite the
        // Solidity scratch pad at memory position 0
        calldatacopy(0, 0, calldatasize)

        // Call the implementation.
        // out and outsize are 0 because we don't know the size yet
        let result := delegatecall(gas, _impl, 0, calldatasize, 0, 0)

        // Copy the returned data
        returndatacopy(0, 0, returndatasize)

        switch result
        // delegatecall returns 0 on error
        case 0 { revert(0, returndatasize) }
        default { return(0, returndatasize) }
      }
    }
    // solhint-enable no-complex-fallback, no-inline-assembly

    /**
     * @dev Allows ProxyStorage contract (only) to upgrade the current implementation.
     * @param _newImplementation representing the address of the new implementation to be set.
     */
    function upgradeTo(address _newImplementation) public onlyProxyStorage returns(bool) {
      if (_newImplementation == address(0)) return false;
      if (getImplementation() == _newImplementation) return false;
      uint256 _newVersion = getVersion() + 1;
      _setVersion(_newVersion);
      _setImplementation(_newImplementation);
      emit Upgraded(_newVersion, _newImplementation);
      return true;
    }

    /**
     * @dev Allows the current owner to relinquish ownership.
     */
    function renounceOwnership() public onlyOwner {
      emit OwnershipRenounced(getOwner());
      _setOwner(address(0));
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a _newOwner.
     * @param _newOwner The address to transfer ownership to.
     */
    function transferOwnership(address _newOwner) public onlyOwner {
      require(_newOwner != address(0));
      emit OwnershipTransferred(getOwner(), _newOwner);
      _setOwner(_newOwner);
    }

    function getOwner() public view returns(address) {
      return addressStorage[keccak256(abi.encodePacked("owner"))];
    }

    function _setOwner(address _owner) private {
      addressStorage[keccak256(abi.encodePacked("owner"))] = _owner;
    }

    function getVersion() public view returns(uint256) {
      return version;
    }

    function _setVersion(uint256 _newVersion) private {
      version = _newVersion;
    }

    function getImplementation() public view returns(address) {
      return implementation;
    }

    function _setImplementation(address _newImplementation) private {
      implementation = _newImplementation;
    }

    function getProxyStorage() public view returns(address) {
      return addressStorage[keccak256(abi.encodePacked("proxyStorage"))];
    }

    function _setProxyStorage(address _proxyStorage) private {
      addressStorage[keccak256(abi.encodePacked("proxyStorage"))] = _proxyStorage;
    }
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

pragma solidity ^0.4.24;

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {
    int256 constant private INT256_MIN = -2**255;

    /**
    * @dev Multiplies two unsigned integers, reverts on overflow.
    */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
    * @dev Multiplies two signed integers, reverts on overflow.
    */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below

        int256 c = a * b;
        require(c / a == b);

        return c;
    }

    /**
    * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
    */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0); // Solidity only automatically asserts when dividing by 0
        require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow

        int256 c = a / b;

        return c;
    }

    /**
    * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;

        return c;
    }

    /**
    * @dev Subtracts two signed integers, reverts on overflow.
    */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));

        return c;
    }

    /**
    * @dev Adds two unsigned integers, reverts on overflow.
    */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);

        return c;
    }

    /**
    * @dev Adds two signed integers, reverts on overflow.
    */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));

        return c;
    }

    /**
    * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }
}

// File: contracts/ProxyStorage.sol

pragma solidity ^0.4.24;



/**
* @title Contract used for access and upgradeability to all network contracts
* @author LiorRabin
*/
contract ProxyStorage is EternalStorage {
  using SafeMath for uint256;

  /**
  * @dev Available contract types on the network
  */
  enum ContractTypes {
    Invalid,
    Consensus,
    BlockReward,
    ProxyStorage,
    Voting
  }

  /**
  * @dev This event will be emitted when all contract addresses have been initialized by the contract owner
  */
  event ProxyInitialized(
    address consensus,
    address blockReward,
    address voting
  );

  /**
  * @dev This event will be emitted each time a contract address is updated
  * @param contractType contract type (See ContractTypes enum)
  * @param contractAddress contract address set for the contract type
  */
  event AddressSet(uint256 contractType, address contractAddress);

  /**
  * @dev This modifier verifies that msg.sender is the owner of the contract
  */
  modifier onlyOwner() {
    require(msg.sender == addressStorage[OWNER]);
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is the voting contract which implement proxy address change
  */
  modifier onlyVoting() {
    require(msg.sender == getVoting());
    _;
  }

  /**
  * @dev Function to be called on contract initialization
  * @param _consensus address of the network consensus contract
  */
  function initialize(address _consensus) external onlyOwner {
    require(!isInitialized());
    require(_consensus != address(0));
    require(_consensus != address(this));
    _setConsensus(_consensus);
    setInitialized(true);
  }

  /**
  * @dev Function to be called to initialize all available contract types addresses
  */
  function initializeAddresses(address _blockReward, address _voting) external onlyOwner {
    require(!boolStorage[PROXY_STORAGE_ADDRESSES_INITIALIZED]);

    addressStorage[BLOCK_REWARD] = _blockReward;
    addressStorage[VOTING] = _voting;

    boolStorage[PROXY_STORAGE_ADDRESSES_INITIALIZED] = true;

    emit ProxyInitialized(
      getConsensus(),
      _blockReward,
      _voting
    );
  }

  /**
  * @dev Function to be called to set specific contract type address
  * @param _contractType contract type (See ContractTypes enum)
  * @param _contractAddress contract address set for the contract type
  */
  function setContractAddress(uint256 _contractType, address _contractAddress) external onlyVoting returns(bool) {
    if (!isInitialized()) return false;
    if (_contractAddress == address(0)) return false;

    bool success = false;

    if (_contractType == uint256(ContractTypes.Consensus)) {
      success = EternalStorageProxy(getConsensus()).upgradeTo(_contractAddress);
    } else if (_contractType == uint256(ContractTypes.BlockReward)) {
      success = EternalStorageProxy(getBlockReward()).upgradeTo(_contractAddress);
    } else if (_contractType == uint256(ContractTypes.ProxyStorage)) {
      success = EternalStorageProxy(this).upgradeTo(_contractAddress);
    } else if (_contractType == uint256(ContractTypes.Voting)) {
      success = EternalStorageProxy(getVoting()).upgradeTo(_contractAddress);
    }

    if (success) {
      emit AddressSet(_contractType, _contractAddress);
    }
    return success;
  }

  /**
  * @dev Function checking if a contract type is valid one for proxy usage
  * @param _contractType contract type to check if valid
  */
  function isValidContractType(uint256 _contractType) external pure returns(bool) {
    return
      _contractType == uint256(ContractTypes.Consensus) ||
      _contractType == uint256(ContractTypes.BlockReward) ||
      _contractType == uint256(ContractTypes.ProxyStorage) ||
      _contractType == uint256(ContractTypes.Voting);
  }

  bytes32 internal constant OWNER = keccak256(abi.encodePacked("owner"));
  bytes32 internal constant CONSENSUS = keccak256(abi.encodePacked("consensus"));
  bytes32 internal constant BLOCK_REWARD = keccak256(abi.encodePacked("blockReward"));
  bytes32 internal constant VOTING = keccak256(abi.encodePacked("voting"));
  bytes32 internal constant PROXY_STORAGE_ADDRESSES_INITIALIZED = keccak256(abi.encodePacked("proxyStorageAddressesInitialized"));

  function _setConsensus(address _consensus) private {
    addressStorage[CONSENSUS] = _consensus;
  }

  function getConsensus() public view returns(address){
    return addressStorage[CONSENSUS];
  }

  function getBlockReward() public view returns(address){
    return addressStorage[BLOCK_REWARD];
  }

  function getVoting() public view returns(address){
    return addressStorage[VOTING];
  }
}

// File: openzeppelin-solidity/contracts/math/Math.sol

pragma solidity ^0.4.24;

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

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

    /**
    * @dev Calculates the average of two numbers. Since these are integers,
    * averages of an even and odd number cannot be represented, and will be
    * rounded down.
    */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

// File: contracts/ConsensusUtils.sol

pragma solidity ^0.4.24;





/**
* @title Consensus utility contract
* @author LiorRabin
*/
contract ConsensusUtils is EternalStorage, ValidatorSet {
  using SafeMath for uint256;

  uint256 public constant DECIMALS = 10 ** 18;
  uint256 public constant MAX_VALIDATORS = 21;
  uint256 public constant MIN_STAKE = 5e21; // 5,000
  uint256 public constant MAX_STAKE = 1e24; // 1,000,000
  uint256 public constant CYCLE_DURATION_BLOCKS = 57600; // 48 hours [48*60*60/3]
  uint256 public constant SNAPSHOTS_PER_CYCLE = 0; // snapshot each 288 minutes [34560/10/60*5]
  uint256 public constant DEFAULT_VALIDATOR_FEE = 15e16; // 15%
  uint256 public constant VALIDATOR_PRODUCTIVITY_BP = 3000; // 30%
  uint256 public constant MAX_STRIKE_COUNT = 5;
  uint256 public constant STRIKE_RESET = 50; // reset strikes after 50 clean cycles

  /**
  * @dev This event will be emitted after a change to the validator set has been finalized
  * @param newSet array of addresses which represent the new validator set
  */
  event ChangeFinalized(address[] newSet);

  /**
  * @dev This event will be emitted on cycle end to indicate the `emitInitiateChange` function needs to be called to apply a new validator set
  */
  event ShouldEmitInitiateChange();

  /**
  * @dev This modifier verifies that the change initiated has not been finalized yet
  */
  modifier notFinalized() {
    require(!isFinalized());
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is the system address (EIP96)
  */
  modifier onlySystem() {
    require(msg.sender == addressStorage[SYSTEM_ADDRESS]);
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is the owner of the contract
  */
  modifier onlyOwner() {
    require(msg.sender == addressStorage[OWNER]);
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is the block reward contract
  */
  modifier onlyBlockReward() {
    require(msg.sender == ProxyStorage(getProxyStorage()).getBlockReward());
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is a validator
  */
  modifier onlyValidator() {
    require(isValidator(msg.sender));
    _;
  }

  /**
  * @dev This modifier verifies that msg.sender is currently jailed
  */
  modifier onlyJailedValidator() {
    require(isJailed(msg.sender));
    _;
  }

  bytes32 internal constant OWNER = keccak256(abi.encodePacked("owner"));
  bytes32 internal constant SYSTEM_ADDRESS = keccak256(abi.encodePacked("SYSTEM_ADDRESS"));
  bytes32 internal constant IS_FINALIZED = keccak256(abi.encodePacked("isFinalized"));
  bytes32 internal constant CURRENT_CYCLE_START_BLOCK = keccak256(abi.encodePacked("currentCycleStartBlock"));
  bytes32 internal constant CURRENT_CYCLE_END_BLOCK = keccak256(abi.encodePacked("currentCycleEndBlock"));
  bytes32 internal constant LAST_SNAPSHOT_TAKEN_AT_BLOCK = keccak256(abi.encodePacked("lastSnapshotTakenAtBlock"));
  bytes32 internal constant NEXT_SNAPSHOT_ID = keccak256(abi.encodePacked("nextSnapshotId"));
  bytes32 internal constant CURRENT_VALIDATORS = keccak256(abi.encodePacked("currentValidators"));
  bytes32 internal constant PENDING_VALIDATORS = keccak256(abi.encodePacked("pendingValidators"));
  bytes32 internal constant PROXY_STORAGE = keccak256(abi.encodePacked("proxyStorage"));
  bytes32 internal constant WAS_PROXY_STORAGE_SET = keccak256(abi.encodePacked("wasProxyStorageSet"));
  bytes32 internal constant NEW_VALIDATOR_SET = keccak256(abi.encodePacked("newValidatorSet"));
  bytes32 internal constant SHOULD_EMIT_INITIATE_CHANGE = keccak256(abi.encodePacked("shouldEmitInitiateChange"));
  bytes32 internal constant TOTAL_STAKE_AMOUNT = keccak256(abi.encodePacked("totalStakeAmount"));
  bytes32 internal constant JAILED_VALIDATORS = keccak256(abi.encodePacked("jailedValidators"));

  function _delegate(address _staker, uint256 _amount, address _validator) internal {
    require(_staker != address(0));
    require(_amount != 0);
    require(_validator != address(0));

    _delegatedAmountAdd(_staker, _validator, _amount);
    _stakeAmountAdd(_validator, _amount);

    // stake amount of the validator isn't greater than the max stake
    require(stakeAmount(_validator) <= getMaxStake());

    // the validator must stake himselft the minimum stake
    if (stakeAmount(_validator) >= getMinStake() && !isPendingValidator(_validator)) {
      _pendingValidatorsAdd(_validator);
      _setValidatorFee(_validator, DEFAULT_VALIDATOR_FEE);
    }

    // if _validator is one of the current validators
    if (isValidator(_validator)) {
      // the total stake needs to be adjusted for the block reward formula
      _totalStakeAmountAdd(_amount);
    }
  }

  function _withdraw(address _staker, uint256 _amount, address _validator) internal {
    require(_validator != address(0));
    require(_amount > 0);
    require(_amount <= stakeAmount(_validator));
    require(_amount <= delegatedAmount(_staker, _validator));

    bool _isValidator = isValidator(_validator);

    // if new stake amount is lesser than minStake and the validator is one of the current validators
    if (stakeAmount(_validator).sub(_amount) < getMinStake() && _isValidator) {
      // do not withdaw the amount until the validator is in current set
      _pendingValidatorsRemove(_validator);
      return;
    }


    _delegatedAmountSub(_staker, _validator, _amount);
    _stakeAmountSub(_validator, _amount);

    // if _validator is one of the current validators
    if (_isValidator) {
      // the total stake needs to be adjusted for the block reward formula
      _totalStakeAmountSub(_amount);
    }

    // if validator is needed to be removed from pending, but not current
    if (stakeAmount(_validator) < getMinStake()) {
      _pendingValidatorsRemove(_validator);
    }
    _staker.transfer(_amount);
  }

  function _setSystemAddress(address _newAddress) internal {
    addressStorage[SYSTEM_ADDRESS] = _newAddress;
  }

  function setProxyStorage(address _newAddress) external onlyOwner {
    require(_newAddress != address(0));
    require(!boolStorage[WAS_PROXY_STORAGE_SET]);
    addressStorage[PROXY_STORAGE] = _newAddress;
    boolStorage[WAS_PROXY_STORAGE_SET] = true;
  }

  function getProxyStorage() public view returns(address) {
    return addressStorage[PROXY_STORAGE];
  }

  function _setFinalized(bool _status) internal {
    boolStorage[IS_FINALIZED] = _status;
  }

  function isFinalized() public view returns(bool) {
    return boolStorage[IS_FINALIZED];
  }

  /**
  * returns maximum possible validators number
  */
  function getMaxValidators() public pure returns(uint256) {
    return MAX_VALIDATORS;
  }

  /**
  * returns minimum stake (wei) needed to become a validator
  */
  function getMinStake() public pure returns(uint256) {
    return MIN_STAKE;
  }

  /**
  * returns maximum stake (wei) for a validator
  */
  function getMaxStake() public pure returns(uint256) {
    return MAX_STAKE;
  }

  /**
  * @dev Function returns the minimum validator fee amount in wei
    While 100% is 1e18
  */
  function getMinValidatorFee() public pure returns(uint256) {
    return DEFAULT_VALIDATOR_FEE;
  }

  

  /**
  * returns number of blocks per cycle (block time is 5 seconds)
  */
  function getCycleDurationBlocks() public pure returns(uint256) {
    return CYCLE_DURATION_BLOCKS;
  }

  function _setCurrentCycle() internal {
    uintStorage[CURRENT_CYCLE_START_BLOCK] = block.number;
    uintStorage[CURRENT_CYCLE_END_BLOCK] = block.number + getCycleDurationBlocks();
  }

  function _checkJail(address[] _validatorSet) internal {
    uint256 expectedNumberOfBlocks = getCycleDurationBlocks().mul(VALIDATOR_PRODUCTIVITY_BP).div(_validatorSet.length).div(10000);
    for (uint i = 0; i < _validatorSet.length; i++) {
      if(blockCounter(_validatorSet[i]) < expectedNumberOfBlocks) {
        // Validator hasn't met the desired uptime jail them and remove them from the next cycle
        _jailValidator(_validatorSet[i]);
      } else if (getStrikes(_validatorSet[i]) != 0) {
        // Validator has met desired uptime and has strikes, inc the strike reset
        _incStrikeReset(_validatorSet[i]);
      }
      //reset the block counter
      _resetBlockCounter(_validatorSet[i]);
    }
  }

  function _removeFromJail(address _validator) internal {
    _jailedValidatorRemove(_validator);
    if (stakeAmount(_validator) >= getMinStake() && !isPendingValidator(_validator)) {
      _pendingValidatorsAdd(_validator);
    }
  }

  function getCurrentCycleStartBlock() external view returns(uint256) {
    return uintStorage[CURRENT_CYCLE_START_BLOCK];
  }

  function getCurrentCycleEndBlock() public view returns(uint256) {
    return uintStorage[CURRENT_CYCLE_END_BLOCK];
  }

  function getReleaseBlock(address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("releaseBlock", _validator))];
  }

  /**
  * returns number of pending validator snapshots to be saved each cycle
  */
  function getSnapshotsPerCycle() public pure returns(uint256) {
    return SNAPSHOTS_PER_CYCLE;
  }

  function _setLastSnapshotTakenAtBlock(uint256 _block) internal {
    uintStorage[LAST_SNAPSHOT_TAKEN_AT_BLOCK] = _block;
  }

  function getLastSnapshotTakenAtBlock() public view returns(uint256) {
    return uintStorage[LAST_SNAPSHOT_TAKEN_AT_BLOCK];
  }

  function _setNextSnapshotId(uint256 _id) internal {
    uintStorage[NEXT_SNAPSHOT_ID] = _id;
  }

  function getNextSnapshotId() public view returns(uint256) {
    return uintStorage[NEXT_SNAPSHOT_ID];
  }

  function _setSnapshot(uint256 _snapshotId, address[] _addresses) internal {
    uint256 len = _addresses.length;
    uint256 n = Math.min(getMaxValidators(), len);
    address[] memory _result = new address[](n);
    uint256 rand = _getSeed();
    for (uint256 i = 0; i < n; i++) {
      uint256 j = rand % len;
      _result[i] = _addresses[j];
      _addresses[j] = _addresses[len - 1];
      delete _addresses[len - 1];
      len--;
      rand = uint256(keccak256(abi.encodePacked(rand)));
    }
    _setSnapshotAddresses(_snapshotId, _result);
  }

  function _setSnapshotAddresses(uint256 _snapshotId, address[] _addresses) internal {
    addressArrayStorage[keccak256(abi.encodePacked("snapshot", _snapshotId, "addresses"))] = _addresses;
  }

  function getSnapshotAddresses(uint256 _snapshotId) public view returns(address[]) {
    return addressArrayStorage[keccak256(abi.encodePacked("snapshot", _snapshotId, "addresses"))];
  }

  function currentValidators() public view returns(address[]) {
    return addressArrayStorage[CURRENT_VALIDATORS];
  }

  function currentValidatorsLength() public view returns(uint256) {
    return addressArrayStorage[CURRENT_VALIDATORS].length;
  }

  function jailedValidatorsLength() public view returns(uint256) {
    return addressArrayStorage[JAILED_VALIDATORS].length;
  }

  function currentValidatorsAtPosition(uint256 _p) public view returns(address) {
    return addressArrayStorage[CURRENT_VALIDATORS][_p];
  }

  function jailedValidatorsAtPosition(uint256 _p) public view returns(address) {
    return addressArrayStorage[JAILED_VALIDATORS][_p];
  }

  function isValidator(address _address) public view returns(bool) {
    for (uint256 i; i < currentValidatorsLength(); i++) {
      if (_address == currentValidatorsAtPosition(i)) {
        return true;
      }
    }
    return false;
  }

  function isJailed(address _address) public view returns(bool) {
    for (uint256 i; i < jailedValidatorsLength(); i++) {
      if (_address == jailedValidatorsAtPosition(i)) {
        return true;
      }
    }
    return false;
  }

  function requiredSignatures() public view returns(uint256) {
    return currentValidatorsLength().div(2).add(1);
  }

  function _currentValidatorsAdd(address _address) internal {
    addressArrayStorage[CURRENT_VALIDATORS].push(_address);
  }

  function _setCurrentValidators(address[] _currentValidators) internal {
    uint256 totalStake = 0;
    for (uint i = 0; i < _currentValidators.length; i++) {
      uint256 stakedAmount = stakeAmount(_currentValidators[i]);
      totalStake = totalStake + stakedAmount;

      // setting fee on all active validators to at least minimum fee
      // needs to run only once for the existing validators
      uint _validatorFee = validatorFee(_currentValidators[i]);
      if (_validatorFee < getMinValidatorFee()) {
        _setValidatorFee(_currentValidators[i],  getMinValidatorFee());
      }
    }
    _setTotalStakeAmount(totalStake);
    addressArrayStorage[CURRENT_VALIDATORS] = _currentValidators;
  }

  function pendingValidators() public view returns(address[]) {
    return addressArrayStorage[PENDING_VALIDATORS];
  }

  function pendingValidatorsLength() public view returns(uint256) {
    return addressArrayStorage[PENDING_VALIDATORS].length;
  }

  function pendingValidatorsAtPosition(uint256 _p) public view returns(address) {
    return addressArrayStorage[PENDING_VALIDATORS][_p];
  }

  function jailedValidators() public view returns(address[]) {
    return addressArrayStorage[JAILED_VALIDATORS];
  }

  function isPendingValidator(address _address) public view returns(bool) {
    for (uint256 i; i < pendingValidatorsLength(); i++) {
      if (_address == pendingValidatorsAtPosition(i)) {
        return true;
      }
    }
    return false;
  }

  function _jailValidator(address _address) internal {
    _pendingValidatorsRemove(_address);
    _addJailedValidator(_address);
    _setJailRelease(_address);
    _resetStrikeReset(_address);
  }

  function _maintenance(address _address) internal {
    _pendingValidatorsRemove(_address);
    _addJailedValidator(_address);
  }

  function _setPendingValidatorsAtPosition(uint256 _p, address _address) internal {
    addressArrayStorage[PENDING_VALIDATORS][_p] = _address;
  }

  function _setJailedValidatorsAtPosition(uint256 _p, address _address) internal {
    addressArrayStorage[JAILED_VALIDATORS][_p] = _address;
  }

  function _pendingValidatorsAdd(address _address) internal {
    require(isJailed(_address) == false);
    addressArrayStorage[PENDING_VALIDATORS].push(_address);
  }

  function _addJailedValidator(address _address) internal {
    addressArrayStorage[JAILED_VALIDATORS].push(_address);
  }

  function _jailedValidatorRemove(address _address) internal {
    bool found = false;
    uint256 removeIndex;
    for (uint256 i; i < jailedValidatorsLength(); i++) {
      if (_address == jailedValidatorsAtPosition(i)) {
        removeIndex = i;
        found = true;
        break;
      }
    }
    if (found) {
      uint256 lastIndex = jailedValidatorsLength() - 1;
      address lastValidator = jailedValidatorsAtPosition(lastIndex);
      if (lastValidator != address(0)) {
        _setJailedValidatorsAtPosition(removeIndex, lastValidator);
      }
      delete addressArrayStorage[JAILED_VALIDATORS][lastIndex];
      addressArrayStorage[JAILED_VALIDATORS].length--;
      // if the validator in on of the current validators
    }
  }

  function _pendingValidatorsRemove(address _address) internal {
    bool found = false;
    uint256 removeIndex;
    for (uint256 i; i < pendingValidatorsLength(); i++) {
      if (_address == pendingValidatorsAtPosition(i)) {
        removeIndex = i;
        found = true;
        break;
      }
    }
    if (found) {
      uint256 lastIndex = pendingValidatorsLength() - 1;
      address lastValidator = pendingValidatorsAtPosition(lastIndex);
      if (lastValidator != address(0)) {
        _setPendingValidatorsAtPosition(removeIndex, lastValidator);
      }
      delete addressArrayStorage[PENDING_VALIDATORS][lastIndex];
      addressArrayStorage[PENDING_VALIDATORS].length--;
      // if the validator in on of the current validators
    }
  }

  function stakeAmount(address _address) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("stakeAmount", _address))];
  }

  function totalStakeAmount() public view returns(uint256) {
    return uintStorage[TOTAL_STAKE_AMOUNT];
  }

  function _stakeAmountAdd(address _address, uint256 _amount) internal {
    uintStorage[keccak256(abi.encodePacked("stakeAmount", _address))] = uintStorage[keccak256(abi.encodePacked("stakeAmount", _address))].add(_amount);
  }

  function _stakeAmountSub(address _address, uint256 _amount) internal {
    uintStorage[keccak256(abi.encodePacked("stakeAmount", _address))] = uintStorage[keccak256(abi.encodePacked("stakeAmount", _address))].sub(_amount);
  }

  function _setJailRelease(address _address) internal {
    uint256 strike = uintStorage[keccak256(abi.encodePacked("strikeCount", _address))];
    // release block scales based on strikes, strikes get reset after undergoing STRIKE_RESET jail free cycles
    // subract one so they can flag to be released on start of the next cycle
    uintStorage[keccak256(abi.encodePacked("releaseBlock", _address))] = (getCurrentCycleEndBlock().add(getCycleDurationBlocks().mul(strike)).sub(1));
    if (strike <= MAX_STRIKE_COUNT) {
      uintStorage[keccak256(abi.encodePacked("strikeCount", _address))] = strike + 1;
    }
  }

  function _resetStrikes(address _address) internal {
    uintStorage[keccak256(abi.encodePacked("strikeCount", _address))] = 0;
  }

  function delegatedAmount(address _address, address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))];
  }

  function _delegatedAmountAdd(address _address, address _validator, uint256 _amount) internal {
    uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))] = uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))].add(_amount);
    if (_address != _validator && !isDelegator(_validator, _address)) {
      _delegatorsAdd(_address, _validator);
    }
  }

  function _delegatedAmountSub(address _address, address _validator, uint256 _amount) internal {
    uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))] = uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))].sub(_amount);
    if (uintStorage[keccak256(abi.encodePacked("delegatedAmount", _address, _validator))] == 0) {
      _delegatorsRemove(_address, _validator);
    }
  }

  function delegators(address _validator) public view returns(address[]) {
    return addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))];
  }

  function delegatorsLength(address _validator) public view returns(uint256) {
    return addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))].length;
  }

  function delegatorsAtPosition(address _validator, uint256 _p) public view returns(address) {
    return addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))][_p];
  }

  function blockCounter(address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("blockCounter", _validator))];
  }

  function isDelegator(address _validator, address _address) public view returns(bool) {
    for (uint256 i; i < delegatorsLength(_validator); i++) {
      if (_address == delegatorsAtPosition(_validator, i)) {
        return true;
      }
    }
    return false;
  }

  function _setDelegatorsAtPosition(address _validator, uint256 _p, address _address) internal {
    addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))][_p] = _address;
  }

  function _delegatorsAdd(address _address, address _validator) internal {
    addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))].push(_address);
  }

  function _delegatorsRemove(address _address, address _validator) internal {
    bool found = false;
    uint256 removeIndex;
    for (uint256 i; i < delegatorsLength(_validator); i++) {
      if (_address == delegatorsAtPosition(_validator, i)) {
        removeIndex = i;
        found = true;
        break;
      }
    }
    if (found) {
      uint256 lastIndex = delegatorsLength(_validator) - 1;
      address lastDelegator = delegatorsAtPosition(_validator, lastIndex);
      if (lastDelegator != address(0)) {
        _setDelegatorsAtPosition(_validator, removeIndex, lastDelegator);
      }
      delete addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))][lastIndex];
      addressArrayStorage[keccak256(abi.encodePacked("delegators", _validator))].length--;
    }
  }

  function getDelegatorsForRewardDistribution(address _validator, uint256 _rewardAmount) public view returns(address[], uint256[]) {
    address[] memory _delegators = delegators(_validator);
    uint256[] memory _rewards = new uint256[](_delegators.length);
    uint256 divider = Math.max(getMinStake(), stakeAmount(_validator));

    for (uint256 i; i < _delegators.length; i++) {
      uint256 _amount = delegatedAmount(delegatorsAtPosition(_validator, i), _validator);
      _rewards[i] = _rewardAmount.mul(_amount).div(divider).mul(DECIMALS - validatorFee(_validator)).div(DECIMALS);
    }

    return (_delegators, _rewards);
  }

  function newValidatorSet() public view returns(address[]) {
    return addressArrayStorage[NEW_VALIDATOR_SET];
  }

  function newValidatorSetLength() public view returns(uint256) {
    return addressArrayStorage[NEW_VALIDATOR_SET].length;
  }

  function _setNewValidatorSet(address[] _newSet) internal {
    addressArrayStorage[NEW_VALIDATOR_SET] = _newSet;
  }

  function _setTotalStakeAmount(uint256 _totalStake) internal {
    uintStorage[TOTAL_STAKE_AMOUNT] = _totalStake;
  }

  function _totalStakeAmountAdd(uint256 _stakeAmount) internal {
    uintStorage[TOTAL_STAKE_AMOUNT] = uintStorage[TOTAL_STAKE_AMOUNT].add(_stakeAmount);
  }

  function _totalStakeAmountSub(uint256 _stakeAmount) internal {
    uintStorage[TOTAL_STAKE_AMOUNT] = uintStorage[TOTAL_STAKE_AMOUNT].sub(_stakeAmount);
  }

  function shouldEmitInitiateChange() public view returns(bool) {
    return boolStorage[SHOULD_EMIT_INITIATE_CHANGE];
  }

  function _setShouldEmitInitiateChange(bool _status) internal {
    boolStorage[SHOULD_EMIT_INITIATE_CHANGE] = _status;
  }

  function _hasCycleEnded() internal view returns(bool) {
    return (block.number >= getCurrentCycleEndBlock());
  }

  function _getSeed() internal view returns(uint256) {
    return uint256(keccak256(abi.encodePacked(blockhash(block.number - 1))));
  }

  function _getRandom(uint256 _from, uint256 _to) internal view returns(uint256) {
    return _getSeed().mod(_to.sub(_from)).add(_from);
  }

  function validatorFee(address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("validatorFee", _validator))];
  }

  function _setValidatorFee(address _validator, uint256 _amount) internal {
    uintStorage[keccak256(abi.encodePacked("validatorFee", _validator))] = _amount;
  }

  /**
  * Internal function to be called from cycle() to increment the block counter for this validator. 
  * block counter is used to assess the validators uptime in a given cycle. It is zeroed at the start of each cycle.
  */
  function _incBlockCounter(address _validator) internal {
    uintStorage[keccak256(abi.encodePacked("blockCounter", _validator))] = uintStorage[keccak256(abi.encodePacked("blockCounter", _validator))] + 1;
  }

  /**
  * Internal function to be called on cycle end to reset the block counter for a validator so we are ready for the new cycle
  */
  function _resetBlockCounter(address _validator) internal {
    uintStorage[keccak256(abi.encodePacked("blockCounter", _validator))] = 0;
  }

  /**
  * Internal function to be called each time a validator has had a clean cycle. the strike reset counter is used to reset a validator strike count
  * if it exceeds the reset threshold
  */
  function _incStrikeReset(address _validator) internal {
    uintStorage[keccak256(abi.encodePacked("strikeReset", _validator))] = uintStorage[keccak256(abi.encodePacked("strikeReset", _validator))] + 1;
    if (uintStorage[keccak256(abi.encodePacked("strikeReset", _validator))] > STRIKE_RESET)
    {
      // Strike count exceeds the reset criteria, reset the strike and reset counters back to zero.
      _resetStrikeReset(_validator);
      _resetStrikes(_validator);
    }
  }

  /**
  * Internal function to be called after a validator has had STRIKE_RESET clean cycles.
  */
  function _resetStrikeReset(address _validator) internal {
    uintStorage[keccak256(abi.encodePacked("strikeReset", _validator))] = 0;
  }

  function getStrikeReset(address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("strikeReset", _validator))];
  }

  function getStrikes(address _validator) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("strikeCount", _validator))];
  }
}

// File: contracts/Consensus.sol

pragma solidity ^0.4.24;



/**
* @title Contract handling consensus logic
* @author LiorRabin
*/
contract Consensus is ConsensusUtils {
  /**
  * @dev Function to be called on contract initialization
  * @param _initialValidator address of the initial validator. If not set - msg.sender will be the initial validator
  */
  function initialize(address _initialValidator) external onlyOwner {
    require(!isInitialized());
    _setSystemAddress(0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE);
    _setCurrentCycle();
    if (_initialValidator == address(0)) {
      _currentValidatorsAdd(msg.sender);
    } else {
      _currentValidatorsAdd(_initialValidator);
    }
    _setFinalized(true);
    setInitialized(true);
  }

  /**
  * @dev Function which returns the current validator addresses
  */
  function getValidators() external view returns(address[]) {
    return currentValidators();
  }

  /**
  * @dev See ValidatorSet.finalizeChange
  */
  function finalizeChange() external onlySystem notFinalized {
    if (newValidatorSetLength() > 0) {
      _setCurrentValidators(newValidatorSet());
      emit ChangeFinalized(currentValidators());
    }
    _setFinalized(true);
  }

  /**
  * @dev Fallback function allowing to pay to this contract. Whoever sends funds is considered as "staking" and wanting to become a validator.
  */
  function () external payable {
    _delegate(msg.sender, msg.value, msg.sender);
  }

  /**
  * @dev stake to become a validator.
  */
  function stake() external payable {
    _delegate(msg.sender, msg.value, msg.sender);
  }

  /**
  * @dev delegate to a validator
  * @param _validator the address of the validator msg.sender is delegating to
  */
  function delegate(address _validator) external payable {
    _delegate(msg.sender, msg.value, _validator);
  }

  /**
  * @dev Function to be called when a staker whishes to withdraw some of his staked funds
  * @param _amount the amount msg.sender wishes to withdraw from the contract
  */
  function withdraw(uint256 _amount) external {
    _withdraw(msg.sender, _amount, msg.sender);
  }

  /**
  * @dev Function to be called when a delegator whishes to withdraw some of his staked funds for a validator
  * @param _validator the address of the validator msg.sender has delegating to
  * @param _amount the amount msg.sender wishes to withdraw from the contract
  */
  function withdraw(address _validator, uint256 _amount) external {
    _withdraw(msg.sender, _amount, _validator);
  }

  /**
  * @dev Function to be called by the block reward contract each block to handle cycles and snapshots logic
  */
  function cycle(address _validator) external onlyBlockReward {
    _incBlockCounter(_validator);
    if (_hasCycleEnded()) {
      IVoting(ProxyStorage(getProxyStorage()).getVoting()).onCycleEnd(currentValidators());
      _setCurrentCycle();
      _checkJail(currentValidators());
      address[] memory newSet = pendingValidators();
      if (newSet.length > 0) {
        _setNewValidatorSet(newSet);
      }
      if (newValidatorSetLength() > 0) {
        _setFinalized(false);
        _setShouldEmitInitiateChange(true);
        emit ShouldEmitInitiateChange();
      }
      IBlockReward(ProxyStorage(getProxyStorage()).getBlockReward()).onCycleEnd();
    }
  }

  /**
  * @dev Function to be called by validators only to emit InitiateChange event (only if `shouldEmitInitiateChange` returns true)
  */
  function emitInitiateChange() external onlyValidator {
    require(shouldEmitInitiateChange());
    require(newValidatorSetLength() > 0);
    emit InitiateChange(blockhash(block.number - 1), newValidatorSet());
    _setShouldEmitInitiateChange(false);
  }


  /**
  * @dev Function to be called by validators to update the validator fee, that's the fee cut the validator takes from his delegatots.
  * @param _amount fee percentage when 1e18 represents 100%.
  */
  function setValidatorFee(uint256 _amount) external onlyValidator {
    require (_amount <= 1 * DECIMALS);
    require(_amount >= getMinValidatorFee());
    _setValidatorFee(msg.sender, _amount);
  }

  /**
  * @dev Function to be called by jailed validator, in order to be released from jail
  */
  function unJail() external onlyJailedValidator {
    require(getReleaseBlock(msg.sender) <= getCurrentCycleEndBlock());

    _removeFromJail(msg.sender);
  }

  /**
  * @dev Function to be called by current validators to be dropped from the next cycle in order to perform maintenance 
  */
  function maintenance() external onlyValidator {
    require(isJailed(msg.sender) == false);
    _maintenance(msg.sender);
  }
}
        

Contract ABI

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getLastSnapshotTakenAtBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"jailedValidatorsLength","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"pendingValidatorsAtPosition","inputs":[{"type":"uint256","name":"_p"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"getSnapshotAddresses","inputs":[{"type":"uint256","name":"_snapshotId"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setProxyStorage","inputs":[{"type":"address","name":"_newAddress"}],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMinValidatorFee","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isJailed","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"delegatedAmount","inputs":[{"type":"address","name":"_address"},{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"SNAPSHOTS_PER_CYCLE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"pendingValidatorsLength","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"newValidatorSetLength","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"DECIMALS","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"stake","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"currentValidatorsLength","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"setValidatorFee","inputs":[{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMinStake","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"currentValidatorsAtPosition","inputs":[{"type":"uint256","name":"_p"}],"constant":true},{"type":"function","stateMutability":"payable","payable":true,"outputs":[],"name":"delegate","inputs":[{"type":"address","name":"_validator"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"newValidatorSet","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"jailedValidators","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""},{"type":"uint256[]","name":""}],"name":"getDelegatorsForRewardDistribution","inputs":[{"type":"address","name":"_validator"},{"type":"uint256","name":"_rewardAmount"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"STRIKE_RESET","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"maintenance","inputs":[],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"unJail","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_VALIDATORS","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"VALIDATOR_PRODUCTIVITY_BP","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"finalizeChange","inputs":[],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMaxValidators","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getStrikes","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"blockCounter","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"CYCLE_DURATION_BLOCKS","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"cycle","inputs":[{"type":"address","name":"_validator"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_STRIKE_COUNT","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getSnapshotsPerCycle","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"requiredSignatures","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"delegators","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isFinalized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"jailedValidatorsAtPosition","inputs":[{"type":"uint256","name":"_p"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"DEFAULT_VALIDATOR_FEE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getCurrentCycleStartBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"emitInitiateChange","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"totalStakeAmount","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"validatorFee","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isDelegator","inputs":[{"type":"address","name":"_validator"},{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"currentValidators","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getCycleDurationBlocks","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"pendingValidators","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getCurrentCycleEndBlock","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address[]","name":""}],"name":"getValidators","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"stakeAmount","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_initialValidator"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_STAKE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MIN_STAKE","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getStrikeReset","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"delegatorsLength","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getNextSnapshotId","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"delegatorsAtPosition","inputs":[{"type":"address","name":"_validator"},{"type":"uint256","name":"_p"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getProxyStorage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getReleaseBlock","inputs":[{"type":"address","name":"_validator"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"shouldEmitInitiateChange","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"withdraw","inputs":[{"type":"address","name":"_validator"},{"type":"uint256","name":"_amount"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isValidator","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isPendingValidator","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMaxStake","inputs":[],"constant":true},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"event","name":"ChangeFinalized","inputs":[{"type":"address[]","name":"newSet","indexed":false}],"anonymous":false},{"type":"event","name":"ShouldEmitInitiateChange","inputs":[],"anonymous":false},{"type":"event","name":"InitiateChange","inputs":[{"type":"bytes32","name":"parentHash","indexed":true},{"type":"address[]","name":"newSet","indexed":false}],"anonymous":false}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b50614f6b806100206000396000f3006080604052600436106102f25763ffffffff60e060020a6000350416630300fc3581146102ff57806308c90076146103265780630fe9d28e1461033b5780631043ca281461036f57806310855269146103d757806310f606e7146103f857806314bfb5271461040d57806321429e6014610442578063256f9193146104695780632a807f151461047e5780632bec36d2146104935780632e0f2625146104a85780632e1a7d4d146104bd578063392e53cd146104d55780633a4b66f1146104ea57806340c9cdeb146104f257806355460f811461050757806356a3b5fa1461051f57806357aeefc5146105345780635c19a95c1461054c5780635ccee1de14610560578063651d8c22146105755780636a28f12f1461058a5780636bdf1d5a146106475780636c376cc51461065c5780636eae5b1114610671578063714897df1461068657806372e81e321461069b57806375286211146106b057806376bd510f146106c55780637b1e52a5146106da5780637d8f7a61146106fb5780637e2bf1201461071c57806385cd8464146107315780638615b171146107525780638bbc1e6b146107675780638d0680431461077c5780638d23fc61146107915780638d4e4083146107b25780638da873f8146107c757806392b391f3146107df578063932781d6146107f457806393b4e25e1461080957806394409a561461081e5780639f77dc3014610833578063a0e1192914610854578063a2cde6091461087b578063a652492314610890578063a82f255b146108a5578063af295181146108ba578063b7ab4db5146108cf578063bf135267146108e4578063c4d66de814610905578063c98517c514610926578063cb1c2b5c1461093b578063d2166ce914610950578063ddb3f48714610971578063e9fbe9d414610992578063eb431b6a146109a7578063ec15a5e6146109cb578063ee19a7fc146109e0578063ef7b6d8914610a01578063f3fef3a314610a16578063facd743b14610a3a578063fb64aac114610a5b578063fe35505b14610a7c575b6102fd333433610a91565b005b34801561030b57600080fd5b50610314610b59565b60408051918252519081900360200190f35b34801561033257600080fd5b50610314610c0f565b34801561034757600080fd5b50610353600435610c71565b60408051600160a060020a039092168252519081900360200190f35b34801561037b57600080fd5b50610387600435610d38565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103c35781810151838201526020016103ab565b505050509050019250505060405180910390f35b3480156103e357600080fd5b506102fd600160a060020a0360043516610e73565b34801561040457600080fd5b50610314611192565b34801561041957600080fd5b5061042e600160a060020a036004351661119e565b604080519115158252519081900360200190f35b34801561044e57600080fd5b50610314600160a060020a03600435811690602435166111ef565b34801561047557600080fd5b506103146112b3565b34801561048a57600080fd5b506103146112b8565b34801561049f57600080fd5b5061031461131a565b3480156104b457600080fd5b5061031461138e565b3480156104c957600080fd5b506102fd60043561139a565b3480156104e157600080fd5b5061042e6113a8565b6102fd611460565b3480156104fe57600080fd5b5061031461146d565b34801561051357600080fd5b506102fd6004356114cf565b34801561052b57600080fd5b50610314611516565b34801561054057600080fd5b50610353600435611524565b6102fd600160a060020a0360043516611586565b34801561056c57600080fd5b50610387611591565b34801561058157600080fd5b5061038761169a565b34801561059657600080fd5b506105ae600160a060020a03600435166024356116fc565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156105f25781810151838201526020016105da565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610631578181015183820152602001610619565b5050505090500194505050505060405180910390f35b34801561065357600080fd5b506103146117fa565b34801561066857600080fd5b506102fd6117ff565b34801561067d57600080fd5b506102fd61182f565b34801561069257600080fd5b50610314611868565b3480156106a757600080fd5b5061031461186d565b3480156106bc57600080fd5b506102fd611873565b3480156106d157600080fd5b506103146119ec565b3480156106e657600080fd5b50610314600160a060020a03600435166119f1565b34801561070757600080fd5b50610314600160a060020a0360043516611ab5565b34801561072857600080fd5b50610314611b37565b34801561073d57600080fd5b506102fd600160a060020a0360043516611b3d565b34801561075e57600080fd5b50610314611e5d565b34801561077357600080fd5b50610314611e62565b34801561078857600080fd5b50610314611e67565b34801561079d57600080fd5b50610387600160a060020a0360043516611e8c565b3480156107be57600080fd5b5061042e611f0e565b3480156107d357600080fd5b50610353600435611f82565b3480156107eb57600080fd5b50610314611fe4565b34801561080057600080fd5b50610314611ff0565b34801561081557600080fd5b506102fd612064565b34801561082a57600080fd5b50610314612127565b34801561083f57600080fd5b50610314600160a060020a0360043516612189565b34801561086057600080fd5b5061042e600160a060020a036004358116906024351661221d565b34801561088757600080fd5b50610387612271565b34801561089c57600080fd5b506103146122d3565b3480156108b157600080fd5b506103876122d9565b3480156108c657600080fd5b5061031461233b565b3480156108db57600080fd5b506103876123af565b3480156108f057600080fd5b50610314600160a060020a03600435166123b9565b34801561091157600080fd5b506102fd600160a060020a036004351661243b565b34801561093257600080fd5b50610314612571565b34801561094757600080fd5b5061031461257f565b34801561095c57600080fd5b50610314600160a060020a036004351661258d565b34801561097d57600080fd5b50610314600160a060020a036004351661260f565b34801561099e57600080fd5b50610314612691565b3480156109b357600080fd5b50610353600160a060020a0360043516602435612705565b3480156109d757600080fd5b506103536127ed565b3480156109ec57600080fd5b50610314600160a060020a03600435166128ab565b348015610a0d57600080fd5b5061042e61293f565b348015610a2257600080fd5b506102fd600160a060020a03600435166024356129b3565b348015610a4657600080fd5b5061042e600160a060020a03600435166129be565b348015610a6757600080fd5b5061042e600160a060020a0360043516612a04565b348015610a8857600080fd5b50610314612a4a565b600160a060020a0383161515610aa657600080fd5b811515610ab257600080fd5b600160a060020a0381161515610ac757600080fd5b610ad2838284612a58565b610adc8183612c13565b610ae4612a4a565b610aed826123b9565b1115610af857600080fd5b610b00611516565b610b09826123b9565b10158015610b1d5750610b1b81612a04565b155b15610b3d57610b2b81612d5a565b610b3d81670214e8348c4f0000612e3d565b610b46816129be565b15610b5457610b5482612ed0565b505050565b60006002600060405160200180807f6c617374536e617073686f7454616b656e4174426c6f636b000000000000000081525060180190506040516020818303038152906040526040518082805190602001908083835b60208310610bce5780518252601f199092019160209182019101610baf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b90565b6000600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310610cd45780518252601f199092019160209182019101610cb5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050610d1d57fe5b600091825260209091200154600160a060020a031692915050565b6060600a60008360405160200180807f736e617073686f74000000000000000000000000000000000000000000000000815250600801828152602001807f61646472657373657300000000000000000000000000000000000000000000008152506009019150506040516020818303038152906040526040518082805190602001908083835b60208310610ddd5780518252601f199092019160209182019101610dbe565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015610e6757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610e49575b50505050509050919050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b60208310610ee65780518252601f199092019160209182019101610ec7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031633149250610f3791505057600080fd5b600160a060020a0381161515610f4c57600080fd5b6006600060405160200180807f77617350726f787953746f72616765536574000000000000000000000000000081525060120190506040516020818303038152906040526040518082805190602001908083835b60208310610fbf5780518252601f199092019160209182019101610fa0565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1615925061100991505057600080fd5b806004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b6020831061107d5780518252601f19909201916020918201910161105e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160009081208054600160a060020a031916600160a060020a039790971696909617909555505080517f77617350726f787953746f7261676553657400000000000000000000000000008184015281516012818303018152603290910191829052805160019460069490939182918401908083835b602083106111455780518252601f199092019160209182019101611126565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b670214e8348c4f000090565b6000805b6111aa610c0f565b8110156111e4576111ba81611f82565b600160a060020a031683600160a060020a031614156111dc57600191506111e9565b6001016111a2565b600091505b50919050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038087168202602f85015285160260438301528251603781840301815260579092019283905281516000936002938593909282918401908083835b602083106112715780518252601f199092019160209182019101611252565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020549695505050505050565b600081565b6000600a60006040516020018080600080516020614e60833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f01905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b670de0b6b3a764000081565b6113a5338233612fd6565b50565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b6020831061141d5780518252601f1990920191602091820191016113fe565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff16949350505050565b61146b333433610a91565b565b6000600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6114d8336129be565b15156114e357600080fd5b670de0b6b3a76400008111156114f857600080fd5b611500611192565b81101561150c57600080fd5b6113a53382612e3d565b69010f0cf064dd5920000090565b6000600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610cd45780518252601f199092019160209182019101610cb5565b6113a5333483610a91565b6060600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f0190506040516020818303038152906040526040518082805190602001908083835b602083106116065780518252601f1990920191602091820191016115e7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000208054845181870281018701909552808552939490939250840190508282801561169057602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611672575b5050505050905090565b6060600a60006040516020018080600080516020614e008339815191528152506010019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b606080606080600080600061171089611e8c565b9450845160405190808252806020026020018201604052801561173d578160200160208202803883390190505b50935061175961174b611516565b6117548b6123b9565b6130f0565b92505b84518210156117eb576117786117728a84612705565b8a6111ef565b90506117c8670de0b6b3a76400006117b06117928c612189565b670de0b6b3a7640000036117bc876117b08e8863ffffffff61310916565b9063ffffffff61313716565b9063ffffffff61310916565b84838151811015156117d657fe5b6020908102909101015260019091019061175c565b50929791965090945050505050565b603281565b611808336129be565b151561181357600080fd5b61181c3361119e565b1561182657600080fd5b61146b3361315a565b6118383361119e565b151561184357600080fd5b61184b61233b565b611854336128ab565b111561185f57600080fd5b61146b3361316c565b601581565b610bb881565b6004600060405160200180807f53595354454d5f41444452455353000000000000000000000000000000000000815250600e0190506040516020818303038152906040526040518082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a03163314925061193791505057600080fd5b61193f611f0e565b1561194957600080fd5b600061195361131a565b11156119e257611969611964611591565b6131a8565b7f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d2763253611992612271565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156119ce5781810151838201526020016119b6565b505050509050019250505060405180910390a15b61146b60016132fb565b601590565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310611a745780518252601f199092019160209182019101611a55565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b600060026000836040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b61e10081565b6060611b476127ed565b600160a060020a031663f89d40866040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611b8457600080fd5b505af1158015611b98573d6000803e3d6000fd5b505050506040513d6020811015611bae57600080fd5b5051600160a060020a03163314611bc457600080fd5b611bcd8261336e565b611bd561349e565b15611e5957611be26127ed565b600160a060020a0316631986d3766040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c1f57600080fd5b505af1158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b5051600160a060020a031663bbac62c8611c61612271565b6040518263ffffffff1660e060020a0281526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611cb3578181015183820152602001611c9b565b5050505090500192505050600060405180830381600087803b158015611cd857600080fd5b505af1158015611cec573d6000803e3d6000fd5b50505050611cf86134b0565b611d08611d03612271565b613621565b611d106122d9565b9050600081511115611d2557611d2581613706565b6000611d2f61131a565b1115611d7357611d3f60006132fb565b611d4960016137c8565b6040517fad8a61077dff62d25ea1bf7cf1af88e1b48075c3d497d494ac9b129b73b0d37c90600090a15b611d7b6127ed565b600160a060020a031663f89d40866040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611db857600080fd5b505af1158015611dcc573d6000803e3d6000fd5b505050506040513d6020811015611de257600080fd5b5051604080517fb1f0c8e10000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163b1f0c8e19160048082019260009290919082900301818387803b158015611e4057600080fd5b505af1158015611e54573d6000803e3d6000fd5b505050505b5050565b600581565b600090565b6000611e876001611e7b60026117b061146d565b9063ffffffff61383b16565b905090565b6060600a6000836040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310610ddd5780518252601f199092019160209182019101610dbe565b60006006600060405160200180807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0190506040516020818303038152906040526040518082805190602001908083836020831061141d5780518252601f1990920191602091820191016113fe565b6000600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610cd45780518252601f199092019160209182019101610cb5565b670214e8348c4f000081565b60006002600060405160200180807f63757272656e744379636c655374617274426c6f636b00000000000000000000815250601601905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b61206d336129be565b151561207857600080fd5b61208061293f565b151561208b57600080fd5b600061209561131a565b1161209f57600080fd5b6000194301407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c896120ce611591565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561210a5781810151838201526020016120f2565b505050509050019250505060405180910390a261146b60006137c8565b6000600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600260008360405160200180807f76616c696461746f724665650000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6000805b61222a8461260f565b8110156122655761223b8482612705565b600160a060020a031683600160a060020a0316141561225d576001915061226a565b600101612221565b600091505b5092915050565b6060600a60006040516020018080600080516020614ee08339815191528152506011019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b61e10090565b6060600a60006040516020018080600080516020614e608339815191528152506011019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b60006002600060405160200180807f63757272656e744379636c65456e64426c6f636b000000000000000000000000815250601401905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6060611e87612271565b600060026000836040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106124ae5780518252601f19909201916020918201910161248f565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506124ff91505057600080fd5b6125076113a8565b1561251157600080fd5b61252e73fffffffffffffffffffffffffffffffffffffffe61384d565b6125366134b0565b600160a060020a03811615156125545761254f3361391d565b61255d565b61255d8161391d565b61256760016132fb565b6113a5600161397d565b69d3c21bcecceda100000081565b69010f0cf064dd5920000081565b600060026000836040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6000600a6000836040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b60006002600060405160200180807f6e657874536e617073686f744964000000000000000000000000000000000000815250600e01905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a6000846040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106127885780518252601f199092019160209182019101612769565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506127d157fe5b600091825260209091200154600160a060020a03169392505050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b602083106128625780518252601f199092019160209182019101612843565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000600260008360405160200180807f72656c65617365426c6f636b0000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b60006006600060405160200180807f73686f756c64456d6974496e6974696174654368616e6765000000000000000081525060180190506040516020818303038152906040526040518082805190602001908083836020831061141d5780518252601f1990920191602091820191016113fe565b611e59338284612fd6565b6000805b6129ca61146d565b8110156111e4576129da81611524565b600160a060020a031683600160a060020a031614156129fc57600191506111e9565b6001016129c2565b6000805b612a106112b8565b8110156111e457612a2081610c71565b600160a060020a031683600160a060020a03161415612a4257600191506111e9565b600101612a08565b69d3c21bcecceda100000090565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038088168202602f8501528616026043830152825160378184030181526057909201928390528151612b2293859360029360009391929182918401908083835b60208310612adf5780518252601f199092019160209182019101612ac0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020549392505061383b9050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038089168202602f850152871602604383015282516037818403018152605790920192839052815160029360009392909182918401908083835b60208310612ba35780518252601f199092019160209182019101612b84565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050600160a060020a0382811690841614801590612c045750612c02828461221d565b155b15610b5457610b5483836139f0565b612c978160026000856040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612adf5780518252601f199092019160209182019101612ac0565b60026000846040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310612d185780518252601f199092019160209182019101612cf9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b612d638161119e565b15612d6d57600080fd5b600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310612dce5780518252601f199092019160209182019101612daf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092909201600090812080546001810182559082529390209092018054600160a060020a031916600160a060020a0394909416939093179092555050565b80600260008460405160200180807f76616c696461746f724665650000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612d185780518252601f199092019160209182019101612cf9565b612f3481600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612adf5780518252601f199092019160209182019101612ac0565b600260006040516020018080600080516020614ec083398151915281525060100190506040516020818303038152906040526040518082805190602001908083835b60208310612f955780518252601f199092019160209182019101612f76565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b6000600160a060020a0382161515612fed57600080fd5b60008311612ffa57600080fd5b613003826123b9565b83111561300f57600080fd5b61301984836111ef565b83111561302557600080fd5b61302e826129be565b9050613038611516565b61305184613045856123b9565b9063ffffffff613ae116565b10801561305b5750805b1561306e5761306982613af8565b6130ea565b613079848385613cf6565b6130838284613f48565b80156130925761309283613fcc565b61309a611516565b6130a3836123b9565b10156130b2576130b282613af8565b604051600160a060020a0385169084156108fc029085906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b505b50505050565b6000818310156131005781613102565b825b9392505050565b60008083151561311c576000915061226a565b5082820282848281151561312c57fe5b041461310257600080fd5b60008080831161314657600080fd5b828481151561315157fe5b04949350505050565b61316381613af8565b6113a581614030565b61317581614090565b61317d611516565b613186826123b9565b1015801561319a575061319881612a04565b155b156113a5576113a581612d5a565b60008080805b8451831015613242576131d785848151811015156131c857fe5b906020019060200201516123b9565b915081840193506131fe85848151811015156131ef57fe5b90602001906020020151612189565b9050613208611192565b81101561323757613237858481518110151561322057fe5b90602001906020020151613232611192565b612e3d565b6001909201916131ae565b61324b84614236565b84600a60006040516020018080600080516020614ee083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b602083106132ad5780518252601f19909201916020918201910161328e565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451611e54959194509201919050614d38565b806006600060405160200180807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b60026000826040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106133ef5780518252601f1990920191602091820191016133d0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120548451600080516020614e4083398151915281880152600160a060020a038816606060020a02602c8201528551808203880181529086019586905280516001909201966002969395509093508291848201918190849084908310612f955780518252601f199092019160209182019101612f76565b60006134a861233b565b431015905090565b436002600060405160200180807f63757272656e744379636c655374617274426c6f636b0000000000000000000081525060160190506040516020818303038152906040526040518082805190602001908083835b602083106135245780518252601f199092019160209182019101613505565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555061356c91506122d39050565b43016002600060405160200180807f63757272656e744379636c65456e64426c6f636b00000000000000000000000081525060140190506040516020818303038152906040526040518082805190602001908083835b602083106135e15780518252601f1990920191602091820191016135c2565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050565b60008061363d6127106117b085516117b0610bb86117bc6122d3565b9150600090505b8251811015610b54578161366e848381518110151561365f57fe5b90602001906020020151611ab5565b101561369957613694838281518110151561368557fe5b90602001906020020151614297565b6136de565b6136b983828151811015156136aa57fe5b906020019060200201516119f1565b156136de576136de83828151811015156136cf57fe5b906020019060200201516142bb565b6136fe83828151811015156136ef57fe5b906020019060200201516144fa565b600101613644565b80600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f0190506040516020818303038152906040526040518082805190602001908083835b6020831061377a5780518252601f19909201916020918201910161375b565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451611e59959194509201919050614d38565b806006600060405160200180807f73686f756c64456d6974496e6974696174654368616e676500000000000000008152506018019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b60008282018381101561310257600080fd5b806004600060405160200180807f53595354454d5f41444452455353000000000000000000000000000000000000815250600e0190506040516020818303038152906040526040518082805190602001908083835b602083106138c15780518252601f1990920191602091820191016138a2565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054600160a060020a031916600160a060020a03959095169490941790935550505050565b600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310612dce5780518252601f199092019160209182019101612daf565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b600a6000826040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a715780518252601f199092019160209182019101613a52565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092909201600090812080546001810182559082529390209092018054600160a060020a031916600160a060020a039590951694909417909355505050565b60008083831115613af157600080fd5b5050900390565b6000808080805b613b076112b8565b831015613b4757613b1783610c71565b600160a060020a031686600160a060020a03161415613b3c5782935060019450613b47565b600190920191613aff565b8415611e54576001613b576112b8565b039150613b6382610c71565b9050600160a060020a03811615613b7e57613b7e848261457c565b600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310613bdf5780518252601f199092019160209182019101613bc0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050613c2857fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e6083398151915281840152815180820360110181526031909101918290528051600a94939192918291908401908083835b60208310613c9f5780518252601f199092019160209182019101613c80565b51815160001960209485036101000a81019182169119929092161790915260408051959093018590039094208752860196909652509290930160002080549350613ced929091508301614d9d565b50505050505050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038088168202602f8501528616026043830152825160378184030181526057909201928390528151613dc093859360029360009391929182918401908083835b60208310613d7d5780518252601f199092019160209182019101613d5e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493925050613ae19050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038089168202602f850152871602604383015282516037818403018152605790920192839052815160029360009392909182918401908083835b60208310613e415780518252601f199092019160209182019101613e22565b51815160001960209485036101000a0190811690199190911617905260408051949092018490039093208652858301969096525092840160009081209590955550508151600080516020614f0083398151915281830152606060020a600160a060020a038089168202602f84015287160260438201528251603781830301815260579091019283905280516002949391928291908401908083835b60208310613efb5780518252601f199092019160209182019101613edc565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250610b5491505057610b548383614659565b612c978160026000856040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310613d7d5780518252601f199092019160209182019101613d5e565b612f3481600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310613d7d5780518252601f199092019160209182019101613d5e565b600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612dce5780518252601f199092019160209182019101612daf565b6000808080805b61409f610c0f565b8310156140df576140af83611f82565b600160a060020a031686600160a060020a031614156140d457829350600194506140df565b600190920191614097565b8415611e545760016140ef610c0f565b0391506140fb82611f82565b9050600160a060020a03811615614116576141168482614892565b600a60006040516020018080600080516020614e0083398151915281525060100190506040516020818303038152906040526040518082805190602001908083835b602083106141775780518252601f199092019160209182019101614158565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506141c057fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e0083398151915281840152815180820360100181526030909101918290528051600a949391929182919084019080838360208310613c9f5780518252601f199092019160209182019101613c80565b80600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b6142a081613af8565b6142a981614030565b6142b2816148f3565b6113a581614b36565b60026000826040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b6020831061433c5780518252601f19909201916020918201910161431d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120548451600080516020614e8083398151915281880152600160a060020a038816606060020a02602b8201528551808203601f018152603f9091019586905280516001909201966002969395509093508291908401908083835b602083106143ee5780518252601f1990920191602091820191016143cf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160009081209590955550508051600080516020614e8083398151915281840152600160a060020a038516606060020a02602b8201528151808203601f018152603f90910191829052805160329460029490939182918401908083835b6020831061449e5780518252601f19909201916020918201910161447f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000205411156113a5576144f181614b36565b6113a581614bb8565b600060026000836040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b80600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b602083106145de5780518252601f1990920191602091820191016145bf565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002080549093508692508210905061462757fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a031602179055505050565b6000808080805b6146698661260f565b8310156146aa5761467a8684612705565b600160a060020a031687600160a060020a0316141561469f57829350600194506146aa565b600190920191614660565b8415613ced5760016146bb8761260f565b0391506146c88683612705565b9050600160a060020a038116156146e4576146e4868583614c3a565b600a6000876040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106147655780518252601f199092019160209182019101614746565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506147ae57fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e2083398151915281840152606060020a600160a060020a038b1602602a8201528151601e818303018152603e909101918290528051600a94939192918291908401908083835b6020831061483a5780518252601f19909201916020918201910161481b565b51815160001960209485036101000a81019182169119929092161790915260408051959093018590039094208752860196909652509290930160002080549350614888929091508301614d9d565b5050505050505050565b80600a60006040516020018080600080516020614e008339815191528152506010019050604051602081830303815290604052604051808280519060200190808383602083106145de5780518252601f1990920191602091820191016145bf565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106149765780518252601f199092019160209182019101614957565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000205490506149d860016130456149d0846117bc6122d3565b611e7b61233b565b600260008460405160200180807f72656c65617365426c6f636b0000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310614a6b5780518252601f199092019160209182019101614a4c565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050600582119050611e59578060010160026000846040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612d185780518252601f199092019160209182019101612cf9565b600060026000836040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b80600a6000856040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310614cbc5780518252601f199092019160209182019101614c9d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935086925082109050614d0557fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550505050565b828054828255906000526020600020908101928215614d8d579160200282015b82811115614d8d5782518254600160a060020a031916600160a060020a03909116178255602090920191600190910190614d58565b50614d99929150614dc1565b5090565b815481835581811115610b5457600083815260209020610b54918101908301614de5565b610c0c91905b80821115614d99578054600160a060020a0319168155600101614dc7565b610c0c91905b80821115614d995760008155600101614deb56006a61696c656456616c696461746f72730000000000000000000000000000000064656c656761746f727300000000000000000000000000000000000000000000626c6f636b436f756e746572000000000000000000000000000000000000000070656e64696e6756616c696461746f7273000000000000000000000000000000737472696b6552657365740000000000000000000000000000000000000000007374616b65416d6f756e74000000000000000000000000000000000000000000746f74616c5374616b65416d6f756e740000000000000000000000000000000063757272656e7456616c696461746f727300000000000000000000000000000064656c656761746564416d6f756e740000000000000000000000000000000000737472696b65436f756e74000000000000000000000000000000000000000000a165627a7a723058209d74b91c90190013a151838806ecea7afea1f8d3ad310a593aa328c9b7f6ad770029

Deployed ByteCode

0x6080604052600436106102f25763ffffffff60e060020a6000350416630300fc3581146102ff57806308c90076146103265780630fe9d28e1461033b5780631043ca281461036f57806310855269146103d757806310f606e7146103f857806314bfb5271461040d57806321429e6014610442578063256f9193146104695780632a807f151461047e5780632bec36d2146104935780632e0f2625146104a85780632e1a7d4d146104bd578063392e53cd146104d55780633a4b66f1146104ea57806340c9cdeb146104f257806355460f811461050757806356a3b5fa1461051f57806357aeefc5146105345780635c19a95c1461054c5780635ccee1de14610560578063651d8c22146105755780636a28f12f1461058a5780636bdf1d5a146106475780636c376cc51461065c5780636eae5b1114610671578063714897df1461068657806372e81e321461069b57806375286211146106b057806376bd510f146106c55780637b1e52a5146106da5780637d8f7a61146106fb5780637e2bf1201461071c57806385cd8464146107315780638615b171146107525780638bbc1e6b146107675780638d0680431461077c5780638d23fc61146107915780638d4e4083146107b25780638da873f8146107c757806392b391f3146107df578063932781d6146107f457806393b4e25e1461080957806394409a561461081e5780639f77dc3014610833578063a0e1192914610854578063a2cde6091461087b578063a652492314610890578063a82f255b146108a5578063af295181146108ba578063b7ab4db5146108cf578063bf135267146108e4578063c4d66de814610905578063c98517c514610926578063cb1c2b5c1461093b578063d2166ce914610950578063ddb3f48714610971578063e9fbe9d414610992578063eb431b6a146109a7578063ec15a5e6146109cb578063ee19a7fc146109e0578063ef7b6d8914610a01578063f3fef3a314610a16578063facd743b14610a3a578063fb64aac114610a5b578063fe35505b14610a7c575b6102fd333433610a91565b005b34801561030b57600080fd5b50610314610b59565b60408051918252519081900360200190f35b34801561033257600080fd5b50610314610c0f565b34801561034757600080fd5b50610353600435610c71565b60408051600160a060020a039092168252519081900360200190f35b34801561037b57600080fd5b50610387600435610d38565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103c35781810151838201526020016103ab565b505050509050019250505060405180910390f35b3480156103e357600080fd5b506102fd600160a060020a0360043516610e73565b34801561040457600080fd5b50610314611192565b34801561041957600080fd5b5061042e600160a060020a036004351661119e565b604080519115158252519081900360200190f35b34801561044e57600080fd5b50610314600160a060020a03600435811690602435166111ef565b34801561047557600080fd5b506103146112b3565b34801561048a57600080fd5b506103146112b8565b34801561049f57600080fd5b5061031461131a565b3480156104b457600080fd5b5061031461138e565b3480156104c957600080fd5b506102fd60043561139a565b3480156104e157600080fd5b5061042e6113a8565b6102fd611460565b3480156104fe57600080fd5b5061031461146d565b34801561051357600080fd5b506102fd6004356114cf565b34801561052b57600080fd5b50610314611516565b34801561054057600080fd5b50610353600435611524565b6102fd600160a060020a0360043516611586565b34801561056c57600080fd5b50610387611591565b34801561058157600080fd5b5061038761169a565b34801561059657600080fd5b506105ae600160a060020a03600435166024356116fc565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156105f25781810151838201526020016105da565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610631578181015183820152602001610619565b5050505090500194505050505060405180910390f35b34801561065357600080fd5b506103146117fa565b34801561066857600080fd5b506102fd6117ff565b34801561067d57600080fd5b506102fd61182f565b34801561069257600080fd5b50610314611868565b3480156106a757600080fd5b5061031461186d565b3480156106bc57600080fd5b506102fd611873565b3480156106d157600080fd5b506103146119ec565b3480156106e657600080fd5b50610314600160a060020a03600435166119f1565b34801561070757600080fd5b50610314600160a060020a0360043516611ab5565b34801561072857600080fd5b50610314611b37565b34801561073d57600080fd5b506102fd600160a060020a0360043516611b3d565b34801561075e57600080fd5b50610314611e5d565b34801561077357600080fd5b50610314611e62565b34801561078857600080fd5b50610314611e67565b34801561079d57600080fd5b50610387600160a060020a0360043516611e8c565b3480156107be57600080fd5b5061042e611f0e565b3480156107d357600080fd5b50610353600435611f82565b3480156107eb57600080fd5b50610314611fe4565b34801561080057600080fd5b50610314611ff0565b34801561081557600080fd5b506102fd612064565b34801561082a57600080fd5b50610314612127565b34801561083f57600080fd5b50610314600160a060020a0360043516612189565b34801561086057600080fd5b5061042e600160a060020a036004358116906024351661221d565b34801561088757600080fd5b50610387612271565b34801561089c57600080fd5b506103146122d3565b3480156108b157600080fd5b506103876122d9565b3480156108c657600080fd5b5061031461233b565b3480156108db57600080fd5b506103876123af565b3480156108f057600080fd5b50610314600160a060020a03600435166123b9565b34801561091157600080fd5b506102fd600160a060020a036004351661243b565b34801561093257600080fd5b50610314612571565b34801561094757600080fd5b5061031461257f565b34801561095c57600080fd5b50610314600160a060020a036004351661258d565b34801561097d57600080fd5b50610314600160a060020a036004351661260f565b34801561099e57600080fd5b50610314612691565b3480156109b357600080fd5b50610353600160a060020a0360043516602435612705565b3480156109d757600080fd5b506103536127ed565b3480156109ec57600080fd5b50610314600160a060020a03600435166128ab565b348015610a0d57600080fd5b5061042e61293f565b348015610a2257600080fd5b506102fd600160a060020a03600435166024356129b3565b348015610a4657600080fd5b5061042e600160a060020a03600435166129be565b348015610a6757600080fd5b5061042e600160a060020a0360043516612a04565b348015610a8857600080fd5b50610314612a4a565b600160a060020a0383161515610aa657600080fd5b811515610ab257600080fd5b600160a060020a0381161515610ac757600080fd5b610ad2838284612a58565b610adc8183612c13565b610ae4612a4a565b610aed826123b9565b1115610af857600080fd5b610b00611516565b610b09826123b9565b10158015610b1d5750610b1b81612a04565b155b15610b3d57610b2b81612d5a565b610b3d81670214e8348c4f0000612e3d565b610b46816129be565b15610b5457610b5482612ed0565b505050565b60006002600060405160200180807f6c617374536e617073686f7454616b656e4174426c6f636b000000000000000081525060180190506040516020818303038152906040526040518082805190602001908083835b60208310610bce5780518252601f199092019160209182019101610baf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b90565b6000600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310610cd45780518252601f199092019160209182019101610cb5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050610d1d57fe5b600091825260209091200154600160a060020a031692915050565b6060600a60008360405160200180807f736e617073686f74000000000000000000000000000000000000000000000000815250600801828152602001807f61646472657373657300000000000000000000000000000000000000000000008152506009019150506040516020818303038152906040526040518082805190602001908083835b60208310610ddd5780518252601f199092019160209182019101610dbe565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015610e6757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610e49575b50505050509050919050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b60208310610ee65780518252601f199092019160209182019101610ec7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031633149250610f3791505057600080fd5b600160a060020a0381161515610f4c57600080fd5b6006600060405160200180807f77617350726f787953746f72616765536574000000000000000000000000000081525060120190506040516020818303038152906040526040518082805190602001908083835b60208310610fbf5780518252601f199092019160209182019101610fa0565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1615925061100991505057600080fd5b806004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b6020831061107d5780518252601f19909201916020918201910161105e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160009081208054600160a060020a031916600160a060020a039790971696909617909555505080517f77617350726f787953746f7261676553657400000000000000000000000000008184015281516012818303018152603290910191829052805160019460069490939182918401908083835b602083106111455780518252601f199092019160209182019101611126565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b670214e8348c4f000090565b6000805b6111aa610c0f565b8110156111e4576111ba81611f82565b600160a060020a031683600160a060020a031614156111dc57600191506111e9565b6001016111a2565b600091505b50919050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038087168202602f85015285160260438301528251603781840301815260579092019283905281516000936002938593909282918401908083835b602083106112715780518252601f199092019160209182019101611252565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020549695505050505050565b600081565b6000600a60006040516020018080600080516020614e60833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f01905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b670de0b6b3a764000081565b6113a5338233612fd6565b50565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b6020831061141d5780518252601f1990920191602091820191016113fe565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff16949350505050565b61146b333433610a91565b565b6000600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6114d8336129be565b15156114e357600080fd5b670de0b6b3a76400008111156114f857600080fd5b611500611192565b81101561150c57600080fd5b6113a53382612e3d565b69010f0cf064dd5920000090565b6000600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310610cd45780518252601f199092019160209182019101610cb5565b6113a5333483610a91565b6060600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f0190506040516020818303038152906040526040518082805190602001908083835b602083106116065780518252601f1990920191602091820191016115e7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000208054845181870281018701909552808552939490939250840190508282801561169057602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611672575b5050505050905090565b6060600a60006040516020018080600080516020614e008339815191528152506010019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b606080606080600080600061171089611e8c565b9450845160405190808252806020026020018201604052801561173d578160200160208202803883390190505b50935061175961174b611516565b6117548b6123b9565b6130f0565b92505b84518210156117eb576117786117728a84612705565b8a6111ef565b90506117c8670de0b6b3a76400006117b06117928c612189565b670de0b6b3a7640000036117bc876117b08e8863ffffffff61310916565b9063ffffffff61313716565b9063ffffffff61310916565b84838151811015156117d657fe5b6020908102909101015260019091019061175c565b50929791965090945050505050565b603281565b611808336129be565b151561181357600080fd5b61181c3361119e565b1561182657600080fd5b61146b3361315a565b6118383361119e565b151561184357600080fd5b61184b61233b565b611854336128ab565b111561185f57600080fd5b61146b3361316c565b601581565b610bb881565b6004600060405160200180807f53595354454d5f41444452455353000000000000000000000000000000000000815250600e0190506040516020818303038152906040526040518082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a03163314925061193791505057600080fd5b61193f611f0e565b1561194957600080fd5b600061195361131a565b11156119e257611969611964611591565b6131a8565b7f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d2763253611992612271565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156119ce5781810151838201526020016119b6565b505050509050019250505060405180910390a15b61146b60016132fb565b601590565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310611a745780518252601f199092019160209182019101611a55565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b600060026000836040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b61e10081565b6060611b476127ed565b600160a060020a031663f89d40866040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611b8457600080fd5b505af1158015611b98573d6000803e3d6000fd5b505050506040513d6020811015611bae57600080fd5b5051600160a060020a03163314611bc457600080fd5b611bcd8261336e565b611bd561349e565b15611e5957611be26127ed565b600160a060020a0316631986d3766040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c1f57600080fd5b505af1158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b5051600160a060020a031663bbac62c8611c61612271565b6040518263ffffffff1660e060020a0281526004018080602001828103825283818151815260200191508051906020019060200280838360005b83811015611cb3578181015183820152602001611c9b565b5050505090500192505050600060405180830381600087803b158015611cd857600080fd5b505af1158015611cec573d6000803e3d6000fd5b50505050611cf86134b0565b611d08611d03612271565b613621565b611d106122d9565b9050600081511115611d2557611d2581613706565b6000611d2f61131a565b1115611d7357611d3f60006132fb565b611d4960016137c8565b6040517fad8a61077dff62d25ea1bf7cf1af88e1b48075c3d497d494ac9b129b73b0d37c90600090a15b611d7b6127ed565b600160a060020a031663f89d40866040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611db857600080fd5b505af1158015611dcc573d6000803e3d6000fd5b505050506040513d6020811015611de257600080fd5b5051604080517fb1f0c8e10000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163b1f0c8e19160048082019260009290919082900301818387803b158015611e4057600080fd5b505af1158015611e54573d6000803e3d6000fd5b505050505b5050565b600581565b600090565b6000611e876001611e7b60026117b061146d565b9063ffffffff61383b16565b905090565b6060600a6000836040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310610ddd5780518252601f199092019160209182019101610dbe565b60006006600060405160200180807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0190506040516020818303038152906040526040518082805190602001908083836020831061141d5780518252601f1990920191602091820191016113fe565b6000600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610cd45780518252601f199092019160209182019101610cb5565b670214e8348c4f000081565b60006002600060405160200180807f63757272656e744379636c655374617274426c6f636b00000000000000000000815250601601905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b61206d336129be565b151561207857600080fd5b61208061293f565b151561208b57600080fd5b600061209561131a565b1161209f57600080fd5b6000194301407f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c896120ce611591565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561210a5781810151838201526020016120f2565b505050509050019250505060405180910390a261146b60006137c8565b6000600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600260008360405160200180807f76616c696461746f724665650000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6000805b61222a8461260f565b8110156122655761223b8482612705565b600160a060020a031683600160a060020a0316141561225d576001915061226a565b600101612221565b600091505b5092915050565b6060600a60006040516020018080600080516020614ee08339815191528152506011019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b61e10090565b6060600a60006040516020018080600080516020614e608339815191528152506011019050604051602081830303815290604052604051808280519060200190808383602083106116065780518252601f1990920191602091820191016115e7565b60006002600060405160200180807f63757272656e744379636c65456e64426c6f636b000000000000000000000000815250601401905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6060611e87612271565b600060026000836040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106124ae5780518252601f19909201916020918201910161248f565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506124ff91505057600080fd5b6125076113a8565b1561251157600080fd5b61252e73fffffffffffffffffffffffffffffffffffffffe61384d565b6125366134b0565b600160a060020a03811615156125545761254f3361391d565b61255d565b61255d8161391d565b61256760016132fb565b6113a5600161397d565b69d3c21bcecceda100000081565b69010f0cf064dd5920000081565b600060026000836040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b6000600a6000836040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b60006002600060405160200180807f6e657874536e617073686f744964000000000000000000000000000000000000815250600e01905060405160208183030381529060405260405180828051906020019080838360208310610bce5780518252601f199092019160209182019101610baf565b6000600a6000846040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106127885780518252601f199092019160209182019101612769565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506127d157fe5b600091825260209091200154600160a060020a03169392505050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b602083106128625780518252601f199092019160209182019101612843565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000600260008360405160200180807f72656c65617365426c6f636b0000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310611a745780518252601f199092019160209182019101611a55565b60006006600060405160200180807f73686f756c64456d6974496e6974696174654368616e6765000000000000000081525060180190506040516020818303038152906040526040518082805190602001908083836020831061141d5780518252601f1990920191602091820191016113fe565b611e59338284612fd6565b6000805b6129ca61146d565b8110156111e4576129da81611524565b600160a060020a031683600160a060020a031614156129fc57600191506111e9565b6001016129c2565b6000805b612a106112b8565b8110156111e457612a2081610c71565b600160a060020a031683600160a060020a03161415612a4257600191506111e9565b600101612a08565b69d3c21bcecceda100000090565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038088168202602f8501528616026043830152825160378184030181526057909201928390528151612b2293859360029360009391929182918401908083835b60208310612adf5780518252601f199092019160209182019101612ac0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020549392505061383b9050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038089168202602f850152871602604383015282516037818403018152605790920192839052815160029360009392909182918401908083835b60208310612ba35780518252601f199092019160209182019101612b84565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050600160a060020a0382811690841614801590612c045750612c02828461221d565b155b15610b5457610b5483836139f0565b612c978160026000856040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612adf5780518252601f199092019160209182019101612ac0565b60026000846040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310612d185780518252601f199092019160209182019101612cf9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b612d638161119e565b15612d6d57600080fd5b600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310612dce5780518252601f199092019160209182019101612daf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092909201600090812080546001810182559082529390209092018054600160a060020a031916600160a060020a0394909416939093179092555050565b80600260008460405160200180807f76616c696461746f724665650000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612d185780518252601f199092019160209182019101612cf9565b612f3481600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612adf5780518252601f199092019160209182019101612ac0565b600260006040516020018080600080516020614ec083398151915281525060100190506040516020818303038152906040526040518082805190602001908083835b60208310612f955780518252601f199092019160209182019101612f76565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b6000600160a060020a0382161515612fed57600080fd5b60008311612ffa57600080fd5b613003826123b9565b83111561300f57600080fd5b61301984836111ef565b83111561302557600080fd5b61302e826129be565b9050613038611516565b61305184613045856123b9565b9063ffffffff613ae116565b10801561305b5750805b1561306e5761306982613af8565b6130ea565b613079848385613cf6565b6130838284613f48565b80156130925761309283613fcc565b61309a611516565b6130a3836123b9565b10156130b2576130b282613af8565b604051600160a060020a0385169084156108fc029085906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b505b50505050565b6000818310156131005781613102565b825b9392505050565b60008083151561311c576000915061226a565b5082820282848281151561312c57fe5b041461310257600080fd5b60008080831161314657600080fd5b828481151561315157fe5b04949350505050565b61316381613af8565b6113a581614030565b61317581614090565b61317d611516565b613186826123b9565b1015801561319a575061319881612a04565b155b156113a5576113a581612d5a565b60008080805b8451831015613242576131d785848151811015156131c857fe5b906020019060200201516123b9565b915081840193506131fe85848151811015156131ef57fe5b90602001906020020151612189565b9050613208611192565b81101561323757613237858481518110151561322057fe5b90602001906020020151613232611192565b612e3d565b6001909201916131ae565b61324b84614236565b84600a60006040516020018080600080516020614ee083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b602083106132ad5780518252601f19909201916020918201910161328e565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451611e54959194509201919050614d38565b806006600060405160200180807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b60026000826040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106133ef5780518252601f1990920191602091820191016133d0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120548451600080516020614e4083398151915281880152600160a060020a038816606060020a02602c8201528551808203880181529086019586905280516001909201966002969395509093508291848201918190849084908310612f955780518252601f199092019160209182019101612f76565b60006134a861233b565b431015905090565b436002600060405160200180807f63757272656e744379636c655374617274426c6f636b0000000000000000000081525060160190506040516020818303038152906040526040518082805190602001908083835b602083106135245780518252601f199092019160209182019101613505565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555061356c91506122d39050565b43016002600060405160200180807f63757272656e744379636c65456e64426c6f636b00000000000000000000000081525060140190506040516020818303038152906040526040518082805190602001908083835b602083106135e15780518252601f1990920191602091820191016135c2565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050565b60008061363d6127106117b085516117b0610bb86117bc6122d3565b9150600090505b8251811015610b54578161366e848381518110151561365f57fe5b90602001906020020151611ab5565b101561369957613694838281518110151561368557fe5b90602001906020020151614297565b6136de565b6136b983828151811015156136aa57fe5b906020019060200201516119f1565b156136de576136de83828151811015156136cf57fe5b906020019060200201516142bb565b6136fe83828151811015156136ef57fe5b906020019060200201516144fa565b600101613644565b80600a600060405160200180807f6e657756616c696461746f725365740000000000000000000000000000000000815250600f0190506040516020818303038152906040526040518082805190602001908083835b6020831061377a5780518252601f19909201916020918201910161375b565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451611e59959194509201919050614d38565b806006600060405160200180807f73686f756c64456d6974496e6974696174654368616e676500000000000000008152506018019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b60008282018381101561310257600080fd5b806004600060405160200180807f53595354454d5f41444452455353000000000000000000000000000000000000815250600e0190506040516020818303038152906040526040518082805190602001908083835b602083106138c15780518252601f1990920191602091820191016138a2565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054600160a060020a031916600160a060020a03959095169490941790935550505050565b600a60006040516020018080600080516020614ee0833981519152815250601101905060405160208183030381529060405260405180828051906020019080838360208310612dce5780518252601f199092019160209182019101612daf565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d019050604051602081830303815290604052604051808280519060200190808383602083106111455780518252601f199092019160209182019101611126565b600a6000826040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310613a715780518252601f199092019160209182019101613a52565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092909201600090812080546001810182559082529390209092018054600160a060020a031916600160a060020a039590951694909417909355505050565b60008083831115613af157600080fd5b5050900390565b6000808080805b613b076112b8565b831015613b4757613b1783610c71565b600160a060020a031686600160a060020a03161415613b3c5782935060019450613b47565b600190920191613aff565b8415611e54576001613b576112b8565b039150613b6382610c71565b9050600160a060020a03811615613b7e57613b7e848261457c565b600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b60208310613bdf5780518252601f199092019160209182019101613bc0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050613c2857fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e6083398151915281840152815180820360110181526031909101918290528051600a94939192918291908401908083835b60208310613c9f5780518252601f199092019160209182019101613c80565b51815160001960209485036101000a81019182169119929092161790915260408051959093018590039094208752860196909652509290930160002080549350613ced929091508301614d9d565b50505050505050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038088168202602f8501528616026043830152825160378184030181526057909201928390528151613dc093859360029360009391929182918401908083835b60208310613d7d5780518252601f199092019160209182019101613d5e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493925050613ae19050565b60408051600080516020614f00833981519152602080830191909152606060020a600160a060020a038089168202602f850152871602604383015282516037818403018152605790920192839052815160029360009392909182918401908083835b60208310613e415780518252601f199092019160209182019101613e22565b51815160001960209485036101000a0190811690199190911617905260408051949092018490039093208652858301969096525092840160009081209590955550508151600080516020614f0083398151915281830152606060020a600160a060020a038089168202602f84015287160260438201528251603781830301815260579091019283905280516002949391928291908401908083835b60208310613efb5780518252601f199092019160209182019101613edc565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250610b5491505057610b548383614659565b612c978160026000856040516020018080600080516020614ea0833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310613d7d5780518252601f199092019160209182019101613d5e565b612f3481600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310613d7d5780518252601f199092019160209182019101613d5e565b600a60006040516020018080600080516020614e00833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612dce5780518252601f199092019160209182019101612daf565b6000808080805b61409f610c0f565b8310156140df576140af83611f82565b600160a060020a031686600160a060020a031614156140d457829350600194506140df565b600190920191614097565b8415611e545760016140ef610c0f565b0391506140fb82611f82565b9050600160a060020a03811615614116576141168482614892565b600a60006040516020018080600080516020614e0083398151915281525060100190506040516020818303038152906040526040518082805190602001908083835b602083106141775780518252601f199092019160209182019101614158565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506141c057fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e0083398151915281840152815180820360100181526030909101918290528051600a949391929182919084019080838360208310613c9f5780518252601f199092019160209182019101613c80565b80600260006040516020018080600080516020614ec0833981519152815250601001905060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b6142a081613af8565b6142a981614030565b6142b2816148f3565b6113a581614b36565b60026000826040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b6020831061433c5780518252601f19909201916020918201910161431d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120548451600080516020614e8083398151915281880152600160a060020a038816606060020a02602b8201528551808203601f018152603f9091019586905280516001909201966002969395509093508291908401908083835b602083106143ee5780518252601f1990920191602091820191016143cf565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160009081209590955550508051600080516020614e8083398151915281840152600160a060020a038516606060020a02602b8201528151808203601f018152603f90910191829052805160329460029490939182918401908083835b6020831061449e5780518252601f19909201916020918201910161447f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000205411156113a5576144f181614b36565b6113a581614bb8565b600060026000836040516020018080600080516020614e40833981519152815250600c0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b80600a60006040516020018080600080516020614e6083398151915281525060110190506040516020818303038152906040526040518082805190602001908083835b602083106145de5780518252601f1990920191602091820191016145bf565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002080549093508692508210905061462757fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a031602179055505050565b6000808080805b6146698661260f565b8310156146aa5761467a8684612705565b600160a060020a031687600160a060020a0316141561469f57829350600194506146aa565b600190920191614660565b8415613ced5760016146bb8761260f565b0391506146c88683612705565b9050600160a060020a038116156146e4576146e4868583614c3a565b600a6000876040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106147655780518252601f199092019160209182019101614746565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350859250821090506147ae57fe5b600091825260208083209091018054600160a060020a031916905560408051600080516020614e2083398151915281840152606060020a600160a060020a038b1602602a8201528151601e818303018152603e909101918290528051600a94939192918291908401908083835b6020831061483a5780518252601f19909201916020918201910161481b565b51815160001960209485036101000a81019182169119929092161790915260408051959093018590039094208752860196909652509290930160002080549350614888929091508301614d9d565b5050505050505050565b80600a60006040516020018080600080516020614e008339815191528152506010019050604051602081830303815290604052604051808280519060200190808383602083106145de5780518252601f1990920191602091820191016145bf565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b602083106149765780518252601f199092019160209182019101614957565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000205490506149d860016130456149d0846117bc6122d3565b611e7b61233b565b600260008460405160200180807f72656c65617365426c6f636b0000000000000000000000000000000000000000815250600c0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310614a6b5780518252601f199092019160209182019101614a4c565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050600582119050611e59578060010160026000846040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612d185780518252601f199092019160209182019101612cf9565b600060026000836040516020018080600080516020614e80833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b600060026000836040516020018080600080516020614f20833981519152815250600b0182600160a060020a0316600160a060020a0316606060020a02815260140191505060405160208183030381529060405260405180828051906020019080838360208310612f955780518252601f199092019160209182019101612f76565b80600a6000856040516020018080600080516020614e20833981519152815250600a0182600160a060020a0316600160a060020a0316606060020a0281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310614cbc5780518252601f199092019160209182019101614c9d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935086925082109050614d0557fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550505050565b828054828255906000526020600020908101928215614d8d579160200282015b82811115614d8d5782518254600160a060020a031916600160a060020a03909116178255602090920191600190910190614d58565b50614d99929150614dc1565b5090565b815481835581811115610b5457600083815260209020610b54918101908301614de5565b610c0c91905b80821115614d99578054600160a060020a0319168155600101614dc7565b610c0c91905b80821115614d995760008155600101614deb56006a61696c656456616c696461746f72730000000000000000000000000000000064656c656761746f727300000000000000000000000000000000000000000000626c6f636b436f756e746572000000000000000000000000000000000000000070656e64696e6756616c696461746f7273000000000000000000000000000000737472696b6552657365740000000000000000000000000000000000000000007374616b65416d6f756e74000000000000000000000000000000000000000000746f74616c5374616b65416d6f756e740000000000000000000000000000000063757272656e7456616c696461746f727300000000000000000000000000000064656c656761746564416d6f756e740000000000000000000000000000000000737472696b65436f756e74000000000000000000000000000000000000000000a165627a7a723058209d74b91c90190013a151838806ecea7afea1f8d3ad310a593aa328c9b7f6ad770029