- We're indexing this chain right now. Some of the counts may be inaccurate.
Contract Address Details
contract

0x5489443C7Fa9F408683273bF06f67dDB380D0960

Sponsored: 

Overview

GOLDX Balance

0 GOLDX

GOLDX Value

$0.00

Token Holdings

Fetching tokens...

More Info

Private Name Tags

Last Balance Update

Blocks Validated

Sponsored

Contract name:
Voting




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




Optimization runs
200
EVM Version
default




Verified at
2023-10-02T01:57:01.019585Z

Contract source code

// File: contracts/abstracts/VotingBase.sol

pragma solidity ^0.4.24;

/**
 * @title Interface to be implemented by voting contract
 * @author LiorRabin
 * @dev abstract contract
 */
contract VotingBase {

  /**
  * @dev Possible states of quorum
  * @param InProgress - state while a ballot has not been finalized yet
  * @param Accepted - state after finalizing the ballot and majority have voted ActionChoices.Accept
  * @param Rejected - state after finalizing the ballot and majority have voted ActionChoices.Reject
  */
  enum QuorumStates {
    Invalid,
    InProgress,
    Accepted,
    Rejected
  }

  /**
  * @dev Possible choices for a ballot
  */
  enum ActionChoices {
    Invalid,
    Accept,
    Reject
  }

  /**
  * @dev This event will be emitted every time a new ballot is created
  * @param id ballot id
  * @param creator address of ballot creator
  */
  event BallotCreated(uint256 indexed id, address indexed creator);

  /**
  * @dev This event will be emitted when a ballot if finalized
  * @param id ballot id
  */
  event BallotFinalized(uint256 indexed id);

  /**
  * @dev This event will be emitted on each vote
  * @param id ballot id
  * @param decision voter decision (see VotingBase.ActionChoices)
  * @param voter address of the voter
  */
  event Vote(uint256 indexed id, uint256 decision, address indexed voter);

  /**
  * @dev Function to be called when voting on a ballot
  * @param _id ballot id
  * @param _choice voter decision on the ballot (see VotingBase.ActionChoices)
  */
  function vote(uint256 _id, uint256 _choice) 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/interfaces/IConsensus.sol

pragma solidity ^0.4.24;

interface IConsensus {
    function currentValidatorsLength() external view returns(uint256);
    function currentValidatorsAtPosition(uint256 _p) external view returns(address);
    function getCycleDurationBlocks() external view returns(uint256);
    function getCurrentCycleEndBlock() external view returns(uint256);
    function cycle(address _validator) external;
    function isValidator(address _address) external view returns(bool);
    function getDelegatorsForRewardDistribution(address _validator, uint256 _rewardAmount) external view returns(address[], uint256[]);
    function isFinalized() external view returns(bool);
    function stakeAmount(address _address) external view returns(uint256);
    function totalStakeAmount() external view returns(uint256);
}

// 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: contracts/VotingUtils.sol

pragma solidity ^0.4.24;





/**
* @title Voting utility contract
* @author LiorRabin
*/
contract VotingUtils is EternalStorage, VotingBase {
  using SafeMath for uint256;

  uint256 public constant DECIMALS = 10 ** 18;
  uint256 public constant MAX_LIMIT_OF_BALLOTS = 100;
  uint256 public constant MIN_BALLOT_DURATION_CYCLES = 2;
  uint256 public constant MAX_BALLOT_DURATION_CYCLES = 14;
  uint256 public constant MINIMUM_TURNOUT_BP = 2000; //20%

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

  /**
  * @dev This modifier verifies the duration of the ballot is valid
  */
  modifier onlyValidDuration(uint256 _startAfterNumberOfCycles, uint256 _cyclesDuration) {
    require(_startAfterNumberOfCycles > 0);
    require(_cyclesDuration > 0);
    require(_cyclesDuration >= getMinBallotDurationCycles());
    require(_cyclesDuration <= getMaxBallotDurationCycles());
    _;
  }

  /**
  * @dev This modifier verifies an address is valid for voting
  */
  modifier onlyValidVotingKey(address _address) {
    require(isValidVotingKey(_address));
    _;
  }

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

  bytes32 internal constant OWNER = keccak256(abi.encodePacked("owner"));
  bytes32 internal constant NEXT_BALLOT_ID = keccak256(abi.encodePacked("nextBallotId"));
  bytes32 internal constant ACTIVE_BALLOTS = keccak256(abi.encodePacked("activeBallots"));
  bytes32 internal constant PROXY_STORAGE = keccak256(abi.encodePacked("proxyStorage"));

  /**
  * @dev Function to check if a contract type is a valid network contract
  * @param _contractType contract type to check (See ProxyStorage.ContractTypes)
  */
  function validContractType(uint256 _contractType) public view returns(bool) {
    return ProxyStorage(getProxyStorage()).isValidContractType(_contractType);
  }

  /**
  * @dev This function checks if an address is valid for voting (is a validator)
  * @param _address the address to check if valid for voting
  */
  function isValidVotingKey(address _address) public view returns(bool) {
    bool valid = false;
    IConsensus consensus = IConsensus(ProxyStorage(getProxyStorage()).getConsensus());
    for (uint256 i; i < consensus.currentValidatorsLength(); i++) {
      address validator = consensus.currentValidatorsAtPosition(i);
      if (validator == _address) {
        valid = true;
      }
    }
    return valid;
  }

  /**
  * @dev Function to get the number of "open" (active) ballots each validator (someone with voting rights) can have at the same time
  */
  function getBallotLimitPerValidator() public view returns(uint256) {
    uint256 validatorsCount = getTotalNumberOfValidators();
    if (validatorsCount == 0) {
      return MAX_LIMIT_OF_BALLOTS;
    }
    uint256 limit = MAX_LIMIT_OF_BALLOTS.div(validatorsCount);
    if (limit == 0) {
      limit = 1;
    }
    return limit;
  }

  /**
  * @dev Function used to check if a voting key has voted on a specific ballot
  * @param _id ballot id to get info of
  * @param _key voter key to get if voted already
  */
  function hasAlreadyVoted(uint256 _id, address _key) public view returns(bool) {
    if (_key == address(0)) {
      return false;
    }
    return getVoterChoice(_id, _key) != 0;
  }

  /**
  * @dev This function is used to check if a ballot can be finalized
  * @param _id ballot id to check
  */
  function canBeFinalized(uint256 _id) public view returns(bool) {
    if (_id >= getNextBallotId()) return false;
    if (getStartBlock(_id) > block.number) return false;
    if (getIsFinalized(_id)) return false;

    return block.number >= getEndBlock(_id);
  }

  function getProposedValue(uint256 _id) public view returns(address) {
    return addressStorage[keccak256(abi.encodePacked("votingState", _id, "proposedValue"))];
  }

  function _setProposedValue(uint256 _id, address _value) internal {
    addressStorage[keccak256(abi.encodePacked("votingState", _id, "proposedValue"))] = _value;
  }

  function getContractType(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "contractType"))];
  }

  function _setContractType(uint256 _id, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "contractType"))] = _value;
  }

  /**
  * @dev This function is used to create a ballot
  * @param _startAfterNumberOfCycles number of cycles after which the ballot should open for voting
  * @param _cyclesDuration number of cycles the ballot will remain open for voting
  * @param _description ballot text description
  */
  function _createBallot(uint256 _startAfterNumberOfCycles, uint256 _cyclesDuration, string _description) internal returns(uint256) {
    require(isInitialized());
    address creator = msg.sender;
    require(withinLimit(creator));
    uint256 ballotId = getNextBallotId();
    _setNextBallotId(ballotId.add(1));
    _setStartBlock(ballotId, _startAfterNumberOfCycles);
    _setEndBlock(ballotId, _cyclesDuration);
    _setIsFinalized(ballotId, false);
    _setQuorumState(ballotId, uint256(QuorumStates.InProgress));
    _setCreator(ballotId, creator);
    _setDescription(ballotId, _description);
    _setIndex(ballotId, activeBallotsLength());
    _setBelowTurnOut(ballotId, false);
    _activeBallotsAdd(ballotId);
    _increaseValidatorLimit(creator);
    emit BallotCreated(ballotId, creator);
    return ballotId;
  }

  function _finalize(uint256 _id) internal {
    if (!getFinalizeCalled(_id)) {
      _decreaseValidatorLimit(_id);
      _setFinalizeCalled(_id);
    }

    // check the turnout
    if (_checkTurnout(_id)) {
      if (getAccepted(_id) > getRejected(_id)) {
        if (_finalizeBallot(_id)) {
          _setQuorumState(_id, uint256(QuorumStates.Accepted));
        } else {
          return;
        }
      } else {
        _setQuorumState(_id, uint256(QuorumStates.Rejected));
      }
      _setBelowTurnOut(_id, false);
    } else {
      // didn't meet the turn out
      _setBelowTurnOut(_id, true);
      _setQuorumState(_id, uint256(QuorumStates.Rejected));
    }
    
    _deactivateBallot(_id);
    _setIsFinalized(_id, true);
    emit BallotFinalized(_id);
  }

  function _deactivateBallot(uint256 _id) internal {
    uint256 removedIndex = getIndex(_id);
    uint256 lastIndex = activeBallotsLength() - 1;
    uint256 lastBallotId = activeBallotsAtIndex(lastIndex);

    // Override the removed ballot with the last one.
    _activeBallotsSet(removedIndex, lastBallotId);

    // Update the index of the last validator.
    _setIndex(lastBallotId, removedIndex);
    _activeBallotsSet(lastIndex, 0);
    _activeBallotsDecreaseLength();
  }

  function _finalizeBallot(uint256 _id) internal returns(bool) {
    return ProxyStorage(getProxyStorage()).setContractAddress(getContractType(_id), getProposedValue(_id));
  }

  function isActiveBallot(uint256 _id) public view returns(bool) {
    return getStartBlock(_id) < block.number && block.number < getEndBlock(_id);
  }

  function getQuorumState(uint256 _id) external view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "quorumState"))];
  }

  function _setQuorumState(uint256 _id, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "quorumState"))] = _value;
  }

  function getNextBallotId() public view returns(uint256) {
    return uintStorage[NEXT_BALLOT_ID];
  }

  function _setNextBallotId(uint256 _id) internal {
    uintStorage[NEXT_BALLOT_ID] = _id;
  }

  /**
  * returns minimum number of cycles a ballot can be open before finalization
  */
  function getMinBallotDurationCycles() public pure returns(uint256) {
    return MIN_BALLOT_DURATION_CYCLES;
  }

  /**
  * returns maximum number of cycles a ballot can be open before finalization
  */
  function getMaxBallotDurationCycles() public pure returns(uint256) {
    return MAX_BALLOT_DURATION_CYCLES;
  }

  function getStartBlock(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "startBlock"))];
  }

  function _setStartBlock(uint256 _id, uint256 _startAfterNumberOfCycles) internal {
    IConsensus consensus = IConsensus(ProxyStorage(getProxyStorage()).getConsensus());
    uint256 cycleDurationBlocks = consensus.getCycleDurationBlocks();
    uint256 currentCycleEndBlock = consensus.getCurrentCycleEndBlock();
    uint256 startBlock = currentCycleEndBlock.add(_startAfterNumberOfCycles.mul(cycleDurationBlocks));
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "startBlock"))] = startBlock;
  }

  function getEndBlock(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "endBlock"))];
  }

  function _setEndBlock(uint256 _id, uint256 _cyclesDuration) internal {
    uint256 cycleDurationBlocks = IConsensus(ProxyStorage(getProxyStorage()).getConsensus()).getCycleDurationBlocks();
    uint256 startBlock = getStartBlock(_id);
    uint256 endBlock = startBlock.add(_cyclesDuration.mul(cycleDurationBlocks));
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "endBlock"))] = endBlock;
  }

  function getIsFinalized(uint256 _id) public view returns(bool) {
    return boolStorage[keccak256(abi.encodePacked("votingState", _id, "isFinalized"))];
  }

  function _setIsFinalized(uint256 _id, bool _value) internal {
    boolStorage[keccak256(abi.encodePacked("votingState", _id, "isFinalized"))] = _value;
  }

  function getBelowTurnOut(uint256 _id) public view returns(bool) {
    return boolStorage[keccak256(abi.encodePacked("votingState", _id, "belowTurnOut"))];
  }

  function _setBelowTurnOut(uint256 _id, bool _value) internal {
    boolStorage[keccak256(abi.encodePacked("votingState", _id, "belowTurnOut"))] = _value;
  }

  function getDescription(uint256 _id) public view returns(string) {
    return stringStorage[keccak256(abi.encodePacked("votingState", _id, "description"))];
  }

  function _setDescription(uint256 _id, string _value) internal {
    stringStorage[keccak256(abi.encodePacked("votingState", _id, "description"))] = _value;
  }

  function getCreator(uint256 _id) public view returns(address) {
    return addressStorage[keccak256(abi.encodePacked("votingState", _id, "creator"))];
  }

  function _setCreator(uint256 _id, address _value) internal {
    addressStorage[keccak256(abi.encodePacked("votingState", _id, "creator"))] = _value;
  }

  function getIndex(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "index"))];
  }

  function _setIndex(uint256 _id, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "index"))] = _value;
  }

  function activeBallots() public view returns(uint[]) {
    return uintArrayStorage[ACTIVE_BALLOTS];
  }

  function activeBallotsAtIndex(uint256 _index) public view returns(uint256) {
    return uintArrayStorage[ACTIVE_BALLOTS][_index];
  }

  function activeBallotsLength() public view returns(uint256) {
    return uintArrayStorage[ACTIVE_BALLOTS].length;
  }

  function _activeBallotsAdd(uint256 _id) internal {
    uintArrayStorage[ACTIVE_BALLOTS].push(_id);
  }

  function _activeBallotsDecreaseLength() internal {
    if (activeBallotsLength() > 0) {
      uintArrayStorage[ACTIVE_BALLOTS].length--;
    }
  }

  function _activeBallotsSet(uint256 _index, uint256 _id) internal {
    uintArrayStorage[ACTIVE_BALLOTS][_index] = _id;
  }

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

  function _setValidatorActiveBallots(address _key, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("validatorActiveBallots", _key))] = _value;
  }

  function _increaseValidatorLimit(address _key) internal {
    _setValidatorActiveBallots(_key, validatorActiveBallots(_key).add(1));
  }

  function _decreaseValidatorLimit(uint256 _id) internal {
    address key = getCreator(_id);
    uint256 ballotsCount = validatorActiveBallots(key);
    if (ballotsCount > 0) {
      _setValidatorActiveBallots(key, ballotsCount - 1);
    }
  }

  function getFinalizeCalled(uint256 _id) public view returns(bool) {
    return boolStorage[keccak256(abi.encodePacked("finalizeCalled", _id))];
  }

  function _setFinalizeCalled(uint256 _id) internal {
    boolStorage[keccak256(abi.encodePacked("finalizeCalled", _id))] = true;
  }

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

  function getTotalNumberOfValidators() internal view returns(uint256) {
    return IConsensus(ProxyStorage(getProxyStorage()).getConsensus()).currentValidatorsLength();
  }

  function getStake(address _key) internal view returns(uint256) {
    return IConsensus(ProxyStorage(getProxyStorage()).getConsensus()).stakeAmount(_key);
  }

  function _setVoterChoice(uint256 _id, address _key, uint256 _choice) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "voters", _key))] = _choice;
  }

  function getVoterChoice(uint256 _id, address _key) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "voters", _key))];
  }

  function withinLimit(address _key) internal view returns(bool) {
    return validatorActiveBallots(_key) < getBallotLimitPerValidator();
  }

  function getAccepted(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "accepted"))];
  }

  function _setAccepted(uint256 _id, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "accepted"))] = _value;
  }

  function getRejected(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "rejected"))];
  }

  function _setRejected(uint256 _id, uint256 _value) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "rejected"))] = _value;
  }

  function getTotalStake(uint256 _id) public view returns(uint256) {
    return uintStorage[keccak256(abi.encodePacked("votingState", _id, "totalStake"))];
  }

  function _setTotalStake(uint256 _id) internal {
    uintStorage[keccak256(abi.encodePacked("votingState", _id, "totalStake"))] = IConsensus(ProxyStorage(getProxyStorage()).getConsensus()).totalStakeAmount();
  }

  function _checkTurnout(uint256 _id) internal view returns(bool) {
    uint256 stake = getTotalStake(_id);
    uint256 minTurnout = stake * MINIMUM_TURNOUT_BP / 10000;

    uint256 totalVotedFor = getAccepted(_id);

    return totalVotedFor > minTurnout;
  }
}

