false
false
0

Contract Address Details

0x970Fd6a020A34D34E83342E236dc005E581E7745

Contract Name
Voting
Creator
0xec21d6–a401f5 at 0x050dcb–d631e2
Balance
0 AI
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
633430
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Voting




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




Optimization runs
200
EVM Version
default




Verified at
2025-04-01T07:09:11.885542Z

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","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getStartBlock","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getQuorumState","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MIN_BALLOT_DURATION_CYCLES","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getVoterChoice","inputs":[{"type":"uint256","name":"_id"},{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getAccepted","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"getIsFinalized","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isActiveBallot","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"getFinalizeCalled","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"DECIMALS","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MINIMUM_TURNOUT_BP","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getNextBallotId","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getTotalStake","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_BALLOT_DURATION_CYCLES","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"getDescription","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"getBelowTurnOut","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getRejected","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"activeBallotsLength","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isValidVotingKey","inputs":[{"type":"address","name":"_address"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"canBeFinalized","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"MAX_LIMIT_OF_BALLOTS","inputs":[],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMaxBallotDurationCycles","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"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","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getEndBlock","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getIndex","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"vote","inputs":[{"type":"uint256","name":"_id"},{"type":"uint256","name":"_choice"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"onCycleEnd","inputs":[{"type":"address[]","name":"validators"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getContractType","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"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":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"hasAlreadyVoted","inputs":[{"type":"uint256","name":"_id"},{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256[]","name":""}],"name":"activeBallots","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getCreator","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getProposedValue","inputs":[{"type":"uint256","name":"_id"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"activeBallotsAtIndex","inputs":[{"type":"uint256","name":"_index"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getProxyStorage","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"validContractType","inputs":[{"type":"uint256","name":"_contractType"}],"constant":true},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMinBallotDurationCycles","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"validatorActiveBallots","inputs":[{"type":"address","name":"_key"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getBallotLimitPerValidator","inputs":[],"constant":true},{"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

Verify & Publish
0x608060405234801561001057600080fd5b506138f2806100206000396000f3006080604052600436106101d45763ffffffff60e060020a60003504166301b2320e81146101d957806308dbb18e146102035780630af58e771461021b5780630eac27f41461023057806322e5fe9d1461025457806323e1a0a81461026c5780632b592f92146102985780632dfba528146102b05780632e0f2625146102c8578063340d3dc2146102dd578063392e53cd146102f25780633ee2f2121461030757806345367f231461031c578063480ca380146103345780634925ec551461034957806360970b6f146103d657806362f4c26b146103ee5780636ccc02341461040657806377da79301461041b5780638129fc1c1461043c57806382c4c96314610453578063897ba3e41461046b5780638be774d3146104805780638c64a20d146104955780638c8ab7ad146105b95780638e7cb6e1146105d1578063b384abef146105e9578063bbac62c814610604578063bdd4ae5514610624578063c12eefd21461063c578063c14bfd2914610675578063d21dc68a14610699578063d48e638a146106fe578063d6edcb3814610732578063df0444771461074a578063ec15a5e614610762578063edaab22314610777578063f3161a4d1461078f578063f49774ee146107a4578063fcff021c146107c5575b600080fd5b3480156101e557600080fd5b506101f16004356107da565b60408051918252519081900360200190f35b34801561020f57600080fd5b506101f16004356108b0565b34801561022757600080fd5b506101f1610942565b34801561023c57600080fd5b506101f1600435600160a060020a0360243516610947565b34801561026057600080fd5b506101f1600435610a39565b34801561027857600080fd5b50610284600435610acb565b604080519115158252519081900360200190f35b3480156102a457600080fd5b50610284600435610ba2565b3480156102bc57600080fd5b50610284600435610bc7565b3480156102d457600080fd5b506101f1610c43565b3480156102e957600080fd5b506101f1610c4f565b3480156102fe57600080fd5b50610284610c55565b34801561031357600080fd5b506101f1610d0e565b34801561032857600080fd5b506101f1600435610dc3565b34801561034057600080fd5b506101f1610e55565b34801561035557600080fd5b50610361600435610e5a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610284600435610fd0565b3480156103fa57600080fd5b506101f1600435611062565b34801561041257600080fd5b506101f16110f4565b34801561042757600080fd5b50610284600160a060020a0360043516611156565b34801561044857600080fd5b506104516112e6565b005b34801561045f57600080fd5b506102846004356113c8565b34801561047757600080fd5b506101f1611420565b34801561048c57600080fd5b506101f1611425565b3480156104a157600080fd5b506104b9600435600160a060020a036024351661142a565b604051808e81526020018d81526020018c1515151581526020018b600160a060020a0316600160a060020a031681526020018a815260200189600160a060020a0316600160a060020a0316815260200180602001881515151581526020018715151515815260200186151515158152602001858152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b8381101561057257818101518382015260200161055a565b50505050905090810190601f16801561059f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060405180910390f35b3480156105c557600080fd5b506101f16004356114e0565b3480156105dd57600080fd5b506101f1600435611572565b3480156105f557600080fd5b50610451600435602435611604565b34801561061057600080fd5b5061045160048035602481019101356116ad565b34801561063057600080fd5b506101f16004356118a3565b34801561064857600080fd5b506101f16004803590602480359160443591600160a060020a036064351691608435918201910135611935565b34801561068157600080fd5b50610284600435600160a060020a0360243516611a1a565b3480156106a557600080fd5b506106ae611a47565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ea5781810151838201526020016106d2565b505050509050019250505060405180910390f35b34801561070a57600080fd5b50610716600435611b34565b60408051600160a060020a039092168252519081900360200190f35b34801561073e57600080fd5b50610716600435611c11565b34801561075657600080fd5b506101f1600435611ca3565b34801561076e57600080fd5b50610716611d61565b34801561078357600080fd5b50610284600435611e1f565b34801561079b57600080fd5b506101f1611ea3565b3480156107b057600080fd5b506101f1600160a060020a0360043516611ea8565b3480156107d157600080fd5b506101f1611f45565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b6020831061086d5780518252601f19909201916020918201910161084e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b919050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600281565b604080516000805160206138a7833981519152602080830191909152602b82018590527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0385160260518301528251604581840301815260659092019283905281516000936002938593909282918401908083835b602083106109f55780518252601f1990920191602091820191016109d6565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b92915050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610b5e5780518252601f199092019160209182019101610b3f565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1695945050505050565b600043610bae836107da565b108015610a335750610bbf826114e0565b431092915050565b6000600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b670de0b6b3a764000081565b6107d081565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610cca5780518252601f199092019160209182019101610cab565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1693505050505b90565b60006002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310610d835780518252601f199092019160209182019101610d64565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054949350505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f746f74616c5374616b6500000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600e81565b6060600360008360405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610eed5780518252601f199092019160209182019101610ece565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fc45780601f10610f9957610100808354040283529160200191610fc4565b820191906000526020600020905b815481529060010190602001808311610fa757829003601f168201915b50505050509050919050565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c0191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a65637465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600860006040516020018080600080516020613887833981519152815250600d01905060405160208183030381529060405260405180828051906020019080838360208310610d835780518252601f199092019160209182019101610d64565b600080808080611164611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b505192505b82600160a060020a03166340c9cdeb6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561120e57600080fd5b505af1158015611222573d6000803e3d6000fd5b505050506040513d602081101561123857600080fd5b50518210156112dc5782600160a060020a03166357aeefc5836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b50519050600160a060020a0380821690871614156112d157600193505b6001909101906111d0565b5091949350505050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106113595780518252601f19909201916020918201910161133a565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506113aa91505057600080fd5b6113b2610c55565b156113bc57600080fd5b6113c66001611f8b565b565b60006113d2610d0e565b82106113e0575060006108ab565b436113ea836107da565b11156113f8575060006108ab565b61140182610acb565b1561140e575060006108ab565b611417826114e0565b43101592915050565b606481565b600e90565b60008060008060008060606000806000806000806114478f6107da565b9c506114528f6114e0565b9b5061145d8f610acb565b9a506114688f611c11565b99506114738f6118a3565b985061147e8f611b34565b97506114898f610e5a565b96506114948f6113c8565b95506114a08f8f611a1a565b94506114ab8f610fd0565b93506114b68f610a39565b92506114c18f611062565b91506114cc8f610dc3565b90509295989b9e9194979a9d509295989b50565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f696e6465780000000000000000000000000000000000000000000000000000008152506005019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600061160f83610acb565b1561161957600080fd5b503361162483610ba2565b151561162f57600080fd5b6116398382611a1a565b1561164357600080fd5b60018214806116525750600282145b151561165d57600080fd5b61166883828461204c565b604080518381529051600160a060020a0383169185917f7c2f48a4bf2e759e77b1e77a8bf1034cdf16e9034dad596d3655bb8b315f85eb9181900360200190a3505050565b600060606000806000806000806116c2611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d602081101561172957600080fd5b5051600160a060020a0316331461173f57600080fd5b88975087151561174e57611897565b611756611a47565b9650600095505b865186101561189757868681518110151561177457fe5b9060200190602002015194504361178a866107da565b10801561179d575061179b85610bc7565b155b1561188c576117ab856113c8565b1561188c576000935060009250600091505b87821015611866576117ea858b8b858181106117d557fe5b90506020020135600160a060020a0316610947565b905060018114156118305761182961181c8b8b8581811061180757fe5b90506020020135600160a060020a031661213d565b859063ffffffff61221516565b935061185b565b600281141561185b5761185861184b8b8b8581811061180757fe5b849063ffffffff61221516565b92505b6001909101906117bd565b6118708585612232565b61187a8584612306565b61188385612397565b61188c85612561565b60019095019461175d565b50505050505050505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000803361194281611156565b151561194d57600080fd5b88886000821161195c57600080fd5b6000811161196957600080fd5b611971611ea3565b81101561197d57600080fd5b611985611425565b81111561199157600080fd5b600160a060020a03881615156119a657600080fd5b6119af89611e1f565b15156119ba57600080fd5b6119f58b8b89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612645945050505050565b9350611a018489612742565b611a0b848a61283e565b50919998505050505050505050565b6000600160a060020a0382161515611a3457506000610a33565b611a3e8383610947565b15159392505050565b6060600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611aaa5780518252601f199092019160209182019101611a8b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015611b2a57602002820191906000526020600020905b815481526020019060010190808311611b16575b5050505050905090565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f72000000000000000000000000000000000000000000000000008152506007019150506040516020818303038152906040526040518082805190602001908083835b60208310611bc75780518252601f199092019160209182019101611ba8565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031695945050505050565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d0191505060405160208183030381529060405260405180828051906020019080838360208310611bc75780518252601f199092019160209182019101611ba8565b6000600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611d065780518252601f199092019160209182019101611ce7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050611d4f57fe5b90600052602060002001549050919050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310611dd65780518252601f199092019160209182019101611db7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000611e29611d61565b600160a060020a03166333875fdd836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015611e7157600080fd5b505af1158015611e85573d6000803e3d6000fd5b505050506040513d6020811015611e9b57600080fd5b505192915050565b600290565b6000600260008360405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000806000611f526128cf565b9150811515611f645760649250611f86565b611f7560648363ffffffff6129d016565b9050801515611f82575060015b8092505b505090565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611fff5780518252601f199092019160209182019101611fe0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b604080516000805160206138a7833981519152602080830191909152602b82018690527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0386160260518301528251604581840301815260659092019283905281518493600293600093909282918401908083835b602083106120fa5780518252601f1990920191602091820191016120db565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050565b6000612147611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561218457600080fd5b505af1158015612198573d6000803e3d6000fd5b505050506040513d60208110156121ae57600080fd5b5051604080517fbf135267000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163bf1352679160248083019260209291908290030181600087803b158015611e7157600080fd5b60008282018381101561222757600080fd5b8091505b5092915050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106122c45780518252601f1990920191602091820191016122a5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a6563746564000000000000000000000000000000000000000000000000815250600801915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b61239f611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050506040513d602081101561240657600080fd5b5051604080517f94409a560000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916394409a56916004808201926020929091908290030181600087803b15801561246557600080fd5b505af1158015612479573d6000803e3d6000fd5b505050506040513d602081101561248f57600080fd5b5051604080516000805160206138a7833981519152602082810191909152602b82018590527f746f74616c5374616b6500000000000000000000000000000000000000000000604b83015282516035818403018152605590920192839052815160029360009392909182918401908083835b602083106125205780518252601f199092019160209182019101612501565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b61256a81610bc7565b151561258257612579816129f3565b61258281612a27565b61258b81612aa3565b156125ec5761259981611062565b6125a282610a39565b11156125d1576125b181612ad4565b156125c7576125c28160025b612b50565b6125cc565b612642565b6125dc565b6125dc8160036125bd565b6125e7816000612be1565b612602565b6125f7816001612be1565b6126028160036125bd565b61260b81612cc1565b612616816001612d16565b60405181907fd470bb0d3dcb39ff5a62757e0a1cdfe60f8200eba22fd0d82383630d457f868690600090a25b50565b6000806000612652610c55565b151561265d57600080fd5b33915061266982612da7565b151561267457600080fd5b61267c610d0e565b905061269761269282600163ffffffff61221516565b612dc1565b6126a18187612e34565b6126ab81866130bd565b6126b6816000612d16565b6126c18160016125bd565b6126cb81836132b5565b6126d58185613346565b6126e6816126e16110f4565b613426565b6126f1816000612be1565b6126fa816134b7565b6127038261356c565b604051600160a060020a0383169082907fe64b3864f6f22f8969f8cb16c039eaf6454ef5e23c09791df010163000a7023590600090a395945050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d019150506040516020818303038152906040526040518082805190602001908083835b602083106127d45780518252601f1990920191602091820191016127b5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0395909516949094179093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b60006128d9611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b505050506040513d602081101561294057600080fd5b5051604080517f40c9cdeb0000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916340c9cdeb916004808201926020929091908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b5051905090565b6000808083116129df57600080fd5b82848115156129ea57fe5b04949350505050565b6000806129ff83611b34565b9150612a0a82611ea8565b90506000811115612a2257612a22826001830361358a565b505050565b6001600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310611fff5780518252601f199092019160209182019101611fe0565b600080600080612ab285610dc3565b92506127106107d08402049150612ac885610a39565b91909111949350505050565b6000612ade611d61565b600160a060020a031663bb0165b1612af5846118a3565b612afe85611c11565b6040518363ffffffff1660e060020a0281526004018083815260200182600160a060020a0316600160a060020a0316815260200192505050602060405180830381600087803b158015611e7157600080fd5b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083835b60208310612c735780518252601f199092019160209182019101612c54565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff1916941515949094179093555050505050565b6000806000612ccf84611572565b92506001612cdb6110f4565b039150612ce782611ca3565b9050612cf38382613626565b612cfd8184613426565b612d08826000613626565b612d106136e1565b50505050565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0191505060405160208183030381529060405260405180828051906020019080838360208310612c735780518252601f199092019160209182019101612c54565b6000612db1611f45565b612dba83611ea8565b1092915050565b806002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c019050604051602081830303815290604052604051808280519060200190808383602083106125205780518252601f199092019160209182019101612501565b600080600080612e42611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612e7f57600080fd5b505af1158015612e93573d6000803e3d6000fd5b505050506040513d6020811015612ea957600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051919550600160a060020a0386169163a6524923916004808201926020929091908290030181600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506040513d6020811015612f3457600080fd5b5051604080517faf2951810000000000000000000000000000000000000000000000000000000081529051919450600160a060020a0386169163af295181916004808201926020929091908290030181600087803b158015612f9557600080fd5b505af1158015612fa9573d6000803e3d6000fd5b505050506040513d6020811015612fbf57600080fd5b50519150612fe3612fd6868563ffffffff6137a016565b839063ffffffff61221516565b905080600260008860405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b602083106130775780518252601f199092019160209182019101613058565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050505050565b60008060006130ca611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561310757600080fd5b505af115801561311b573d6000803e3d6000fd5b505050506040513d602081101561313157600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163a6524923916004808201926020929091908290030181600087803b15801561319057600080fd5b505af11580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b505192506131c7856107da565b91506131dc612fd6858563ffffffff6137a016565b905080600260008760405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106132705780518252601f199092019160209182019101613251565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f7200000000000000000000000000000000000000000000000000815250600701915050604051602081830303815290604052604051808280519060200190808383602083106127d45780518252601f1990920191602091820191016127b5565b80600360008460405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b602083106133d85780518252601f1990920191602091820191016133b9565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451612a229591945092019190506137ce565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f696e646578000000000000000000000000000000000000000000000000000000815250600501915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106135185780518252601f1990920191602091820191016134f9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509290920160009081208054600181018255908252939020909201929092555050565b6126428161358a600161357e85611ea8565b9063ffffffff61221516565b80600260008460405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106136885780518252601f199092019160209182019101613669565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350869250821090506136d157fe5b6000918252602090912001555050565b60006136eb6110f4565b11156113c657600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106137525780518252601f199092019160209182019101613733565b51815160001960209485036101000a8101918216911992909216179091526040805195909301859003909420875286019690965250929093016000208054935061264292909150830161384c565b6000808315156137b3576000915061222b565b508282028284828115156137c357fe5b041461222757600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061380f57805160ff191683800117855561383c565b8280016001018555821561383c579182015b8281111561383c578251825591602001919060010190613821565b5061384892915061386c565b5090565b815481835581811115612a2257600083815260209020612a229181019083015b610d0b91905b808211156138485760008155600101613872560061637469766542616c6c6f747300000000000000000000000000000000000000766f74696e675374617465000000000000000000000000000000000000000000a165627a7a723058208d70072ebed43198b496d8e8560f428fa5f8fefd60a01bc2bd679521aeb93a290029

Deployed ByteCode

0x6080604052600436106101d45763ffffffff60e060020a60003504166301b2320e81146101d957806308dbb18e146102035780630af58e771461021b5780630eac27f41461023057806322e5fe9d1461025457806323e1a0a81461026c5780632b592f92146102985780632dfba528146102b05780632e0f2625146102c8578063340d3dc2146102dd578063392e53cd146102f25780633ee2f2121461030757806345367f231461031c578063480ca380146103345780634925ec551461034957806360970b6f146103d657806362f4c26b146103ee5780636ccc02341461040657806377da79301461041b5780638129fc1c1461043c57806382c4c96314610453578063897ba3e41461046b5780638be774d3146104805780638c64a20d146104955780638c8ab7ad146105b95780638e7cb6e1146105d1578063b384abef146105e9578063bbac62c814610604578063bdd4ae5514610624578063c12eefd21461063c578063c14bfd2914610675578063d21dc68a14610699578063d48e638a146106fe578063d6edcb3814610732578063df0444771461074a578063ec15a5e614610762578063edaab22314610777578063f3161a4d1461078f578063f49774ee146107a4578063fcff021c146107c5575b600080fd5b3480156101e557600080fd5b506101f16004356107da565b60408051918252519081900360200190f35b34801561020f57600080fd5b506101f16004356108b0565b34801561022757600080fd5b506101f1610942565b34801561023c57600080fd5b506101f1600435600160a060020a0360243516610947565b34801561026057600080fd5b506101f1600435610a39565b34801561027857600080fd5b50610284600435610acb565b604080519115158252519081900360200190f35b3480156102a457600080fd5b50610284600435610ba2565b3480156102bc57600080fd5b50610284600435610bc7565b3480156102d457600080fd5b506101f1610c43565b3480156102e957600080fd5b506101f1610c4f565b3480156102fe57600080fd5b50610284610c55565b34801561031357600080fd5b506101f1610d0e565b34801561032857600080fd5b506101f1600435610dc3565b34801561034057600080fd5b506101f1610e55565b34801561035557600080fd5b50610361600435610e5a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039b578181015183820152602001610383565b50505050905090810190601f1680156103c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103e257600080fd5b50610284600435610fd0565b3480156103fa57600080fd5b506101f1600435611062565b34801561041257600080fd5b506101f16110f4565b34801561042757600080fd5b50610284600160a060020a0360043516611156565b34801561044857600080fd5b506104516112e6565b005b34801561045f57600080fd5b506102846004356113c8565b34801561047757600080fd5b506101f1611420565b34801561048c57600080fd5b506101f1611425565b3480156104a157600080fd5b506104b9600435600160a060020a036024351661142a565b604051808e81526020018d81526020018c1515151581526020018b600160a060020a0316600160a060020a031681526020018a815260200189600160a060020a0316600160a060020a0316815260200180602001881515151581526020018715151515815260200186151515158152602001858152602001848152602001838152602001828103825289818151815260200191508051906020019080838360005b8381101561057257818101518382015260200161055a565b50505050905090810190601f16801561059f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060405180910390f35b3480156105c557600080fd5b506101f16004356114e0565b3480156105dd57600080fd5b506101f1600435611572565b3480156105f557600080fd5b50610451600435602435611604565b34801561061057600080fd5b5061045160048035602481019101356116ad565b34801561063057600080fd5b506101f16004356118a3565b34801561064857600080fd5b506101f16004803590602480359160443591600160a060020a036064351691608435918201910135611935565b34801561068157600080fd5b50610284600435600160a060020a0360243516611a1a565b3480156106a557600080fd5b506106ae611a47565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ea5781810151838201526020016106d2565b505050509050019250505060405180910390f35b34801561070a57600080fd5b50610716600435611b34565b60408051600160a060020a039092168252519081900360200190f35b34801561073e57600080fd5b50610716600435611c11565b34801561075657600080fd5b506101f1600435611ca3565b34801561076e57600080fd5b50610716611d61565b34801561078357600080fd5b50610284600435611e1f565b34801561079b57600080fd5b506101f1611ea3565b3480156107b057600080fd5b506101f1600160a060020a0360043516611ea8565b3480156107d157600080fd5b506101f1611f45565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b6020831061086d5780518252601f19909201916020918201910161084e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b919050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600281565b604080516000805160206138a7833981519152602080830191909152602b82018590527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0385160260518301528251604581840301815260659092019283905281516000936002938593909282918401908083835b602083106109f55780518252601f1990920191602091820191016109d6565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205493505050505b92915050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610b5e5780518252601f199092019160209182019101610b3f565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1695945050505050565b600043610bae836107da565b108015610a335750610bbf826114e0565b431092915050565b6000600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b670de0b6b3a764000081565b6107d081565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610cca5780518252601f199092019160209182019101610cab565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1693505050505b90565b60006002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310610d835780518252601f199092019160209182019101610d64565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054949350505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f746f74616c5374616b6500000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600e81565b6060600360008360405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b60208310610eed5780518252601f199092019160209182019101610ece565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019166000191681526020019081526020016000208054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610fc45780601f10610f9957610100808354040283529160200191610fc4565b820191906000526020600020905b815481529060010190602001808311610fa757829003601f168201915b50505050509050919050565b6000600660008360405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c0191505060405160208183030381529060405260405180828051906020019080838360208310610b5e5780518252601f199092019160209182019101610b3f565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a65637465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600860006040516020018080600080516020613887833981519152815250600d01905060405160208183030381529060405260405180828051906020019080838360208310610d835780518252601f199092019160209182019101610d64565b600080808080611164611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b505192505b82600160a060020a03166340c9cdeb6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561120e57600080fd5b505af1158015611222573d6000803e3d6000fd5b505050506040513d602081101561123857600080fd5b50518210156112dc5782600160a060020a03166357aeefc5836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b50519050600160a060020a0380821690871614156112d157600193505b6001909101906111d0565b5091949350505050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106113595780518252601f19909201916020918201910161133a565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316331492506113aa91505057600080fd5b6113b2610c55565b156113bc57600080fd5b6113c66001611f8b565b565b60006113d2610d0e565b82106113e0575060006108ab565b436113ea836107da565b11156113f8575060006108ab565b61140182610acb565b1561140e575060006108ab565b611417826114e0565b43101592915050565b606481565b600e90565b60008060008060008060606000806000806000806114478f6107da565b9c506114528f6114e0565b9b5061145d8f610acb565b9a506114688f611c11565b99506114738f6118a3565b985061147e8f611b34565b97506114898f610e5a565b96506114948f6113c8565b95506114a08f8f611a1a565b94506114ab8f610fd0565b93506114b68f610a39565b92506114c18f611062565b91506114cc8f610dc3565b90509295989b9e9194979a9d509295989b50565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f696e6465780000000000000000000000000000000000000000000000000000008152506005019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b600061160f83610acb565b1561161957600080fd5b503361162483610ba2565b151561162f57600080fd5b6116398382611a1a565b1561164357600080fd5b60018214806116525750600282145b151561165d57600080fd5b61166883828461204c565b604080518381529051600160a060020a0383169185917f7c2f48a4bf2e759e77b1e77a8bf1034cdf16e9034dad596d3655bb8b315f85eb9181900360200190a3505050565b600060606000806000806000806116c2611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156116ff57600080fd5b505af1158015611713573d6000803e3d6000fd5b505050506040513d602081101561172957600080fd5b5051600160a060020a0316331461173f57600080fd5b88975087151561174e57611897565b611756611a47565b9650600095505b865186101561189757868681518110151561177457fe5b9060200190602002015194504361178a866107da565b10801561179d575061179b85610bc7565b155b1561188c576117ab856113c8565b1561188c576000935060009250600091505b87821015611866576117ea858b8b858181106117d557fe5b90506020020135600160a060020a0316610947565b905060018114156118305761182961181c8b8b8581811061180757fe5b90506020020135600160a060020a031661213d565b859063ffffffff61221516565b935061185b565b600281141561185b5761185861184b8b8b8581811061180757fe5b849063ffffffff61221516565b92505b6001909101906117bd565b6118708585612232565b61187a8584612306565b61188385612397565b61188c85612561565b60019095019461175d565b50505050505050505050565b6000600260008360405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000803361194281611156565b151561194d57600080fd5b88886000821161195c57600080fd5b6000811161196957600080fd5b611971611ea3565b81101561197d57600080fd5b611985611425565b81111561199157600080fd5b600160a060020a03881615156119a657600080fd5b6119af89611e1f565b15156119ba57600080fd5b6119f58b8b89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612645945050505050565b9350611a018489612742565b611a0b848a61283e565b50919998505050505050505050565b6000600160a060020a0382161515611a3457506000610a33565b611a3e8383610947565b15159392505050565b6060600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611aaa5780518252601f199092019160209182019101611a8b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002080548451818702810187019095528085529394909392508401905082828015611b2a57602002820191906000526020600020905b815481526020019060010190808311611b16575b5050505050905090565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f72000000000000000000000000000000000000000000000000008152506007019150506040516020818303038152906040526040518082805190602001908083835b60208310611bc75780518252601f199092019160209182019101611ba8565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031695945050505050565b6000600460008360405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d0191505060405160208183030381529060405260405180828051906020019080838360208310611bc75780518252601f199092019160209182019101611ba8565b6000600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611d065780518252601f199092019160209182019101611ce7565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805490935085925082109050611d4f57fe5b90600052602060002001549050919050565b60006004600060405160200180807f70726f787953746f726167650000000000000000000000000000000000000000815250600c0190506040516020818303038152906040526040518082805190602001908083835b60208310611dd65780518252601f199092019160209182019101611db7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b6000611e29611d61565b600160a060020a03166333875fdd836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b158015611e7157600080fd5b505af1158015611e85573d6000803e3d6000fd5b505050506040513d6020811015611e9b57600080fd5b505192915050565b600290565b6000600260008360405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040526040518082805190602001908083836020831061086d5780518252601f19909201916020918201910161084e565b6000806000611f526128cf565b9150811515611f645760649250611f86565b611f7560648363ffffffff6129d016565b9050801515611f82575060015b8092505b505090565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310611fff5780518252601f199092019160209182019101611fe0565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff19169415159490941790935550505050565b604080516000805160206138a7833981519152602080830191909152602b82018690527f766f746572730000000000000000000000000000000000000000000000000000604b8301526c01000000000000000000000000600160a060020a0386160260518301528251604581840301815260659092019283905281518493600293600093909282918401908083835b602083106120fa5780518252601f1990920191602091820191016120db565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050565b6000612147611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561218457600080fd5b505af1158015612198573d6000803e3d6000fd5b505050506040513d60208110156121ae57600080fd5b5051604080517fbf135267000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163bf1352679160248083019260209291908290030181600087803b158015611e7157600080fd5b60008282018381101561222757600080fd5b8091505b5092915050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f61636365707465640000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106122c45780518252601f1990920191602091820191016122a5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f72656a6563746564000000000000000000000000000000000000000000000000815250600801915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b61239f611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156123dc57600080fd5b505af11580156123f0573d6000803e3d6000fd5b505050506040513d602081101561240657600080fd5b5051604080517f94409a560000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916394409a56916004808201926020929091908290030181600087803b15801561246557600080fd5b505af1158015612479573d6000803e3d6000fd5b505050506040513d602081101561248f57600080fd5b5051604080516000805160206138a7833981519152602082810191909152602b82018590527f746f74616c5374616b6500000000000000000000000000000000000000000000604b83015282516035818403018152605590920192839052815160029360009392909182918401908083835b602083106125205780518252601f199092019160209182019101612501565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000209390935550505050565b61256a81610bc7565b151561258257612579816129f3565b61258281612a27565b61258b81612aa3565b156125ec5761259981611062565b6125a282610a39565b11156125d1576125b181612ad4565b156125c7576125c28160025b612b50565b6125cc565b612642565b6125dc565b6125dc8160036125bd565b6125e7816000612be1565b612602565b6125f7816001612be1565b6126028160036125bd565b61260b81612cc1565b612616816001612d16565b60405181907fd470bb0d3dcb39ff5a62757e0a1cdfe60f8200eba22fd0d82383630d457f868690600090a25b50565b6000806000612652610c55565b151561265d57600080fd5b33915061266982612da7565b151561267457600080fd5b61267c610d0e565b905061269761269282600163ffffffff61221516565b612dc1565b6126a18187612e34565b6126ab81866130bd565b6126b6816000612d16565b6126c18160016125bd565b6126cb81836132b5565b6126d58185613346565b6126e6816126e16110f4565b613426565b6126f1816000612be1565b6126fa816134b7565b6127038261356c565b604051600160a060020a0383169082907fe64b3864f6f22f8969f8cb16c039eaf6454ef5e23c09791df010163000a7023590600090a395945050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f70726f706f73656456616c756500000000000000000000000000000000000000815250600d019150506040516020818303038152906040526040518082805190602001908083835b602083106127d45780518252601f1990920191602091820191016127b5565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0395909516949094179093555050505050565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f636f6e7472616374547970650000000000000000000000000000000000000000815250600c01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b60006128d9611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561291657600080fd5b505af115801561292a573d6000803e3d6000fd5b505050506040513d602081101561294057600080fd5b5051604080517f40c9cdeb0000000000000000000000000000000000000000000000000000000081529051600160a060020a03909216916340c9cdeb916004808201926020929091908290030181600087803b15801561299f57600080fd5b505af11580156129b3573d6000803e3d6000fd5b505050506040513d60208110156129c957600080fd5b5051905090565b6000808083116129df57600080fd5b82848115156129ea57fe5b04949350505050565b6000806129ff83611b34565b9150612a0a82611ea8565b90506000811115612a2257612a22826001830361358a565b505050565b6001600660008360405160200180807f66696e616c697a6543616c6c6564000000000000000000000000000000000000815250600e0182815260200191505060405160208183030381529060405260405180828051906020019080838360208310611fff5780518252601f199092019160209182019101611fe0565b600080600080612ab285610dc3565b92506127106107d08402049150612ac885610a39565b91909111949350505050565b6000612ade611d61565b600160a060020a031663bb0165b1612af5846118a3565b612afe85611c11565b6040518363ffffffff1660e060020a0281526004018083815260200182600160a060020a0316600160a060020a0316815260200192505050602060405180830381600087803b158015611e7157600080fd5b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f71756f72756d5374617465000000000000000000000000000000000000000000815250600b01915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f62656c6f775475726e4f75740000000000000000000000000000000000000000815250600c019150506040516020818303038152906040526040518082805190602001908083835b60208310612c735780518252601f199092019160209182019101612c54565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff1916941515949094179093555050505050565b6000806000612ccf84611572565b92506001612cdb6110f4565b039150612ce782611ca3565b9050612cf38382613626565b612cfd8184613426565b612d08826000613626565b612d106136e1565b50505050565b80600660008460405160200180806000805160206138a7833981519152815250600b01828152602001807f697346696e616c697a6564000000000000000000000000000000000000000000815250600b0191505060405160208183030381529060405260405180828051906020019080838360208310612c735780518252601f199092019160209182019101612c54565b6000612db1611f45565b612dba83611ea8565b1092915050565b806002600060405160200180807f6e65787442616c6c6f7449640000000000000000000000000000000000000000815250600c019050604051602081830303815290604052604051808280519060200190808383602083106125205780518252601f199092019160209182019101612501565b600080600080612e42611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612e7f57600080fd5b505af1158015612e93573d6000803e3d6000fd5b505050506040513d6020811015612ea957600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051919550600160a060020a0386169163a6524923916004808201926020929091908290030181600087803b158015612f0a57600080fd5b505af1158015612f1e573d6000803e3d6000fd5b505050506040513d6020811015612f3457600080fd5b5051604080517faf2951810000000000000000000000000000000000000000000000000000000081529051919450600160a060020a0386169163af295181916004808201926020929091908290030181600087803b158015612f9557600080fd5b505af1158015612fa9573d6000803e3d6000fd5b505050506040513d6020811015612fbf57600080fd5b50519150612fe3612fd6868563ffffffff6137a016565b839063ffffffff61221516565b905080600260008860405160200180806000805160206138a7833981519152815250600b01828152602001807f7374617274426c6f636b00000000000000000000000000000000000000000000815250600a019150506040516020818303038152906040526040518082805190602001908083835b602083106130775780518252601f199092019160209182019101613058565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002093909355505050505050505050565b60008060006130ca611d61565b600160a060020a031663179e740b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561310757600080fd5b505af115801561311b573d6000803e3d6000fd5b505050506040513d602081101561313157600080fd5b5051604080517fa65249230000000000000000000000000000000000000000000000000000000081529051600160a060020a039092169163a6524923916004808201926020929091908290030181600087803b15801561319057600080fd5b505af11580156131a4573d6000803e3d6000fd5b505050506040513d60208110156131ba57600080fd5b505192506131c7856107da565b91506131dc612fd6858563ffffffff6137a016565b905080600260008760405160200180806000805160206138a7833981519152815250600b01828152602001807f656e64426c6f636b0000000000000000000000000000000000000000000000008152506008019150506040516020818303038152906040526040518082805190602001908083835b602083106132705780518252601f199092019160209182019101613251565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050505050565b80600460008460405160200180806000805160206138a7833981519152815250600b01828152602001807f63726561746f7200000000000000000000000000000000000000000000000000815250600701915050604051602081830303815290604052604051808280519060200190808383602083106127d45780518252601f1990920191602091820191016127b5565b80600360008460405160200180806000805160206138a7833981519152815250600b01828152602001807f6465736372697074696f6e000000000000000000000000000000000000000000815250600b019150506040516020818303038152906040526040518082805190602001908083835b602083106133d85780518252601f1990920191602091820191016133b9565b51815160001960209485036101000a01908116901991909116179052604080519490920184900390932086528583019690965250929093016000208451612a229591945092019190506137ce565b80600260008460405160200180806000805160206138a7833981519152815250600b01828152602001807f696e646578000000000000000000000000000000000000000000000000000000815250600501915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106135185780518252601f1990920191602091820191016134f9565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509290920160009081208054600181018255908252939020909201929092555050565b6126428161358a600161357e85611ea8565b9063ffffffff61221516565b80600260008460405160200180807f76616c696461746f7241637469766542616c6c6f74730000000000000000000081525060160182600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052604051808280519060200190808383602083106122c45780518252601f1990920191602091820191016122a5565b80600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106136885780518252601f199092019160209182019101613669565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000208054909350869250821090506136d157fe5b6000918252602090912001555050565b60006136eb6110f4565b11156113c657600860006040516020018080600080516020613887833981519152815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106137525780518252601f199092019160209182019101613733565b51815160001960209485036101000a8101918216911992909216179091526040805195909301859003909420875286019690965250929093016000208054935061264292909150830161384c565b6000808315156137b3576000915061222b565b508282028284828115156137c357fe5b041461222757600080fd5b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061380f57805160ff191683800117855561383c565b8280016001018555821561383c579182015b8281111561383c578251825591602001919060010190613821565b5061384892915061386c565b5090565b815481835581811115612a2257600083815260209020612a229181019083015b610d0b91905b808211156138485760008155600101613872560061637469766542616c6c6f747300000000000000000000000000000000000000766f74696e675374617465000000000000000000000000000000000000000000a165627a7a723058208d70072ebed43198b496d8e8560f428fa5f8fefd60a01bc2bd679521aeb93a290029