diff --git a/controls/cluster/Clusterkeys.sol b/controls/cluster/Clusterkeys.sol index 8f7dbcd66..a51af58ca 100644 --- a/controls/cluster/Clusterkeys.sol +++ b/controls/cluster/Clusterkeys.sol @@ -6,6 +6,7 @@ contract Clusterkeys { enum Operation {None, Add, Delete} struct OrgDetails { string orgId; + string vorgId; string [] privateKey; string pendingKey; Operation pendingOp; @@ -17,6 +18,7 @@ contract Clusterkeys { struct OrgVoterDetails { string orgId; address [] orgVoterAccount; + string [] privateKey; } OrgVoterDetails [] private voterList; mapping(bytes32 => uint) private VoterOrgIndex; @@ -67,9 +69,10 @@ contract Clusterkeys { // checks if the sender is one of the registered voter account for the org modifier canVote(string _orgId){ bool flag = false; - uint orgIndex = getOrgIndexVoter(_orgId); - for (uint i = 0; i < voterList[orgIndex].orgVoterAccount.length; i++){ - if ( voterList[orgIndex].orgVoterAccount[i] == msg.sender){ + uint orgIndex = getOrgIndex(_orgId); + uint vorgIndex = getOrgIndexVoter(orgList[orgIndex].vorgId); + for (uint i = 0; i < voterList[vorgIndex].orgVoterAccount.length; i++){ + if ( voterList[vorgIndex].orgVoterAccount[i] == msg.sender){ flag = true; break; } @@ -82,7 +85,8 @@ contract Clusterkeys { // checks if the org has any voter accounts set up or not function checkIfVoterExists(string _orgId, address _address) internal view returns (bool, uint){ bool keyExists = false; - uint voterIndex = getOrgIndexVoter(_orgId); + uint orgIndex = getOrgIndex(_orgId); + uint voterIndex = getOrgIndexVoter(orgList[orgIndex].vorgId); for (uint i = 0; i < voterList[voterIndex].orgVoterAccount.length; i++){ if(keccak256(abi.encodePacked(voterList[voterIndex].orgVoterAccount[i])) == keccak256(abi.encodePacked(_address))){ keyExists = true; @@ -95,12 +99,14 @@ contract Clusterkeys { // checks if the voter account is already in the voter accounts list for the org function checkVotingAccountExists(string _orgId) internal returns (bool) { - if (VoterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0){ + + uint orgIndex = getOrgIndex(_orgId); + if (VoterOrgIndex[keccak256(abi.encodePacked(orgList[orgIndex].vorgId))] == 0){ emit NoVotingAccount(_orgId); return false; } - uint orgIndex = getOrgIndexVoter(_orgId); - if (voterList[orgIndex].orgVoterAccount.length == 0) { + uint vorgIndex = getOrgIndexVoter(orgList[orgIndex].vorgId); + if (voterList[vorgIndex].orgVoterAccount.length == 0) { emit NoVotingAccount(_orgId); return false; } @@ -133,13 +139,13 @@ contract Clusterkeys { return (keyExists, i); } - // function for adding a voter account to a org + // function for adding a voter account to a master org function addVoter(string _orgId, address _address) external { if (VoterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) { orgVoterNum++; VoterOrgIndex[keccak256(abi.encodePacked(_orgId))] = orgVoterNum; - voterList.push( OrgVoterDetails(_orgId, new address[](0))); + voterList.push( OrgVoterDetails(_orgId, new address[](0), new string[](0))); voterList[orgVoterNum - 1].orgVoterAccount.push(_address); emit VoterAdded(_orgId, _address); } @@ -158,7 +164,7 @@ contract Clusterkeys { } } - // function for deleting a voter account to a org + // function for deleting a voter account to a master org function deleteVoter(string _orgId, address _address) external { if (VoterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) { @@ -184,13 +190,13 @@ contract Clusterkeys { // function for adding a private key for the org. Thsi will be added once // approval process is complete - function addOrgKey(string _orgId, string _privateKey) external + function addOrgKey(string _orgId, string _morgId, string _privateKey) external { if (checkVotingAccountExists(_orgId)){ if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) { numberOfOrgs++; OrgIndex[keccak256(abi.encodePacked(_orgId))] = numberOfOrgs; - orgList.push( OrgDetails(_orgId, new string[](0), _privateKey, Operation.Add)); + orgList.push( OrgDetails(_orgId, _morgId, new string[](0), _privateKey, Operation.Add)); voterInit(_orgId); emit ItemForApproval(_orgId, Operation.Add, _privateKey); } @@ -267,16 +273,17 @@ contract Clusterkeys { // initialize the voter account votes to false. This will be called when a // new item is initiated for approval function voterInit(string _orgId) internal { - uint orgIndex = getOrgIndexVoter(_orgId); - for (uint i = 0; i < voterList[orgIndex].orgVoterAccount.length; i++){ - voteStatus[orgIndex][voterList[orgIndex].orgVoterAccount[i]] = false; + uint orgIndex = getOrgIndex(_orgId); + uint vorgIndex = getOrgIndexVoter(orgList[orgIndex].vorgId); + for (uint i = 0; i < voterList[vorgIndex].orgVoterAccount.length; i++){ + voteStatus[orgIndex][voterList[vorgIndex].orgVoterAccount[i]] = false; } voteCount[orgIndex] = 0; } // processes the vote from the voter account. function processVote (string _orgId) internal { - uint orgIndex = getOrgIndexVoter(_orgId); + uint orgIndex = getOrgIndex(_orgId); if (voteStatus[orgIndex][msg.sender] == false ){ voteStatus[orgIndex][msg.sender] = true; voteCount[orgIndex]++; @@ -286,19 +293,75 @@ contract Clusterkeys { // checks if enough votes have been cast for the pending operation. If yes // returns true function checkEnoughVotes (string _orgId) internal view returns (bool) { - uint orgIndex = getOrgIndexVoter(_orgId); + uint orgIndex = getOrgIndex(_orgId); if (voteCount[orgIndex] > voterList[orgIndex].orgVoterAccount.length / 2 ){ return true; } return false; } + function checkKeyInUse(string _orgId, string _vorgId, string _key) internal view returns (bool) { + bool keyInUse = false; + for (uint i = 0; i < orgList.length; i++){ + if (keccak256(abi.encodePacked(orgList[i].orgId)) == keccak256(abi.encodePacked(_orgId))){ + continue; + } + if (keccak256(abi.encodePacked(orgList[i].vorgId)) == keccak256(abi.encodePacked(_vorgId))){ + for (uint j = 0; j < orgList[i].privateKey.length; j++){ + if (keccak256(abi.encodePacked(orgList[i].privateKey[j])) == keccak256(abi.encodePacked(_key))){ + keyInUse = true; + break; + } + } + } + if (keyInUse == true) { + return true; + } + } + return false; + } + // updates the master keys list with the key being added or deleted + function masterKeyUpdate(string _orgId, string _vorgId, string _key, Operation _op) internal { + uint vorgIndex = getOrgIndexVoter(_vorgId); + if (_op == Operation.Add) { + // check if the key is existing. if yes ignore else add to master list + bool keyExists = false; + for (uint i = 0; i < voterList[vorgIndex].privateKey.length; i++){ + if(keccak256(abi.encodePacked(orgList[vorgIndex].privateKey[i])) == keccak256(abi.encodePacked(_key))){ + keyExists = true; + break; + } + } + if (keyExists == false ){ + voterList[vorgIndex].privateKey.push(_key); + } + } + else { + // the key can be deleted from master list only when none of the suborgs have the + // key in the private keys + if (!(checkKeyInUse(_orgId, _vorgId, _key))){ + uint index; + for (index = 0; i < voterList[vorgIndex].privateKey.length; index++) { + if(keccak256(abi.encodePacked(voterList[vorgIndex].privateKey[index])) == keccak256(abi.encodePacked(_key))) { + break; + } + } + for (uint j = index; j < voterList[vorgIndex].privateKey.length -1; j++){ + voterList[vorgIndex].privateKey[j] = voterList[vorgIndex].privateKey[j+1]; + } + delete voterList[vorgIndex].privateKey[voterList[vorgIndex].privateKey.length -1]; + voterList[vorgIndex].privateKey.length --; + } + } + } + // function to process the approavl for add or delete function processApproval(uint _orgIndex) internal { if(checkEnoughVotes(orgList[_orgIndex].orgId)){ string storage locKey = orgList[_orgIndex].pendingKey; if (orgList[_orgIndex].pendingOp == Operation.Add){ orgList[_orgIndex].privateKey.push(orgList[_orgIndex].pendingKey); + masterKeyUpdate(orgList[_orgIndex].orgId, orgList[_orgIndex].vorgId, orgList[_orgIndex].pendingKey, Operation.Add); emit OrgKeyAdded(orgList[_orgIndex].orgId, locKey); } else { @@ -310,6 +373,7 @@ contract Clusterkeys { } delete orgList[_orgIndex].privateKey[orgList[_orgIndex].privateKey.length -1]; orgList[_orgIndex].privateKey.length --; + masterKeyUpdate(orgList[_orgIndex].orgId, orgList[_orgIndex].vorgId, orgList[_orgIndex].pendingKey, Operation.Delete); emit OrgKeyDeleted(orgList[_orgIndex].orgId, locKey); } orgList[_orgIndex].pendingOp = Operation.None; diff --git a/controls/cluster/abi/Clusterkeys.abi b/controls/cluster/abi/Clusterkeys.abi index fc11d8f9b..53bf8b327 100644 --- a/controls/cluster/abi/Clusterkeys.abi +++ b/controls/cluster/abi/Clusterkeys.abi @@ -1 +1 @@ -[{"constant":false,"inputs":[],"name":"printAllOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approvePendingOp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"deleteOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"addVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"deleteVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"printAllVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"addOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_voterAccount","type":"string"}],"name":"orgVoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"OrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAccountDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NoVotingAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"PendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_pendingOp","type":"uint8"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"ItemForApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NothingToApprove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"PrintAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_voterAccount","type":"address"}],"name":"PrintVoter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_pendingOp","type":"uint8"},{"indexed":false,"name":"_pendingKey","type":"string"}],"name":"PrintKey","type":"event"}] \ No newline at end of file +[{"constant":false,"inputs":[],"name":"printAllOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approvePendingOp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_morgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"addOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"deleteOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"addVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"deleteVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"printAllVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"OrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"PendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_pendingOp","type":"uint8"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"ItemForApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NothingToApprove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NoVotingAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAccountDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"PrintAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_voterAccount","type":"address"}],"name":"PrintVoter","type":"event"}] \ No newline at end of file diff --git a/controls/cluster/abi/Clusterkeys.bin-runtime b/controls/cluster/abi/Clusterkeys.bin-runtime new file mode 100644 index 000000000..3d9e50001 --- /dev/null +++ b/controls/cluster/abi/Clusterkeys.bin-runtime @@ -0,0 +1 @@ +6080604052600436106100825763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632bbc5084811461008757806335dc47721461009e57806337c5345e146100be57806349379c50146100f65780635607395b1461012257806359cbd6fe1461015057806373f9cee01461017e575b600080fd5b34801561009357600080fd5b5061009c610193565b005b3480156100aa57600080fd5b5061009c6004803560248101910135610364565b3480156100ca57600080fd5b5061009c6024600480358281019290820135918135808301929082013591604435918201910135610681565b34801561010257600080fd5b5061009c6024600480358281019290820135918135918201910135610d46565b34801561012e57600080fd5b5061009c6024600480358281019291013590600160a060020a03903516611152565b34801561015c57600080fd5b5061009c6024600480358281019291013590600160a060020a039035166115eb565b34801561018a57600080fd5b5061009c6119c6565b6000805b600054821015610360575060005b60008054839081106101b357fe5b906000526020600020906005020160020180549050811015610355577f3d030f7cce2619e90f621cb560eb4327f74d9a412c2daa8bed5a892d759187ec6000838154811015156101ff57fe5b906000526020600020906005020160000160008481548110151561021f57fe5b90600052602060002090600502016002018381548110151561023d57fe5b60009182526020918290206040805181815285546002600182161561010002600019019091160491810182905292909101928291908201906060830190869080156102c95780601f1061029e576101008083540402835291602001916102c9565b820191906000526020600020905b8154815290600101906020018083116102ac57829003601f168201915b505083810382528454600260001961010060018416150201909116048082526020909101908590801561033d5780601f106103125761010080835404028352916020019161033d565b820191906000526020600020905b81548152906001019060200180831161032057829003601f168201915b505094505050505060405180910390a16001016101a5565b600190910190610197565b5050565b600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843750600094508493508392508291506103a9905085611b28565b925061046c6000848154811015156103bd57fe5b90600052602060002090600502016001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104625780601f1061043757610100808354040283529160200191610462565b820191906000526020600020905b81548152906001019060200180831161044557829003601f168201915b5050505050611c0a565b9150600090505b600280548390811061048157fe5b9060005260206000209060030201600101805490508110156104f85760028054339190849081106104ae57fe5b9060005260206000209060030201600101828154811015156104cc57fe5b600091825260209091200154600160a060020a031614156104f057600193506104f8565b600101610473565b83151561056657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4163636f756e742063616e6e6f7420766f746500000000000000000000000000604482015290519081900360640190fd5b61059f88888080601f01602080910402602001604051908101604052809392919081815260200183838082843750611c44945050505050565b15610626576105dd88888080601f01602080910402602001604051908101604052809392919081815260200183838082843750611b28945050505050565b955061061888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750611d82945050505050565b61062186611dee565b610677565b7fe820171ad1d64f6ca44bb0943acbac4c6085812bf91e8b79164629563980622888886040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a15b5050505050505050565b60008060006106bf89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612968945050505050565b15610d3b57600160008a8a604051602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b6020831061071e5780518252601f1990920191602091820191016106ff565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250610a5291505057600680546001908101918290556040516000908c908c90602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b602083106107c95780518252601f1990920191602091820191016107aa565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160009081209590955550508051601f8c01839004909202820160c090810190915260a082018b815282918d908d9081908501838280828437820191505050505050815260200189898080601f01602080910402602001604051908101604052809392919081815260200183838082843750505092845250506040805160008082526020828101909352919093019291506108a8565b60608152602001906001900390816108935790505b50815260200187878080601f01602080910402602001604051908101604052809392919081815260200183838082843750505092845250506001602092830181905284549081018086556000958652948390208451805160059093029091019361091793508492910190613d13565b5060208281015180516109309260018501920190613d13565b506040820151805161094c916002840191602090910190613d91565b5060608201518051610968916003840191602090910190613d13565b50608082015160048201805460ff1916600183600281111561098657fe5b02179055505050506109c789898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612bc8945050505050565b7f4475befcee492797e02530076fd7e138aa058eb3bcd028a9df5c0f2815ba9f4a8989600188886040518080602001856002811115610a0257fe5b60ff168152602001806020018381038352888882818152602001925080828437909101848103835285815260200190508585808284376040519201829003995090975050505050505050a1610d3b565b610a8b89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750611c44945050505050565b15610ae5577f2de31d28953221328a1c7e30a93fa15e0d8573128a8f6fa92cf66408a0403c9989896040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a1610d3b565b6000925060009150610b5489898080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8d018190048102820181019092528b815294508b93508a9250829150840183828082843750612ca8945050505050565b90935091508215610bd3577ffd2bb3c1cfc78c051cb1f0ed88147fb9348eba128a594dc66fbf35dc63fe692d8989878760405180806020018060200183810383528787828181526020019250808284379091018481038352858152602001905085858082843760405192018290039850909650505050505050a1610d3b565b610c0c89898080601f01602080910402602001604051908101604052809392919081815260200183838082843750611b28945050505050565b90508484600083815481101515610c1f57fe5b90600052602060002090600502016003019190610c3d929190613dea565b506001600082815481101515610c4f57fe5b60009182526020909120600460059092020101805460ff19166001836002811115610c7657fe5b0217905550610cb489898080601f01602080910402602001604051908101604052809392919081815260200183838082843750612bc8945050505050565b7f4475befcee492797e02530076fd7e138aa058eb3bcd028a9df5c0f2815ba9f4a8989600188886040518080602001856002811115610cef57fe5b60ff168152602001806020018381038352888882818152602001925080828437909101848103835285815260200190508585808284376040519201829003995090975050505050505050a15b505050505050505050565b6000806000610d8487878080601f01602080910402602001604051908101604052809392919081815260200183838082843750612968945050505050565b1561114957600160008888604051602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b60208310610de35780518252601f199092019160209182019101610dc4565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250610e7b915050577f0d426160118ead0b6900081fd1f08b0d9b626bd033ddd50cd7d24be253e11a8387876040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a1611149565b610eb487878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611c44945050505050565b15610f0e577f2de31d28953221328a1c7e30a93fa15e0d8573128a8f6fa92cf66408a0403c9987876040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a1611149565b610f4787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611b28945050505050565b92506000915060009050610fb887878080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8d018190048102820181019092528b815294508b93508a9250829150840183828082843750612ca8945050505050565b92509050600181151514156110f8578484600085815481101515610fd857fe5b90600052602060002090600502016003019190610ff6929190613dea565b50600260008481548110151561100857fe5b60009182526020909120600460059092020101805460ff1916600183600281111561102f57fe5b021790555061106d87878080601f01602080910402602001604051908101604052809392919081815260200183838082843750612bc8945050505050565b7f4475befcee492797e02530076fd7e138aa058eb3bcd028a9df5c0f2815ba9f4a87876002888860405180806020018560028111156110a857fe5b60ff168152602001806020018381038352888882818152602001925080828437909101848103835285815260200190508585808284376040519201829003995090975050505050505050a1611149565b7f1625cf45f71f82c8ccf66926c15856f85b1e08dbe285065512100db776fdeb2885856040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a15b50505050505050565b6000806000600360008787604051602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b602083106111b15780518252601f199092019160209182019101611192565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020541515925061144091505057600780546001019081905560405160039060009089908990602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b6020831061125d5780518252601f19909201916020918201910161123e565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652858101969096525092830160002094909455508051601f890183900490920282016080908101909152606082018881526002935082918a908a9081908501838280828437505050928452505060408051600080825260208083018452808601929092528251818152918201835291909301929150611315565b60608152602001906001900390816113005790505b509052815460018101808455600093845260209384902083518051929560039094029091019261134a92849290910190613d13565b5060208281015180516113639260018501920190613e58565b506040820151805161137f916002840191602090910190613d91565b50505050600260016007540381548110151561139757fe5b600091825260208083206001600390930201820180549283018155835291829020018054600160a060020a03871673ffffffffffffffffffffffffffffffffffffffff199091168117909155604080519283019190915280825281018690527f424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d345749087908790879080606081018585808284376040519201829003965090945050505050a16115e3565b600092506000915061148386868080601f016020809104026020016040519081016040528093929190818152602001838380828437508a9450612ed99350505050565b909350915082156114f45760408051600160a060020a03861660208201528181529081018690527f57c0436fcca42a02516ed36a118ab7196a853b19ae03db4cbe9d1f6ec5a8f30b9087908790879080606081018585808284376040519201829003965090945050505050a16115e3565b61152d86868080601f01602080910402602001604051908101604052809392919081815260200183838082843750611c0a945050505050565b905060028181548110151561153e57fe5b600091825260208083206001600390930201820180549283018155835291829020018054600160a060020a03871673ffffffffffffffffffffffffffffffffffffffff199091168117909155604080519283019190915280825281018690527f424f3ad05c61ea35cad66f22b70b1fad7250d8229921238078c401db36d345749087908790879080606081018585808284376040519201829003965090945050505050a15b505050505050565b600080600080600360008888604051602001808383808284378201915050925050506040516020818303038152906040526040518082805190602001908083835b6020831061164b5780518252601f19909201916020918201910161162c565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054151592506116e3915050577f0d426160118ead0b6900081fd1f08b0d9b626bd033ddd50cd7d24be253e11a8387876040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a1611149565b61171c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611c0a945050505050565b935061175987878080601f016020809104026020016040519081016040528093929190818152602001838380828437508b9450612ed99350505050565b90935091506001831515141561195c5750805b600160028581548110151561177d57fe5b9060005260206000209060030201600101805490500381101561184b5760028054859081106117a857fe5b9060005260206000209060030201600101816001018154811015156117c957fe5b60009182526020909120015460028054600160a060020a0390921691869081106117ef57fe5b90600052602060002090600302016001018281548110151561180d57fe5b6000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905560010161176c565b600280548590811061185957fe5b9060005260206000209060030201600101600160028681548110151561187b57fe5b9060005260206000209060030201600101805490500381548110151561189d57fe5b6000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916905560028054859081106118d157fe5b90600052602060002090600302016001018054809190600190036118f59190613ec6565b5060408051600160a060020a03871660208201528181529081018790527f192eeefa7720f7067bcc0a3f5bbcc2941c417a8761ec8b795d2941f3b0d2be179088908890889080606081018585808284376040519201829003965090945050505050a1611149565b60408051600160a060020a03871660208201528181529081018790527ffc25f65937d1cb43a570fb3b3c5d0bf0b69b4cdd2da44c56b9893e2d140359609088908890889080606081018585808284376040519201829003965090945050505050a150505050505050565b6000805b600254821015610360575060005b60028054839081106119e657fe5b906000526020600020906003020160010180549050811015611b1d577f0c0001a7636c2b95d29de23e25bb65060f9ad324f9f38b309f6f5659a6cb3165600283815481101515611a3257fe5b9060005260206000209060030201600001600284815481101515611a5257fe5b906000526020600020906003020160010183815481101515611a7057fe5b6000918252602091829020015460408051600160a060020a039092169282018390528082528354600260001960018316156101000201909116049082018190528190606082019085908015611b065780601f10611adb57610100808354040283529160200191611b06565b820191906000526020600020905b815481529060010190602001808311611ae957829003601f168201915b5050935050505060405180910390a16001016119d8565b6001909101906119ca565b60006001806000846040516020018082805190602001908083835b60208310611b625780518252601f199092019160209182019101611b43565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310611bc55780518252601f199092019160209182019101611ba6565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020549390930395945050505050565b60006001600360008460405160200180828051906020019080838360208310611b625780518252601f199092019160209182019101611b43565b60008060016000846040516020018082805190602001908083835b60208310611c7e5780518252601f199092019160209182019101611c5f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310611ce15780518252601f199092019160209182019101611cc2565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250611d2d9150505760009150611d7c565b611d3683611b28565b9050600080805483908110611d4757fe5b600091825260209091206004600590920201015460ff166002811115611d6957fe5b14611d775760019150611d7c565b600091505b50919050565b6000611d8d82611b28565b600081815260046020908152604080832033845290915290205490915060ff1615156103605760008181526004602090815260408083203384528252808320805460ff19166001908117909155938352600590915290208054909101905550565b600080600080611ea3600086815481101515611e0657fe5b6000918252602091829020600590910201805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611e995780601f10611e6e57610100808354040283529160200191611e99565b820191906000526020600020905b815481529060010190602001808311611e7c57829003601f168201915b50505050506130bf565b15612961576000805486908110611eb657fe5b60009182526020909120600360059092020101935060016000805487908110611edb57fe5b600091825260209091206004600590920201015460ff166002811115611efd57fe5b14156122de576000805486908110611f1157fe5b9060005260206000209060050201600201600086815481101515611f3157fe5b600091825260208083208454600180820180885596865292909420600593909302016003018054611f7d9493909301929091600260001991831615610100029190910190911604613eef565b5050612193600086815481101515611f9157fe5b6000918252602091829020600590910201805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156120245780601f10611ff957610100808354040283529160200191612024565b820191906000526020600020905b81548152906001019060200180831161200757829003601f168201915b505050505060008781548110151561203857fe5b90600052602060002090600502016001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156120dd5780601f106120b2576101008083540402835291602001916120dd565b820191906000526020600020905b8154815290600101906020018083116120c057829003601f168201915b50505050506000888154811015156120f157fe5b6000918252602091829020600360059092020101805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156121875780601f1061215c57610100808354040283529160200191612187565b820191906000526020600020905b81548152906001019060200180831161216a57829003601f168201915b5050505050600161311c565b7f6f4d370520782587dabc737a258f46de81ad45d733a42cd5a0045cff1e46deb46000868154811015156121c357fe5b60009182526020918290206040805181815260059093029091018054600260001961010060018416150201909116049183018290529288929182918201906060830190869080156122555780601f1061222a57610100808354040283529160200191612255565b820191906000526020600020905b81548152906001019060200180831161223857829003601f168201915b50508381038252845460026000196101006001841615020190911604808252602090910190859080156122c95780601f1061229e576101008083540402835291602001916122c9565b820191906000526020600020905b8154815290600101906020018083116122ac57829003601f168201915b505094505050505060405180910390a16128e5565b60009250600091506124206000868154811015156122f857fe5b6000918252602091829020600590910201805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561238b5780601f106123605761010080835404028352916020019161238b565b820191906000526020600020905b81548152906001019060200180831161236e57829003601f168201915b5050885460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815294508a935091508301828280156124165780601f106123eb57610100808354040283529160200191612416565b820191906000526020600020905b8154815290600101906020018083116123f957829003601f168201915b5050505050612ca8565b90935091508190505b600160008681548110151561243a57fe5b906000526020600020906005020160020180549050038110156124ef57600080548690811061246557fe5b90600052602060002090600502016002018160010181548110151561248657fe5b9060005260206000200160008681548110151561249f57fe5b9060005260206000209060050201600201828154811015156124bd57fe5b9060005260206000200190805460018160011615610100020316600290046124e6929190613eef565b50600101612429565b60008054869081106124fd57fe5b9060005260206000209060050201600201600160008781548110151561251f57fe5b9060005260206000209060050201600201805490500381548110151561254157fe5b9060005260206000200160006125579190613f64565b600080548690811061256557fe5b90600052602060002090600502016002018054809190600190036125899190613fab565b5061279e60008681548110151561259c57fe5b6000918252602091829020600590910201805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561262f5780601f106126045761010080835404028352916020019161262f565b820191906000526020600020905b81548152906001019060200180831161261257829003601f168201915b505050505060008781548110151561264357fe5b90600052602060002090600502016001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156126e85780601f106126bd576101008083540402835291602001916126e8565b820191906000526020600020905b8154815290600101906020018083116126cb57829003601f168201915b50505050506000888154811015156126fc57fe5b6000918252602091829020600360059092020101805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156127925780601f1061276757610100808354040283529160200191612792565b820191906000526020600020905b81548152906001019060200180831161277557829003601f168201915b5050505050600261311c565b7f2e0a2dc845dce9ef7206b8fe38f3dacaad17ba74d7be9fba469c9858ae16a5d66000868154811015156127ce57fe5b60009182526020918290206040805181815260059093029091018054600260001961010060018416150201909116049183018290529288929182918201906060830190869080156128605780601f1061283557610100808354040283529160200191612860565b820191906000526020600020905b81548152906001019060200180831161284357829003601f168201915b50508381038252845460026000196101006001841615020190911604808252602090910190859080156128d45780601f106128a9576101008083540402835291602001916128d4565b820191906000526020600020905b8154815290600101906020018083116128b757829003601f168201915b505094505050505060405180910390a15b600080868154811015156128f557fe5b60009182526020909120600460059092020101805460ff1916600183600281111561291c57fe5b02179055506040805160208101909152600080825280548790811061293d57fe5b906000526020600020906005020160030190805190602001906115e3929190613d13565b5050505050565b600080600061297684611b28565b915060036000808481548110151561298a57fe5b906000526020600020906005020160010160405160200180828054600181600116156101000203166002900480156129f95780601f106129d75761010080835404028352918201916129f9565b820191906000526020600020905b8154815290600101906020018083116129e5575b50509150506040516020818303038152906040526040518082805190602001908083835b60208310612a3c5780518252601f199092019160209182019101612a1d565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205415159250612b21915050577faca1d1ef8876e1135c8c76871025becb2eefcbdb13c62fcd55c51dc174abf7af846040518080602001828103825283818151815260200191508051906020019080838360005b83811015612ade578181015183820152602001612ac6565b50505050905090810190601f168015612b0b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a160009250612bc1565b612b336000838154811015156103bd57fe5b9050600281815481101515612b4457fe5b60009182526020909120600160039092020101541515612bbc577faca1d1ef8876e1135c8c76871025becb2eefcbdb13c62fcd55c51dc174abf7af8460405180806020018281038252838181518152602001915080519060200190808383600083811015612ade578181015183820152602001612ac6565b600192505b5050919050565b6000806000612bd684611b28565b9250612bea6000848154811015156103bd57fe5b9150600090505b6002805483908110612bff57fe5b906000526020600020906003020160010180549050811015612c945760008381526004602052604081206002805483919086908110612c3a57fe5b906000526020600020906003020160010184815481101515612c5857fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff1916911515919091179055600101612bf1565b505060009081526005602052604081205550565b600080808080612cb787611b28565b9150600090505b6000805483908110612ccc57fe5b906000526020600020906005020160020180549050811015612ecc57856040516020018082805190602001908083835b60208310612d1b5780518252601f199092019160209182019101612cfc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310612d7e5780518252601f199092019160209182019101612d5f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091206000805491945092508591508110612dbb57fe5b906000526020600020906005020160020182815481101515612dd957fe5b906000526020600020016040516020018082805460018160011615610100020316600290048015612e415780601f10612e1f576101008083540402835291820191612e41565b820191906000526020600020905b815481529060010190602001808311612e2d575b50509150506040516020818303038152906040526040518082805190602001908083835b60208310612e845780518252601f199092019160209182019101612e65565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161415612ec45760019250612ecc565b600101612cbe565b9196919550909350505050565b60008080808080612ee988611b28565b9250612efd6000848154811015156103bd57fe5b9150600090505b6002805483908110612f1257fe5b9060005260206000209060030201600101805490508110156130b157866040516020018082600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040526040518082805190602001908083835b60208310612f9e5780518252601f199092019160209182019101612f7f565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091206002805491945092508591508110612fdb57fe5b906000526020600020906003020160010182815481101515612ff957fe5b6000918252602091829020015460408051600160a060020a039092166c0100000000000000000000000002828401528051601481840301815260349092019081905281519192909182918401908083835b602083106130695780518252601f19909201916020918201910161304a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614156130a957600193506130b1565b600101612f04565b929792965091945050505050565b6000806130cb83611b28565b9050600280828154811015156130dd57fe5b9060005260206000209060030201600101805490508115156130fb57fe5b6000838152600560205260409020549190041015611d775760019150611d7c565b600080600080600061312d88611c0a565b9450600186600281111561313d57fe5b14156133b45760009350600092505b600280548690811061315a57fe5b90600052602060002090600302016002018054905083101561335d57866040516020018082805190602001908083835b602083106131a95780518252601f19909201916020918201910161318a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b6020831061320c5780518252601f1990920191602091820191016131ed565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120600080549194509250889150811061324957fe5b90600052602060002090600502016002018481548110151561326757fe5b9060005260206000200160405160200180828054600181600116156101000203166002900480156132cf5780601f106132ad5761010080835404028352918201916132cf565b820191906000526020600020905b8154815290600101906020018083116132bb575b50509150506040516020818303038152906040526040518082805190602001908083835b602083106133125780518252601f1990920191602091820191016132f3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161415613352576001935061335d565b60019092019161314c565b8315156133af57600280548690811061337257fe5b60009182526020808320600260039093020191909101805460018101808355918452928290208a5191936133ac93910191908b0190613d13565b50505b610d3b565b6133bf898989613746565b1515610d3b57600091505b60028054869081106133d857fe5b9060005260206000209060030201600201805490508310156135d757866040516020018082805190602001908083835b602083106134275780518252601f199092019160209182019101613408565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b6020831061348a5780518252601f19909201916020918201910161346b565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912060028054919450925088915081106134c757fe5b9060005260206000209060030201600201838154811015156134e557fe5b90600052602060002001604051602001808280546001816001161561010002031660029004801561354d5780601f1061352b57610100808354040283529182019161354d565b820191906000526020600020905b815481529060010190602001808311613539575b50509150506040516020818303038152906040526040518082805190602001908083835b602083106135905780518252601f199092019160209182019101613571565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614156135cc576135d7565b6001909101906133ca565b50805b60016002868154811015156135eb57fe5b906000526020600020906003020160020180549050038110156136a057600280548690811061361657fe5b90600052602060002090600302016002018160010181548110151561363757fe5b9060005260206000200160028681548110151561365057fe5b90600052602060002090600302016002018281548110151561366e57fe5b906000526020600020019080546001816001161561010002031660029004613697929190613eef565b506001016135da565b60028054869081106136ae57fe5b906000526020600020906003020160020160016002878154811015156136d057fe5b906000526020600020906003020160020180549050038154811015156136f257fe5b9060005260206000200160006137089190613f64565b600280548690811061371657fe5b906000526020600020906003020160020180548091906001900361373a9190613fab565b50505050505050505050565b60008080805b600054821015613d0457866040516020018082805190602001908083835b602083106137895780518252601f19909201916020918201910161376a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106137ec5780518252601f1990920191602091820191016137cd565b5181516020939093036101000a60001901801990911692169190911790526040519201829003909120600080549194509250859150811061382957fe5b906000526020600020906005020160000160405160200180828054600181600116156101000203166002900480156138985780601f10613876576101008083540402835291820191613898565b820191906000526020600020905b815481529060010190602001808311613884575b50509150506040516020818303038152906040526040518082805190602001908083835b602083106138db5780518252601f1990920191602091820191016138bc565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916141561391757613cf9565b856040516020018082805190602001908083835b6020831061394a5780518252601f19909201916020918201910161392b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b602083106139ad5780518252601f19909201916020918201910161398e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912060008054919450925085915081106139ea57fe5b90600052602060002090600502016001016040516020018082805460018160011615610100020316600290048015613a595780601f10613a37576101008083540402835291820191613a59565b820191906000526020600020905b815481529060010190602001808311613a45575b50509150506040516020818303038152906040526040518082805190602001908083835b60208310613a9c5780518252601f199092019160209182019101613a7d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161415613ce5575060005b6000805483908110613ae557fe5b906000526020600020906005020160020180549050811015613ce557846040516020018082805190602001908083835b60208310613b345780518252601f199092019160209182019101613b15565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040526040518082805190602001908083835b60208310613b975780518252601f199092019160209182019101613b78565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091206000805491945092508591508110613bd457fe5b906000526020600020906005020160020182815481101515613bf257fe5b906000526020600020016040516020018082805460018160011615610100020316600290048015613c5a5780601f10613c38576101008083540402835291820191613c5a565b820191906000526020600020905b815481529060010190602001808311613c46575b50509150506040516020818303038152906040526040518082805190602001908083835b60208310613c9d5780518252601f199092019160209182019101613c7e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161415613cdd5760019250613ce5565b600101613ad7565b60018315151415613cf95760019350613d09565b60019091019061374c565b600093505b5050509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613d5457805160ff1916838001178555613d81565b82800160010185558215613d81579182015b82811115613d81578251825591602001919060010190613d66565b50613d8d929150613fcf565b5090565b828054828255906000526020600020908101928215613dde579160200282015b82811115613dde5782518051613dce918491602090910190613d13565b5091602001919060010190613db1565b50613d8d929150613fec565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e2b5782800160ff19823516178555613d81565b82800160010185558215613d81579182015b82811115613d81578235825591602001919060010190613e3d565b828054828255906000526020600020908101928215613eba579160200282015b82811115613eba578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190613e78565b50613d8d92915061400f565b815481835581811115613eea57600083815260209020613eea918101908301613fcf565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613f285780548555613d81565b82800160010185558215613d8157600052602060002091601f016020900482015b82811115613d81578254825591600101919060010190613f49565b50805460018160011615610100020316600290046000825580601f10613f8a5750613fa8565b601f016020900490600052602060002090810190613fa89190613fcf565b50565b815481835581811115613eea57600083815260209020613eea918101908301613fec565b613fe991905b80821115613d8d5760008155600101613fd5565b90565b613fe991905b80821115613d8d5760006140068282613f64565b50600101613ff2565b613fe991905b80821115613d8d57805473ffffffffffffffffffffffffffffffffffffffff191681556001016140155600a165627a7a72305820561aa676285a47bee0b60a17eb33b545fd2bca718f4e472f71f69f9dc3029c770029 \ No newline at end of file