// File: contracts/Voting.sol

pragma solidity ^0.4.24;


/**
* @title Contract handling vote to change implementations network contracts
* @author LiorRabin
*/
contract Voting is VotingUtils {
  /**
  * @dev Function to be called on contract initialization
  */
  function initialize() external onlyOwner {
    require(!isInitialized());
    setInitialized(true);
  }

  /**
  * @dev Function to create a new ballot
  * @param _startAfterNumberOfCycles number of cycles after which the ballot should open for voting
  * @param _cyclesDuration number of cycles the ballot will remain open for voting
  * @param _contractType contract type to change its address (See ProxyStorage.ContractTypes)
  * @param _proposedValue proposed address for the contract type
  * @param _description ballot text description
  */
  function newBallot(uint256 _startAfterNumberOfCycles, uint256 _cyclesDuration, uint256 _contractType, address _proposedValue, string _description) external onlyValidVotingKey(msg.sender) onlyValidDuration(_startAfterNumberOfCycles, _cyclesDuration) returns(uint256) {
    require(_proposedValue != address(0));
    require(validContractType(_contractType));
    uint256 ballotId = _createBallot(_startAfterNumberOfCycles, _cyclesDuration, _description);
    _setProposedValue(ballotId, _proposedValue);
    _setContractType(ballotId, _contractType);
    return ballotId;
  }

  /**
  * @dev Function to get specific ballot info along with voters involvment on it
  * @param _id ballot id to get info of
  * @param _key voter key to get if voted already
  */
  function getBallotInfo(uint256 _id, address _key) external view returns(uint256 startBlock, uint256 endBlock, bool isFinalized, address proposedValue, uint256 contractType, address creator, string description, bool canBeFinalizedNow, bool alreadyVoted, bool belowTurnOut, uint256 accepted, uint256 rejected, uint256 totalStake) {
    startBlock = getStartBlock(_id);
    endBlock = getEndBlock(_id);
    isFinalized = getIsFinalized(_id);
    proposedValue = getProposedValue(_id);
    contractType = getContractType(_id);
    creator = getCreator(_id);
    description = getDescription(_id);
    canBeFinalizedNow = canBeFinalized(_id);
    alreadyVoted = hasAlreadyVoted(_id, _key);
    belowTurnOut = getBelowTurnOut(_id);
    accepted = getAccepted(_id);
    rejected = getRejected(_id);
    totalStake = getTotalStake(_id);

    return (startBlock, endBlock, isFinalized, proposedValue, contractType, creator, description, canBeFinalizedNow, alreadyVoted, belowTurnOut, accepted, rejected, totalStake);
  }

  /**
  * @dev This function is used to vote on a ballot
  * @param _id ballot id to vote on
  * @param _choice voting decision on the ballot (see VotingBase.ActionChoices)
  */
  function vote(uint256 _id, uint256 _choice) external {
    require(!getIsFinalized(_id));
    address voter = msg.sender;
    require(isActiveBallot(_id));
    require(!hasAlreadyVoted(_id, voter));
    require(_choice == uint(ActionChoices.Accept) || _choice == uint(ActionChoices.Reject));
    _setVoterChoice(_id, voter, _choice);
    emit Vote(_id, _choice, voter);
  }

  /**
  * @dev Function to be called by the consensus contract when a cycles ends
  * In this function, all active ballots votes will be counted and updated according to the current validators
  */
  function onCycleEnd(address[] validators) external onlyConsensus {
    uint256 numOfValidators = validators.length;
    if (numOfValidators == 0) {
      return;
    }
    uint[] memory ballots = activeBallots();
    for (uint256 i = 0; i < ballots.length; i++) {
      uint256 ballotId = ballots[i];
      if (getStartBlock(ballotId) < block.number && !getFinalizeCalled(ballotId)) {
        
        if (canBeFinalized(ballotId)) {
          uint256 accepts = 0;
          uint256 rejects = 0;
          for (uint256 j = 0; j < numOfValidators; j++) {
            uint256 choice = getVoterChoice(ballotId, validators[j]);
            if (choice == uint(ActionChoices.Accept)) {
              accepts = accepts.add(getStake(validators[j]));
            } else if (choice == uint256(ActionChoices.Reject)) {
              rejects = rejects.add(getStake(validators[j]));
            }
          }

          _setAccepted(ballotId, accepts);
          _setRejected(ballotId, rejects);
          _setTotalStake(ballotId);
          _finalize(ballotId);
        }
      }
    }
  }
}
        

Contract ABI

[{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"DECIMALS","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"MAX_BALLOT_DURATION_CYCLES","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"MAX_LIMIT_OF_BALLOTS","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"MINIMUM_TURNOUT_BP","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"MIN_BALLOT_DURATION_CYCLES","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":""}],"name":"activeBallots","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"activeBallotsAtIndex","inputs":[{"type":"uint256","name":"_index"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"activeBallotsLength","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"canBeFinalized","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getAccepted","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"startBlock"},{"type":"uint256","name":"endBlock"},{"type":"bool","name":"isFinalized"},{"type":"address","name":"proposedValue"},{"type":"uint256","name":"contractType"},{"type":"address","name":"creator"},{"type":"string","name":"description"},{"type":"bool","name":"canBeFinalizedNow"},{"type":"bool","name":"alreadyVoted"},{"type":"bool","name":"belowTurnOut"},{"type":"uint256","name":"accepted"},{"type":"uint256","name":"rejected"},{"type":"uint256","name":"totalStake"}],"name":"getBallotInfo","inputs":[{"type":"uint256","name":"_id"},{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getBallotLimitPerValidator","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"getBelowTurnOut","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getContractType","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"getCreator","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":""}],"name":"getDescription","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getEndBlock","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"getFinalizeCalled","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getIndex","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"getIsFinalized","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":""}],"name":"getMaxBallotDurationCycles","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":""}],"name":"getMinBallotDurationCycles","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getNextBallotId","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"getProposedValue","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":""}],"name":"getProxyStorage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getQuorumState","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getRejected","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getStartBlock","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getTotalStake","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"getVoterChoice","inputs":[{"type":"uint256","name":"_id"},{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"hasAlreadyVoted","inputs":[{"type":"uint256","name":"_id"},{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[],"constant":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"isActiveBallot","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"isInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"isValidVotingKey","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":""}],"name":"newBallot","inputs":[{"type":"uint256","name":"_startAfterNumberOfCycles"},{"type":"uint256","name":"_cyclesDuration"},{"type":"uint256","name":"_contractType"},{"type":"address","name":"_proposedValue"},{"type":"string","name":"_description"}],"constant":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"onCycleEnd","inputs":[{"type":"address[]","name":"validators"}],"constant":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":""}],"name":"validContractType","inputs":[{"type":"uint256","name":"_contractType"}],"constant":true},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":""}],"name":"validatorActiveBallots","inputs":[{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"vote","inputs":[{"type":"uint256","name":"_id"},{"type":"uint256","name":"_choice"}],"constant":false},{"type":"event","name":"BallotCreated","inputs":[{"type":"uint256","name":"id","indexed":true},{"type":"address","name":"creator","indexed":true}],"anonymous":false},{"type":"event","name":"BallotFinalized","inputs":[{"type":"uint256","name":"id","indexed":true}],"anonymous":false},{"type":"event","name":"Vote","inputs":[{"type":"uint256","name":"id","indexed":true},{"type":"uint256","name":"decision","indexed":false},{"type":"address","name":"voter","indexed":true}],"anonymous":false}]
              

Contract Creation Code

0x608060405234801561001057600080fd5b506138f2806100206000396000f3006080604052600436106101d45763ffffffff60e060020a60003504166301b2320e81146101d957806308dbb18e146102035780630af58e771461021b5780630eac27f41461023057806322e5fe9d1461025457806323e1a0a81461026c5780632b592f92146102985780632dfba528146102b05780632e0f2625146102c8578063340d3dc2146102dd578063392e53cd146102f25780633ee2f2121461030757806345367f231461031c578063480ca380146103345780634925ec551461034957806360970b6f146103d657806362f4c26b146103ee5780636ccc02341461040657806377da79301461041b5780638129fc1c1461043c57806382c4c96314610453578063897ba3e41461046b5780638be774d3146104805780638c64a20d146104955780638c8ab7ad146105b95780638e7cb6e1146105d1578063b384abef146105e9578063bbac62c814610604578063bdd4ae5514610624578063c12eefd21461063c578063c14bfd2914610675578063d21dc68a14610699578063d48e638a146106fe578063d6edcb3814610732578063df0444771461074a578063ec15a5e614610762578063edaab22314610777578063f3161a4d1461078f578063f49774ee146107a4578063fcff021c146107c5575b600080fd5b3480156101e557600080fd5b506101f16004356107da565b60408051918252519081900360200190f35b34801561020f57600080fd5b506101f16004356108b0565b34801561022757600080fd5b506101f1610942565b34801561023c57600080fd5b506101f1600435600160a060020a0360243516610947565b34801561026057600080fd5b506101f1600435610a39565b34801561027857600080fd5b50610284600435610acb565b604080519115158252519081900360200190f35b3480156102a457600080fd5b50610284600435610ba2565b3480156102bc57600080fd5b50610284600435610bc7565b3480156102d457600080fd5b506101f1610c43565b3480156102e957600080fd5b506101f1610c4f565b3480156102fe57600080fd5b50610284610c55565b34801561031357600080fd5b506101f1610d0e565b34801561032857600080fd5b506101f1600435610dc3565b34801561034057600080fd5b506101f1610e55565b34801561035557600080fd5b50610361600435610e5a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610284600435610fd0565b3480156103fa57600080fd5b506101f1600435611062565b34801561041257600080fd5b506101f16110f4565b34801561042757600080fd5b50610284600160a060020a0360043516611156565b34801561044857600080fd5b506104516112e6565b005b34801561045f57600080fd5b506102846004356113c8565b34801561047757600080fd5b506101f1611420565b34801561048c57600080fd5b506101f1611425565b3480156104a157600080fd5b506104b9600435600160a060020a036024351661142a565b604051808e81526020018d81526020018c1515151581526020018b600160a060020a0316600160a060020a031681526020018a815260200189600160a060020a0316600160a060020a0316815260200180602001881515151581526020018715151515815260200186151515158152602001858152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b8381101561057257818101518382015260200161055a565b50505050905090810190601f16801561059f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060405180910390f35b3480156105c557600080fd5b506101f16004356114e0565b3480156105dd57600080fd5b506101f1600435611572565b3480156105f557600080fd5b50610451600435602435611604565b34801561061057600080fd5b5061045160048035602481019101356116ad565b34801561063057600080fd5b506101f16004356118a3565b34801561064857600080fd5b506101f16004803590602480359160443591600160a060020a036064351691608435918201910135611935565b34801561068157600080fd5b50610284600435600160a060020a0360243516611a1a565b3480156106a557600080fd5b506106ae611a47565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ea5781810151838201526020016106d2565b505050509050019250505060405180910390f35b34801561070a57600080fd5b50610716600435611b34565b60408051600160a060020a039092168252519081900360200190f35b34801561073e57600080fd5b50610716600435611c11565b34801561075657600080fd5b506101f1600435611ca3565b34801561076e57600080fd5b50610716611d61565b34801561078357600080fd5b50610284600435611e1f565b34801561079b57600080fd5b506101f1611ea3565b3480156107b057600080fd5b506101f1600160a060020a0360043516611ea8565b3480156107d157600080fd5b506101f1611f45565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b6020831061086d5780518252601f19909201916020918201910161084e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b919050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600281565b604080516000805160206138a7833981519152602080830191909152602b82018590527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0385160260518301528251604581840301815260659092019283905281516000936002938593909282918401908083835b602083106109f55780518252601f1990920191602091820191016109d6565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b92915050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610b5e5780518252601f199092019160209182019101610b3f565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1695945050505050565b600043610bae836107da565b108015610a335750610bbf826114e0565b431092915050565b6000600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b670de0b6b3a764000081565b6107d081565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610cca5780518252601f199092019160209182019101610cab565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1693505050505b90565b60006002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310610d835780518252601f199092019160209182019101610d64565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054949350505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f746f74616c5374616b6500000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600e81565b6060600360008360405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610eed5780518252601f199092019160209182019101610ece565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fc45780601f10610f9957610100808354040283529160200191610fc4565b820191906000526020600020905b815481529060010190602001808311610fa757829003601f168201915b50505050509050919050565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c0191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a65637465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600860006040516020018080600080516020613887833981519152815250600d01905060405160208183030381529060405260405180828051906020019080838360208310610d835780518252601f199092019160209182019101610d64565b600080808080611164611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b505192505b82600160a060020a03166340c9cdeb6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561120e57600080fd5b505af1158015611222573d6000803e3d6000fd5b505050506040513d602081101561123857600080fd5b50518210156112dc5782600160a060020a03166357aeefc5836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b50519050600160a060020a0380821690871614156112d157600193505b6001909101906111d0565b5091949350505050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106113595780518252601f19909201916020918201910161133a565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506113aa91505057600080fd5b6113b2610c55565b156113bc57600080fd5b6113c66001611f8b565b565b60006113d2610d0e565b82106113e0575060006108ab565b436113ea836107da565b11156113f8575060006108ab565b61140182610acb565b1561140e575060006108ab565b611417826114e0565b43101592915050565b606481565b600e90565b60008060008060008060606000806000806000806114478f6107da565b9c506114528f6114e0565b9b5061145d8f610acb565b9a506114688f611c11565b99506114738f6118a3565b985061147e8f611b34565b97506114898f610e5a565b96506114948f6113c8565b95506114a08f8f611a1a565b94506114ab8f610fd0565b93506114b68f610a39565b92506114c18f611062565b91506114cc8f610dc3565b90509295989b9e9194979a9d509295989b50565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f696e6465780000000000000000000000000000000000000000000000000000008152506005019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600061160f83610acb565b1561161957600080fd5b503361162483610ba2565b151561162f57600080fd5b6116398382611a1a565b1561164357600080fd5b60018214806116525750600282145b151561165d57600080fd5b61166883828461204c565b604080518381529051600160a060020a0383169185917f7c2f48a4bf2e759e77b1e77a8bf1034cdf16e9034dad596d3655bb8b315f85eb9181900360200190a3505050565b600060606000806000806000806116c2611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d602081101561172957600080fd5b5051600160a060020a0316331461173f57600080fd5b88975087151561174e57611897565b611756611a47565b9650600095505b865186101561189757868681518110151561177457fe5b9060200190602002015194504361178a866107da565b10801561179d575061179b85610bc7565b155b1561188c576117ab856113c8565b1561188c576000935060009250600091505b87821015611866576117ea858b8b858181106117d557fe5b90506020020135600160a060020a0316610947565b905060018114156118305761182961181c8b8b8581811061180757fe5b90506020020135600160a060020a031661213d565b859063ffffffff61221516565b935061185b565b600281141561185b5761185861184b8b8b8581811061180757fe5b849063ffffffff61221516565b92505b6001909101906117bd565b6118708585612232565b61187a8584612306565b61188385612397565b61188c85612561565b60019095019461175d565b50505050505050505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000803361194281611156565b151561194d57600080fd5b88886000821161195c57600080fd5b6000811161196957600080fd5b611971611ea3565b81101561197d57600080fd5b611985611425565b81111561199157600080fd5b600160a060020a03881615156119a657600080fd5b6119af89611e1f565b15156119ba57600080fd5b6119f58b8b89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612645945050505050565b9350611a018489612742565b611a0b848a61283e565b50919998505050505050505050565b6000600160a060020a0382161515611a3457506000610a33565b611a3e8383610947565b15159392505050565b6060600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611aaa5780518252601f199092019160209182019101611a8b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015611b2a57602002820191906000526020600020905b815481526020019060010190808311611b16575b5050505050905090565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f72000000000000000000000000000000000000000000000000008152506007019150506040516020818303038152906040526040518082805190602001908083835b60208310611bc75780518252601f199092019160209182019101611ba8565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031695945050505050565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d0191505060405160208183030381529060405260405180828051906020019080838360208310611bc75780518252601f199092019160209182019101611ba8565b6000600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611d065780518252601f199092019160209182019101611ce7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050611d4f57fe5b90600052602060002001549050919050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310611dd65780518252601f199092019160209182019101611db7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000611e29611d61565b600160a060020a03166333875fdd836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015611e7157600080fd5b505af1158015611e85573d6000803e3d6000fd5b505050506040513d6020811015611e9b57600080fd5b505192915050565b600290565b6000600260008360405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000806000611f526128cf565b9150811515611f645760649250611f86565b611f7560648363ffffffff6129d016565b9050801515611f82575060015b8092505b505090565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611fff5780518252601f199092019160209182019101611fe0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b604080516000805160206138a7833981519152602080830191909152602b82018690527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0386160260518301528251604581840301815260659092019283905281518493600293600093909282918401908083835b602083106120fa5780518252601f1990920191602091820191016120db565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050565b6000612147611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561218457600080fd5b505af1158015612198573d6000803e3d6000fd5b505050506040513d60208110156121ae57600080fd5b5051604080517fbf135267000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163bf1352679160248083019260209291908290030181600087803b158015611e7157600080fd5b60008282018381101561222757600080fd5b8091505b5092915050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106122c45780518252601f1990920191602091820191016122a5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a6563746564000000000000000000000000000000000000000000000000815250600801915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b61239f611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050506040513d602081101561240657600080fd5b5051604080517f94409a560000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916394409a56916004808201926020929091908290030181600087803b15801561246557600080fd5b505af1158015612479573d6000803e3d6000fd5b505050506040513d602081101561248f57600080fd5b5051604080516000805160206138a7833981519152602082810191909152602b82018590527f746f74616c5374616b6500000000000000000000000000000000000000000000604b83015282516035818403018152605590920192839052815160029360009392909182918401908083835b602083106125205780518252601f199092019160209182019101612501565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b61256a81610bc7565b151561258257612579816129f3565b61258281612a27565b61258b81612aa3565b156125ec5761259981611062565b6125a282610a39565b11156125d1576125b181612ad4565b156125c7576125c28160025b612b50565b6125cc565b612642565b6125dc565b6125dc8160036125bd565b6125e7816000612be1565b612602565b6125f7816001612be1565b6126028160036125bd565b61260b81612cc1565b612616816001612d16565b60405181907fd470bb0d3dcb39ff5a62757e0a1cdfe60f8200eba22fd0d82383630d457f868690600090a25b50565b6000806000612652610c55565b151561265d57600080fd5b33915061266982612da7565b151561267457600080fd5b61267c610d0e565b905061269761269282600163ffffffff61221516565b612dc1565b6126a18187612e34565b6126ab81866130bd565b6126b6816000612d16565b6126c18160016125bd565b6126cb81836132b5565b6126d58185613346565b6126e6816126e16110f4565b613426565b6126f1816000612be1565b6126fa816134b7565b6127038261356c565b604051600160a060020a0383169082907fe64b3864f6f22f8969f8cb16c039eaf6454ef5e23c09791df010163000a7023590600090a395945050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d019150506040516020818303038152906040526040518082805190602001908083835b602083106127d45780518252601f1990920191602091820191016127b5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0395909516949094179093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b60006128d9611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b505050506040513d602081101561294057600080fd5b5051604080517f40c9cdeb0000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916340c9cdeb916004808201926020929091908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b5051905090565b6000808083116129df57600080fd5b82848115156129ea57fe5b04949350505050565b6000806129ff83611b34565b9150612a0a82611ea8565b90506000811115612a2257612a22826001830361358a565b505050565b6001600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310611fff5780518252601f199092019160209182019101611fe0565b600080600080612ab285610dc3565b92506127106107d08402049150612ac885610a39565b91909111949350505050565b6000612ade611d61565b600160a060020a031663bb0165b1612af5846118a3565b612afe85611c11565b6040518363ffffffff1660e060020a0281526004018083815260200182600160a060020a0316600160a060020a0316815260200192505050602060405180830381600087803b158015611e7157600080fd5b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083835b60208310612c735780518252601f199092019160209182019101612c54565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff1916941515949094179093555050505050565b6000806000612ccf84611572565b92506001612cdb6110f4565b039150612ce782611ca3565b9050612cf38382613626565b612cfd8184613426565b612d08826000613626565b612d106136e1565b50505050565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0191505060405160208183030381529060405260405180828051906020019080838360208310612c735780518252601f199092019160209182019101612c54565b6000612db1611f45565b612dba83611ea8565b1092915050565b806002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c019050604051602081830303815290604052604051808280519060200190808383602083106125205780518252601f199092019160209182019101612501565b600080600080612e42611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612e7f57600080fd5b505af1158015612e93573d6000803e3d6000fd5b505050506040513d6020811015612ea957600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051919550600160a060020a0386169163a6524923916004808201926020929091908290030181600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506040513d6020811015612f3457600080fd5b5051604080517faf2951810000000000000000000000000000000000000000000000000000000081529051919450600160a060020a0386169163af295181916004808201926020929091908290030181600087803b158015612f9557600080fd5b505af1158015612fa9573d6000803e3d6000fd5b505050506040513d6020811015612fbf57600080fd5b50519150612fe3612fd6868563ffffffff6137a016565b839063ffffffff61221516565b905080600260008860405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b602083106130775780518252601f199092019160209182019101613058565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050505050565b60008060006130ca611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561310757600080fd5b505af115801561311b573d6000803e3d6000fd5b505050506040513d602081101561313157600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163a6524923916004808201926020929091908290030181600087803b15801561319057600080fd5b505af11580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b505192506131c7856107da565b91506131dc612fd6858563ffffffff6137a016565b905080600260008760405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106132705780518252601f199092019160209182019101613251565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f7200000000000000000000000000000000000000000000000000815250600701915050604051602081830303815290604052604051808280519060200190808383602083106127d45780518252601f1990920191602091820191016127b5565b80600360008460405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b602083106133d85780518252601f1990920191602091820191016133b9565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451612a229591945092019190506137ce565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f696e646578000000000000000000000000000000000000000000000000000000815250600501915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106135185780518252601f1990920191602091820191016134f9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509290920160009081208054600181018255908252939020909201929092555050565b6126428161358a600161357e85611ea8565b9063ffffffff61221516565b80600260008460405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106136885780518252601f199092019160209182019101613669565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350869250821090506136d157fe5b6000918252602090912001555050565b60006136eb6110f4565b11156113c657600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106137525780518252601f199092019160209182019101613733565b51815160001960209485036101000a8101918216911992909216179091526040805195909301859003909420875286019690965250929093016000208054935061264292909150830161384c565b6000808315156137b3576000915061222b565b508282028284828115156137c357fe5b041461222757600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061380f57805160ff191683800117855561383c565b8280016001018555821561383c579182015b8281111561383c578251825591602001919060010190613821565b5061384892915061386c565b5090565b815481835581811115612a2257600083815260209020612a229181019083015b610d0b91905b808211156138485760008155600101613872560061637469766542616c6c6f747300000000000000000000000000000000000000766f74696e675374617465000000000000000000000000000000000000000000a165627a7a723058208d70072ebed43198b496d8e8560f428fa5f8fefd60a01bc2bd679521aeb93a290029

Deployed ByteCode

0x6080604052600436106101d45763ffffffff60e060020a60003504166301b2320e81146101d957806308dbb18e146102035780630af58e771461021b5780630eac27f41461023057806322e5fe9d1461025457806323e1a0a81461026c5780632b592f92146102985780632dfba528146102b05780632e0f2625146102c8578063340d3dc2146102dd578063392e53cd146102f25780633ee2f2121461030757806345367f231461031c578063480ca380146103345780634925ec551461034957806360970b6f146103d657806362f4c26b146103ee5780636ccc02341461040657806377da79301461041b5780638129fc1c1461043c57806382c4c96314610453578063897ba3e41461046b5780638be774d3146104805780638c64a20d146104955780638c8ab7ad146105b95780638e7cb6e1146105d1578063b384abef146105e9578063bbac62c814610604578063bdd4ae5514610624578063c12eefd21461063c578063c14bfd2914610675578063d21dc68a14610699578063d48e638a146106fe578063d6edcb3814610732578063df0444771461074a578063ec15a5e614610762578063edaab22314610777578063f3161a4d1461078f578063f49774ee146107a4578063fcff021c146107c5575b600080fd5b3480156101e557600080fd5b506101f16004356107da565b60408051918252519081900360200190f35b34801561020f57600080fd5b506101f16004356108b0565b34801561022757600080fd5b506101f1610942565b34801561023c57600080fd5b506101f1600435600160a060020a0360243516610947565b34801561026057600080fd5b506101f1600435610a39565b34801561027857600080fd5b50610284600435610acb565b604080519115158252519081900360200190f35b3480156102a457600080fd5b50610284600435610ba2565b3480156102bc57600080fd5b50610284600435610bc7565b3480156102d457600080fd5b506101f1610c43565b3480156102e957600080fd5b506101f1610c4f565b3480156102fe57600080fd5b50610284610c55565b34801561031357600080fd5b506101f1610d0e565b34801561032857600080fd5b506101f1600435610dc3565b34801561034057600080fd5b506101f1610e55565b34801561035557600080fd5b50610361600435610e5a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610284600435610fd0565b3480156103fa57600080fd5b506101f1600435611062565b34801561041257600080fd5b506101f16110f4565b34801561042757600080fd5b50610284600160a060020a0360043516611156565b34801561044857600080fd5b506104516112e6565b005b34801561045f57600080fd5b506102846004356113c8565b34801561047757600080fd5b506101f1611420565b34801561048c57600080fd5b506101f1611425565b3480156104a157600080fd5b506104b9600435600160a060020a036024351661142a565b604051808e81526020018d81526020018c1515151581526020018b600160a060020a0316600160a060020a031681526020018a815260200189600160a060020a0316600160a060020a0316815260200180602001881515151581526020018715151515815260200186151515158152602001858152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b8381101561057257818101518382015260200161055a565b50505050905090810190601f16801561059f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060405180910390f35b3480156105c557600080fd5b506101f16004356114e0565b3480156105dd57600080fd5b506101f1600435611572565b3480156105f557600080fd5b50610451600435602435611604565b34801561061057600080fd5b5061045160048035602481019101356116ad565b34801561063057600080fd5b506101f16004356118a3565b34801561064857600080fd5b506101f16004803590602480359160443591600160a060020a036064351691608435918201910135611935565b34801561068157600080fd5b50610284600435600160a060020a0360243516611a1a565b3480156106a557600080fd5b506106ae611a47565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ea5781810151838201526020016106d2565b505050509050019250505060405180910390f35b34801561070a57600080fd5b50610716600435611b34565b60408051600160a060020a039092168252519081900360200190f35b34801561073e57600080fd5b50610716600435611c11565b34801561075657600080fd5b506101f1600435611ca3565b34801561076e57600080fd5b50610716611d61565b34801561078357600080fd5b50610284600435611e1f565b34801561079b57600080fd5b506101f1611ea3565b3480156107b057600080fd5b506101f1600160a060020a0360043516611ea8565b3480156107d157600080fd5b506101f1611f45565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b6020831061086d5780518252601f19909201916020918201910161084e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b919050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600281565b604080516000805160206138a7833981519152602080830191909152602b82018590527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0385160260518301528251604581840301815260659092019283905281516000936002938593909282918401908083835b602083106109f55780518252601f1990920191602091820191016109d6565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b92915050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610b5e5780518252601f199092019160209182019101610b3f565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1695945050505050565b600043610bae836107da565b108015610a335750610bbf826114e0565b431092915050565b6000600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b670de0b6b3a764000081565b6107d081565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610cca5780518252601f199092019160209182019101610cab565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1693505050505b90565b60006002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310610d835780518252601f199092019160209182019101610d64565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054949350505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f746f74616c5374616b6500000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600e81565b6060600360008360405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610eed5780518252601f199092019160209182019101610ece565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fc45780601f10610f9957610100808354040283529160200191610fc4565b820191906000526020600020905b815481529060010190602001808311610fa757829003601f168201915b50505050509050919050565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c0191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a65637465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600860006040516020018080600080516020613887833981519152815250600d01905060405160208183030381529060405260405180828051906020019080838360208310610d835780518252601f199092019160209182019101610d64565b600080808080611164611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b505192505b82600160a060020a03166340c9cdeb6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561120e57600080fd5b505af1158015611222573d6000803e3d6000fd5b505050506040513d602081101561123857600080fd5b50518210156112dc5782600160a060020a03166357aeefc5836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b50519050600160a060020a0380821690871614156112d157600193505b6001909101906111d0565b5091949350505050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106113595780518252601f19909201916020918201910161133a565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506113aa91505057600080fd5b6113b2610c55565b156113bc57600080fd5b6113c66001611f8b565b565b60006113d2610d0e565b82106113e0575060006108ab565b436113ea836107da565b11156113f8575060006108ab565b61140182610acb565b1561140e575060006108ab565b611417826114e0565b43101592915050565b606481565b600e90565b60008060008060008060606000806000806000806114478f6107da565b9c506114528f6114e0565b9b5061145d8f610acb565b9a506114688f611c11565b99506114738f6118a3565b985061147e8f611b34565b97506114898f610e5a565b96506114948f6113c8565b95506114a08f8f611a1a565b94506114ab8f610fd0565b93506114b68f610a39565b92506114c18f611062565b91506114cc8f610dc3565b90509295989b9e9194979a9d509295989b50565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f696e6465780000000000000000000000000000000000000000000000000000008152506005019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600061160f83610acb565b1561161957600080fd5b503361162483610ba2565b151561162f57600080fd5b6116398382611a1a565b1561164357600080fd5b60018214806116525750600282145b151561165d57600080fd5b61166883828461204c565b604080518381529051600160a060020a0383169185917f7c2f48a4bf2e759e77b1e77a8bf1034cdf16e9034dad596d3655bb8b315f85eb9181900360200190a3505050565b600060606000806000806000806116c2611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d602081101561172957600080fd5b5051600160a060020a0316331461173f57600080fd5b88975087151561174e57611897565b611756611a47565b9650600095505b865186101561189757868681518110151561177457fe5b9060200190602002015194504361178a866107da565b10801561179d575061179b85610bc7565b155b1561188c576117ab856113c8565b1561188c576000935060009250600091505b87821015611866576117ea858b8b858181106117d557fe5b90506020020135600160a060020a0316610947565b905060018114156118305761182961181c8b8b8581811061180757fe5b90506020020135600160a060020a031661213d565b859063ffffffff61221516565b935061185b565b600281141561185b5761185861184b8b8b8581811061180757fe5b849063ffffffff61221516565b92505b6001909101906117bd565b6118708585612232565b61187a8584612306565b61188385612397565b61188c85612561565b60019095019461175d565b50505050505050505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000803361194281611156565b151561194d57600080fd5b88886000821161195c57600080fd5b6000811161196957600080fd5b611971611ea3565b81101561197d57600080fd5b611985611425565b81111561199157600080fd5b600160a060020a03881615156119a657600080fd5b6119af89611e1f565b15156119ba57600080fd5b6119f58b8b89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612645945050505050565b9350611a018489612742565b611a0b848a61283e565b50919998505050505050505050565b6000600160a060020a0382161515611a3457506000610a33565b611a3e8383610947565b15159392505050565b6060600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611aaa5780518252601f199092019160209182019101611a8b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015611b2a57602002820191906000526020600020905b815481526020019060010190808311611b16575b5050505050905090565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f72000000000000000000000000000000000000000000000000008152506007019150506040516020818303038152906040526040518082805190602001908083835b60208310611bc75780518252601f199092019160209182019101611ba8565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031695945050505050565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d0191505060405160208183030381529060405260405180828051906020019080838360208310611bc75780518252601f199092019160209182019101611ba8565b6000600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611d065780518252601f199092019160209182019101611ce7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050611d4f57fe5b90600052602060002001549050919050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310611dd65780518252601f199092019160209182019101611db7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000611e29611d61565b600160a060020a03166333875fdd836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015611e7157600080fd5b505af1158015611e85573d6000803e3d6000fd5b505050506040513d6020811015611e9b57600080fd5b505192915050565b600290565b6000600260008360405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000806000611f526128cf565b9150811515611f645760649250611f86565b611f7560648363ffffffff6129d016565b9050801515611f82575060015b8092505b505090565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611fff5780518252601f199092019160209182019101611fe0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b604080516000805160206138a7833981519152602080830191909152602b82018690527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0386160260518301528251604581840301815260659092019283905281518493600293600093909282918401908083835b602083106120fa5780518252601f1990920191602091820191016120db565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050565b6000612147611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561218457600080fd5b505af1158015612198573d6000803e3d6000fd5b505050506040513d60208110156121ae57600080fd5b5051604080517fbf135267000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163bf1352679160248083019260209291908290030181600087803b158015611e7157600080fd5b60008282018381101561222757600080fd5b8091505b5092915050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106122c45780518252601f1990920191602091820191016122a5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a6563746564000000000000000000000000000000000000000000000000815250600801915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b61239f611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050506040513d602081101561240657600080fd5b5051604080517f94409a560000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916394409a56916004808201926020929091908290030181600087803b15801561246557600080fd5b505af1158015612479573d6000803e3d6000fd5b505050506040513d602081101561248f57600080fd5b5051604080516000805160206138a7833981519152602082810191909152602b82018590527f746f74616c5374616b6500000000000000000000000000000000000000000000604b83015282516035818403018152605590920192839052815160029360009392909182918401908083835b602083106125205780518252601f199092019160209182019101612501565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b61256a81610bc7565b151561258257612579816129f3565b61258281612a27565b61258b81612aa3565b156125ec5761259981611062565b6125a282610a39565b11156125d1576125b181612ad4565b156125c7576125c28160025b612b50565b6125cc565b612642565b6125dc565b6125dc8160036125bd565b6125e7816000612be1565b612602565b6125f7816001612be1565b6126028160036125bd565b61260b81612cc1565b612616816001612d16565b60405181907fd470bb0d3dcb39ff5a62757e0a1cdfe60f8200eba22fd0d82383630d457f868690600090a25b50565b6000806000612652610c55565b151561265d57600080fd5b33915061266982612da7565b151561267457600080fd5b61267c610d0e565b905061269761269282600163ffffffff61221516565b612dc1565b6126a18187612e34565b6126ab81866130bd565b6126b6816000612d16565b6126c18160016125bd565b6126cb81836132b5565b6126d58185613346565b6126e6816126e16110f4565b613426565b6126f1816000612be1565b6126fa816134b7565b6127038261356c565b604051600160a060020a0383169082907fe64b3864f6f22f8969f8cb16c039eaf6454ef5e23c09791df010163000a7023590600090a395945050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d019150506040516020818303038152906040526040518082805190602001908083835b602083106127d45780518252601f1990920191602091820191016127b5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0395909516949094179093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b60006128d9611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b505050506040513d602081101561294057600080fd5b5051604080517f40c9cdeb0000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916340c9cdeb916004808201926020929091908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b5051905090565b6000808083116129df57600080fd5b82848115156129ea57fe5b04949350505050565b6000806129ff83611b34565b9150612a0a82611ea8565b90506000811115612a2257612a22826001830361358a565b505050565b6001600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310611fff5780518252601f199092019160209182019101611fe0565b600080600080612ab285610dc3565b92506127106107d08402049150612ac885610a39565b91909111949350505050565b6000612ade611d61565b600160a060020a031663bb0165b1612af5846118a3565b612afe85611c11565b6040518363ffffffff1660e060020a0281526004018083815260200182600160a060020a0316600160a060020a0316815260200192505050602060405180830381600087803b158015611e7157600080fd5b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083835b60208310612c735780518252601f199092019160209182019101612c54565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff1916941515949094179093555050505050565b6000806000612ccf84611572565b92506001612cdb6110f4565b039150612ce782611ca3565b9050612cf38382613626565b612cfd8184613426565b612d08826000613626565b612d106136e1565b50505050565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0191505060405160208183030381529060405260405180828051906020019080838360208310612c735780518252601f199092019160209182019101612c54565b6000612db1611f45565b612dba83611ea8565b1092915050565b806002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c019050604051602081830303815290604052604051808280519060200190808383602083106125205780518252601f199092019160209182019101612501565b600080600080612e42611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612e7f57600080fd5b505af1158015612e93573d6000803e3d6000fd5b505050506040513d6020811015612ea957600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051919550600160a060020a0386169163a6524923916004808201926020929091908290030181600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506040513d6020811015612f3457600080fd5b5051604080517faf2951810000000000000000000000000000000000000000000000000000000081529051919450600160a060020a0386169163af295181916004808201926020929091908290030181600087803b158015612f9557600080fd5b505af1158015612fa9573d6000803e3d6000fd5b505050506040513d6020811015612fbf57600080fd5b50519150612fe3612fd6868563ffffffff6137a016565b839063ffffffff61221516565b905080600260008860405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b602083106130775780518252601f199092019160209182019101613058565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050505050565b60008060006130ca611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561310757600080fd5b505af115801561311b573d6000803e3d6000fd5b505050506040513d602081101561313157600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163a6524923916004808201926020929091908290030181600087803b15801561319057600080fd5b505af11580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b505192506131c7856107da565b91506131dc612fd6858563ffffffff6137a016565b905080600260008760405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106132705780518252601f199092019160209182019101613251565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f7200000000000000000000000000000000000000000000000000815250600701915050604051602081830303815290604052604051808280519060200190808383602083106127d45780518252601f1990920191602091820191016127b5565b80600360008460405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b602083106133d85780518252601f1990920191602091820191016133b9565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451612a229591945092019190506137ce565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f696e646578000000000000000000000000000000000000000000000000000000815250600501915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106135185780518252601f1990920191602091820191016134f9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509290920160009081208054600181018255908252939020909201929092555050565b6126428161358a600161357e85611ea8565b9063ffffffff61221516565b80600260008460405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106136885780518252601f199092019160209182019101613669565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350869250821090506136d157fe5b6000918252602090912001555050565b60006136eb6110f4565b11156113c657600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106137525780518252601f199092019160209182019101613733565b51815160001960209485036101000a8101918216911992909216179091526040805195909301859003909420875286019690965250929093016000208054935061264292909150830161384c565b6000808315156137b3576000915061222b565b508282028284828115156137c357fe5b041461222757600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061380f57805160ff191683800117855561383c565b8280016001018555821561383c579182015b8281111561383c578251825591602001919060010190613821565b5061384892915061386c565b5090565b815481835581811115612a2257600083815260209020612a229181019083015b610d0b91905b808211156138485760008155600101613872560061637469766542616c6c6f747300000000000000000000000000000000000000766f74696e675374617465000000000000000000000000000000000000000000a165627a7a723058208d70072ebed43198b496d8e8560f428fa5f8fefd60a01bc2bd679521aeb93a290029