- Contract name:
- EnergyWebSparkV1
- Optimization enabled
- false
- Compiler version
- v0.8.18+commit.87f61d96
- EVM Version
- default
- Verified at
- 2023-08-24T22:20:09.862722Z
Contract source code
// File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: crowdfund.sol pragma solidity ^0.8.9; contract EnergyWebSparkV1 is Ownable { struct Campaign { address owner; string username; string title; string description; uint256 target; uint256 deadline; uint256 amountCollected; bool campaignAmountWithdrawn; string image; address[] funders; uint256[] contributions; bool status; } mapping(uint256 => Campaign) public campaigns; event CampaignCreated( uint256 campaignId, address owner, string username, string title, string description, uint256 target, uint256 deadline, bool campaignAmountWithdrawn, string image, bool status ); event CampaignEdited( uint256 campaignId, address owner, string username, string title, string description, uint256 target, uint256 deadline, string image ); event CampaignStatusChanged(uint256 campaignId, address owner, bool status ); event ContributionMade( uint256 campaignId, address contributor, uint256 amountContributed ); event ContributionTakenBack( uint256 campaignId, address contributor, uint256 amountContributed ); event AllContributionsWithdrawn( uint256 campaignId ); event AllContributionsWithdrawnTargetNotReached( uint256 campaignId ) ; uint256 public numberOfCampaigns = 0; address payable feeAddress = payable(0xBc82Fdc61D8753dcB65b18eca2ea7540Aba2f122); uint256 public feePoints = 500; function setFeeAddress(address payable _feeAddress) public onlyOwner { feeAddress = _feeAddress; } function setFeePoints(uint256 _feePoints) public onlyOwner { feePoints = _feePoints; } function createCampaign( address _owner, string memory _username, string memory _title, string memory _description, uint256 _target, uint256 _deadline, string memory _image ) public returns (uint256) { Campaign storage campaign = campaigns[numberOfCampaigns]; require( _deadline > block.timestamp, "The deadline should be a date in the future" ); campaign.owner = _owner; campaign.username = _username; campaign.title = _title; campaign.description = _description; campaign.target = _target; campaign.deadline = _deadline; campaign.campaignAmountWithdrawn = false; campaign.amountCollected = 0; campaign.image = _image; campaign.status = true; emit CampaignCreated( numberOfCampaigns, _owner, _username, _title, _description, _target, _deadline, false, _image, true ); numberOfCampaigns++; return numberOfCampaigns - 1; } function editCampaign( uint256 _id, string memory _title, string memory _description, uint256 _target, uint256 _deadline, string memory _image ) public { require(_id < numberOfCampaigns, "Invalid campaign ID"); Campaign storage campaign = campaigns[_id]; require( campaign.owner == msg.sender, "Only the campaign owner can edit the campaign" ); require( _deadline > block.timestamp, "The campaign deadline has to be set to a later date" ); campaign.title = _title; campaign.description = _description; campaign.target = _target; campaign.deadline = _deadline; campaign.image = _image; emit CampaignEdited( _id, msg.sender, campaign.username, _title, _description, _target, _deadline, _image ); } function editCampaignStatus(uint256 _id, bool _status) public { require(_id < numberOfCampaigns, "Invalid campaign ID"); Campaign storage campaign = campaigns[_id]; require( campaign.owner == msg.sender, "Only the campaign owner can change the status of the campaign" ); require( campaign.deadline > block.timestamp, "The campaign deadline has to be set to a later date" ); campaign.status = _status; emit CampaignStatusChanged(_id, msg.sender, _status); } function contributeToCampaign(uint256 _id) public payable { uint256 amount = msg.value; Campaign storage campaign = campaigns[_id]; require( campaign.status == true, "The campaign has to be active to contribute" ); campaign.funders.push(msg.sender); campaign.contributions.push(amount); require(amount > 0); campaign.amountCollected = campaign.amountCollected + amount; emit ContributionMade(_id, msg.sender, amount); } function getContributors(uint256 _id) public view returns (address[] memory, uint256[] memory) { return (campaigns[_id].funders, campaigns[_id].contributions); } function getCampaigns() public view returns (Campaign[] memory) { Campaign[] memory allCampaigns = new Campaign[](numberOfCampaigns); for (uint256 i = 0; i < numberOfCampaigns; i++) { Campaign storage item = campaigns[i]; allCampaigns[i] = item; } return allCampaigns; } function withdrawContributions(uint256 _id) public { require(_id < numberOfCampaigns, "Invalid campaign ID"); Campaign storage campaign = campaigns[_id]; require( campaign.owner == msg.sender, "Only the campaign owner can withdraw contributions" ); require( block.timestamp > campaign.deadline, "The campaign has not ended yet" ); require( campaign.amountCollected >= campaign.target, "The campaign target has not been reached" ); require( campaign.campaignAmountWithdrawn == false, "The campaign amount can only be claimed once" ); uint256 totalAmount = campaign.amountCollected; require(totalAmount > 0, "No contributions to withdraw"); uint256 feeAmount = (totalAmount * feePoints) / 10000; uint256 contributorAmount = totalAmount - feeAmount; require(payable(msg.sender).send(contributorAmount)); require(payable(feeAddress).send(feeAmount)); campaign.campaignAmountWithdrawn = true; emit AllContributionsWithdrawn(_id); } function takeBackContribution(uint256 _id) public { require(_id < numberOfCampaigns, "Invalid campaign ID"); Campaign storage campaign = campaigns[_id]; require( campaign.deadline > block.timestamp, "The campaign has already ended" ); uint256 totalContributions = 0; uint256 indexCount = 0; for (uint256 i = 0; i < campaign.funders.length; i++) { if (campaign.funders[i] == msg.sender) { totalContributions += campaign.contributions[i]; indexCount++; } } require( totalContributions > 0, "You haven't made any contributions to this campaign" ); for (uint256 i = 0; i < indexCount; i++) { uint256 indexToRemove = getLatestContributionIndex( campaign, msg.sender ); campaign.funders[indexToRemove] = campaign.funders[ campaign.funders.length - 1 ]; campaign.contributions[indexToRemove] = campaign.contributions[ campaign.contributions.length - 1 ]; campaign.funders.pop(); campaign.contributions.pop(); } require(payable(msg.sender).send(totalContributions)); campaign.amountCollected -= totalContributions; emit ContributionTakenBack(_id, msg.sender, totalContributions); } function getLatestContributionIndex( Campaign storage campaign, address contributor ) internal view returns (uint256) { for (uint256 i = campaign.funders.length - 1; i >= 0; i--) { if (campaign.funders[i] == contributor) { return i; } } revert("Contributor not found"); } function refundAllContributions(uint256 _id) public { require(_id < numberOfCampaigns, "Invalid campaign ID"); Campaign storage campaign = campaigns[_id]; require( block.timestamp > campaign.deadline, "The campaign has not ended yet" ); require( campaign.amountCollected < campaign.target, "The campaign has reached it's target" ); require( campaign.campaignAmountWithdrawn == false, "The campaign amount has already been withdrawn" ); campaign.campaignAmountWithdrawn = true; for (uint256 i = 0; i < campaign.funders.length; i++) { address contributor = campaign.funders[i]; uint256 contributionAmount = campaign.contributions[i]; if (contributionAmount > 0) { require(payable(contributor).send(contributionAmount)); } } emit AllContributionsWithdrawnTargetNotReached(_id); } }
Contract ABI
[{"type":"event","name":"AllContributionsWithdrawn","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AllContributionsWithdrawnTargetNotReached","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"CampaignCreated","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false},{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"string","name":"username","internalType":"string","indexed":false},{"type":"string","name":"title","internalType":"string","indexed":false},{"type":"string","name":"description","internalType":"string","indexed":false},{"type":"uint256","name":"target","internalType":"uint256","indexed":false},{"type":"uint256","name":"deadline","internalType":"uint256","indexed":false},{"type":"bool","name":"campaignAmountWithdrawn","internalType":"bool","indexed":false},{"type":"string","name":"image","internalType":"string","indexed":false},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"CampaignEdited","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false},{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"string","name":"username","internalType":"string","indexed":false},{"type":"string","name":"title","internalType":"string","indexed":false},{"type":"string","name":"description","internalType":"string","indexed":false},{"type":"uint256","name":"target","internalType":"uint256","indexed":false},{"type":"uint256","name":"deadline","internalType":"uint256","indexed":false},{"type":"string","name":"image","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"CampaignStatusChanged","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false},{"type":"address","name":"owner","internalType":"address","indexed":false},{"type":"bool","name":"status","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"ContributionMade","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false},{"type":"address","name":"contributor","internalType":"address","indexed":false},{"type":"uint256","name":"amountContributed","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ContributionTakenBack","inputs":[{"type":"uint256","name":"campaignId","internalType":"uint256","indexed":false},{"type":"address","name":"contributor","internalType":"address","indexed":false},{"type":"uint256","name":"amountContributed","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"string","name":"username","internalType":"string"},{"type":"string","name":"title","internalType":"string"},{"type":"string","name":"description","internalType":"string"},{"type":"uint256","name":"target","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"amountCollected","internalType":"uint256"},{"type":"bool","name":"campaignAmountWithdrawn","internalType":"bool"},{"type":"string","name":"image","internalType":"string"},{"type":"bool","name":"status","internalType":"bool"}],"name":"campaigns","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"contributeToCampaign","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"createCampaign","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"string","name":"_username","internalType":"string"},{"type":"string","name":"_title","internalType":"string"},{"type":"string","name":"_description","internalType":"string"},{"type":"uint256","name":"_target","internalType":"uint256"},{"type":"uint256","name":"_deadline","internalType":"uint256"},{"type":"string","name":"_image","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"editCampaign","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"string","name":"_title","internalType":"string"},{"type":"string","name":"_description","internalType":"string"},{"type":"uint256","name":"_target","internalType":"uint256"},{"type":"uint256","name":"_deadline","internalType":"uint256"},{"type":"string","name":"_image","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"editCampaignStatus","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"},{"type":"bool","name":"_status","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"feePoints","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct EnergyWebSparkV1.Campaign[]","components":[{"type":"address","name":"owner","internalType":"address"},{"type":"string","name":"username","internalType":"string"},{"type":"string","name":"title","internalType":"string"},{"type":"string","name":"description","internalType":"string"},{"type":"uint256","name":"target","internalType":"uint256"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"uint256","name":"amountCollected","internalType":"uint256"},{"type":"bool","name":"campaignAmountWithdrawn","internalType":"bool"},{"type":"string","name":"image","internalType":"string"},{"type":"address[]","name":"funders","internalType":"address[]"},{"type":"uint256[]","name":"contributions","internalType":"uint256[]"},{"type":"bool","name":"status","internalType":"bool"}]}],"name":"getCampaigns","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"},{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getContributors","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numberOfCampaigns","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"refundAllContributions","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeAddress","inputs":[{"type":"address","name":"_feeAddress","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeePoints","inputs":[{"type":"uint256","name":"_feePoints","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"takeBackContribution","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawContributions","inputs":[{"type":"uint256","name":"_id","internalType":"uint256"}]}]
Deployed ByteCode
0x6080604052600436106100fe5760003560e01c8063715018a6116100955780638705fcd4116100645780638705fcd41461031a5780638da5cb5b14610343578063a6b036331461036e578063dba038b314610399578063f2fde38b146103c2576100fe565b8063715018a6146102745780637660be5d1461028b578063767befcc146102c85780637925f4c3146102f1576100fe565b8063141961bc116100d1578063141961bc1461019c5780633c1ab00f146101e257806357a50e82146102205780636c18d1ad14610249576100fe565b806307ca140d146101035780630b008fd01461012e5780630b7ef89b146101575780630d83120314610173575b600080fd5b34801561010f57600080fd5b506101186103eb565b6040516101259190612085565b60405180910390f35b34801561013a57600080fd5b50610155600480360381019061015091906120e0565b6103f1565b005b610171600480360381019061016c91906120e0565b61073b565b005b34801561017f57600080fd5b5061019a600480360381019061019591906120e0565b6108a4565b005b3480156101a857600080fd5b506101c360048036038101906101be91906120e0565b6108b6565b6040516101d99a999897969594939291906121f9565b60405180910390f35b3480156101ee57600080fd5b50610209600480360381019061020491906120e0565b610b64565b60405161021792919061242d565b60405180910390f35b34801561022c57600080fd5b50610247600480360381019061024291906120e0565b610c76565b005b34801561025557600080fd5b5061025e611078565b60405161026b9190612085565b60405180910390f35b34801561028057600080fd5b5061028961107e565b005b34801561029757600080fd5b506102b260048036038101906102ad91906125c5565b611092565b6040516102bf9190612085565b60405180910390f35b3480156102d457600080fd5b506102ef60048036038101906102ea9190612703565b611251565b005b3480156102fd57600080fd5b5061031860048036038101906103139190612743565b6113e0565b005b34801561032657600080fd5b50610341600480360381019061033c9190612862565b6115a8565b005b34801561034f57600080fd5b506103586115f4565b604051610365919061288f565b60405180910390f35b34801561037a57600080fd5b5061038361161d565b6040516103909190612bca565b60405180910390f35b3480156103a557600080fd5b506103c060048036038101906103bb91906120e0565b611abc565b005b3480156103ce57600080fd5b506103e960048036038101906103e49190612bec565b611d31565b005b60025481565b6002548110610435576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161042c90612c65565b60405180910390fd5b60006001600083815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146104de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d590612cf7565b60405180910390fd5b80600501544211610524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161051b90612d63565b60405180910390fd5b80600401548160060154101561056f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161056690612df5565b60405180910390fd5b600015158160070160009054906101000a900460ff161515146105c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105be90612e87565b60405180910390fd5b60008160060154905060008111610613576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060a90612ef3565b60405180910390fd5b6000612710600454836106269190612f42565b6106309190612fb3565b9050600081836106409190612fe4565b90503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505061068057600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f193505050506106e057600080fd5b60018460070160006101000a81548160ff0219169083151502179055507f0a1f8d78f004799cb9dc66229fce41612b12c3c0e038fdd336c28eb5668f364d8560405161072c9190612085565b60405180910390a15050505050565b600034905060006001600084815260200190815260200160002090506001151581600b0160009054906101000a900460ff161515146107af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a69061308a565b60405180910390fd5b80600901339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600a018290806001815401808255809150506001900390600052602060002001600090919091909150556000821161084c57600080fd5b81816006015461085c91906130aa565b81600601819055507f0a4a91237423e0a1766a761c7cb029311d8b95d6b1b81db1b949a70c98b4e08e833384604051610897939291906130de565b60405180910390a1505050565b6108ac611db4565b8060048190555050565b60016020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010180546108ff90613144565b80601f016020809104026020016040519081016040528092919081815260200182805461092b90613144565b80156109785780601f1061094d57610100808354040283529160200191610978565b820191906000526020600020905b81548152906001019060200180831161095b57829003601f168201915b50505050509080600201805461098d90613144565b80601f01602080910402602001604051908101604052809291908181526020018280546109b990613144565b8015610a065780601f106109db57610100808354040283529160200191610a06565b820191906000526020600020905b8154815290600101906020018083116109e957829003601f168201915b505050505090806003018054610a1b90613144565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4790613144565b8015610a945780601f10610a6957610100808354040283529160200191610a94565b820191906000526020600020905b815481529060010190602001808311610a7757829003601f168201915b5050505050908060040154908060050154908060060154908060070160009054906101000a900460ff1690806008018054610ace90613144565b80601f0160208091040260200160405190810160405280929190818152602001828054610afa90613144565b8015610b475780601f10610b1c57610100808354040283529160200191610b47565b820191906000526020600020905b815481529060010190602001808311610b2a57829003601f168201915b50505050509080600b0160009054906101000a900460ff1690508a565b6060806001600084815260200190815260200160002060090160016000858152602001908152602001600020600a0181805480602002602001604051908101604052809291908181526020018280548015610c1457602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610bca575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015610c6657602002820191906000526020600020905b815481526020019060010190808311610c52575b5050505050905091509150915091565b6002548110610cba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb190612c65565b60405180910390fd5b600060016000838152602001908152602001600020905042816005015411610d17576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0e906131c1565b60405180910390fd5b60008060005b8360090180549050811015610def573373ffffffffffffffffffffffffffffffffffffffff16846009018281548110610d5957610d586131e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610ddc5783600a018181548110610db557610db46131e1565b5b906000526020600020015483610dcb91906130aa565b92508180610dd890613210565b9250505b8080610de790613210565b915050610d1d565b5060008211610e33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e2a906132ca565b60405180910390fd5b60005b81811015610fdd576000610e4a8533611e32565b90508460090160018660090180549050610e649190612fe4565b81548110610e7557610e746131e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856009018281548110610eb657610eb56131e1565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600a01600186600a0180549050610f169190612fe4565b81548110610f2757610f266131e1565b5b906000526020600020015485600a018281548110610f4857610f476131e1565b5b906000526020600020018190555084600901805480610f6a57610f696132ea565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055905584600a01805480610fb357610fb26132ea565b5b60019003818190600052602060002001600090559055508080610fd590613210565b915050610e36565b503373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505061101c57600080fd5b818360060160008282546110309190612fe4565b925050819055507ff537aeada5eb2cbb5911ed8117f94a65e7e772de9af160dfc8346408ed09e40284338460405161106a939291906130de565b60405180910390a150505050565b60045481565b611086611db4565b6110906000611f25565b565b60008060016000600254815260200190815260200160002090504284116110ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e59061338b565b60405180910390fd5b888160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550878160010190816111429190613557565b50868160020190816111549190613557565b50858160030190816111669190613557565b5084816004018190555083816005018190555060008160070160006101000a81548160ff02191690831515021790555060008160060181905550828160080190816111b19190613557565b50600181600b0160006101000a81548160ff0219169083151502179055507fde644a8b621e3255cca0b902591330559ba02aa83c3178e65c54d32247e42ed36002548a8a8a8a8a8a60008b60016040516112149a99989796959493929190613629565b60405180910390a16002600081548092919061122f90613210565b919050555060016002546112439190612fe4565b915050979650505050505050565b6002548210611295576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128c90612c65565b60405180910390fd5b60006001600084815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461133e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161133590613753565b60405180910390fd5b42816005015411611384576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137b906137e5565b60405180910390fd5b8181600b0160006101000a81548160ff0219169083151502179055507f046a9ef4e9741ed9b7cba82ad486735ab516bd04dc43f6ee911737503f759db78333846040516113d393929190613805565b60405180910390a1505050565b6002548610611424576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141b90612c65565b60405180910390fd5b60006001600088815260200190815260200160002090503373ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c4906138ae565b60405180910390fd5b42831161150f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611506906137e5565b60405180910390fd5b858160020190816115209190613557565b50848160030190816115329190613557565b50838160040181905550828160050181905550818160080190816115569190613557565b507f89c3eaa972d3d4e7c97d7d4ad715cfe1e027100a35e9b95f9978392df6dbd88b8733836001018989898989604051611597989796959493929190613952565b60405180910390a150505050505050565b6115b0611db4565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600060025467ffffffffffffffff81111561163d5761163c61249a565b5b60405190808252806020026020018201604052801561167657816020015b611663611ff1565b81526020019060019003908161165b5790505b50905060005b600254811015611ab457600060016000838152602001908152602001600020905080604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201805461171090613144565b80601f016020809104026020016040519081016040528092919081815260200182805461173c90613144565b80156117895780601f1061175e57610100808354040283529160200191611789565b820191906000526020600020905b81548152906001019060200180831161176c57829003601f168201915b505050505081526020016002820180546117a290613144565b80601f01602080910402602001604051908101604052809291908181526020018280546117ce90613144565b801561181b5780601f106117f05761010080835404028352916020019161181b565b820191906000526020600020905b8154815290600101906020018083116117fe57829003601f168201915b5050505050815260200160038201805461183490613144565b80601f016020809104026020016040519081016040528092919081815260200182805461186090613144565b80156118ad5780601f10611882576101008083540402835291602001916118ad565b820191906000526020600020905b81548152906001019060200180831161189057829003601f168201915b505050505081526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff161515151581526020016008820180546118ff90613144565b80601f016020809104026020016040519081016040528092919081815260200182805461192b90613144565b80156119785780601f1061194d57610100808354040283529160200191611978565b820191906000526020600020905b81548152906001019060200180831161195b57829003601f168201915b5050505050815260200160098201805480602002602001604051908101604052809291908181526020018280548015611a0657602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190600101908083116119bc575b50505050508152602001600a8201805480602002602001604051908101604052809291908181526020018280548015611a5e57602002820191906000526020600020905b815481526020019060010190808311611a4a575b50505050508152602001600b820160009054906101000a900460ff161515151581525050838381518110611a9557611a946131e1565b5b6020026020010181905250508080611aac90613210565b91505061167c565b508091505090565b6002548110611b00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611af790612c65565b60405180910390fd5b600060016000838152602001908152602001600020905080600501544211611b5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b5490612d63565b60405180910390fd5b8060040154816006015410611ba7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9e90613a5e565b60405180910390fd5b600015158160070160009054906101000a900460ff16151514611bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bf690613af0565b60405180910390fd5b60018160070160006101000a81548160ff02191690831515021790555060005b8160090180549050811015611cf5576000826009018281548110611c4657611c456131e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600083600a018381548110611c8b57611c8a6131e1565b5b906000526020600020015490506000811115611ce0578173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050611cdf57600080fd5b5b50508080611ced90613210565b915050611c1f565b507fd0f81f0c368322b2c887363c50a1898b8b7a70ee966e1bab461a3662e7fa5bb682604051611d259190612085565b60405180910390a15050565b611d39611db4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611da8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d9f90613b82565b60405180910390fd5b611db181611f25565b50565b611dbc611fe9565b73ffffffffffffffffffffffffffffffffffffffff16611dda6115f4565b73ffffffffffffffffffffffffffffffffffffffff1614611e30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e2790613bee565b60405180910390fd5b565b60008060018460090180549050611e499190612fe4565b90505b60008110611ee3578273ffffffffffffffffffffffffffffffffffffffff16846009018281548110611e8157611e806131e1565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603611ed05780915050611f1f565b8080611edb90613c0e565b915050611e4c565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1690613c83565b60405180910390fd5b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b604051806101800160405280600073ffffffffffffffffffffffffffffffffffffffff1681526020016060815260200160608152602001606081526020016000815260200160008152602001600081526020016000151581526020016060815260200160608152602001606081526020016000151581525090565b6000819050919050565b61207f8161206c565b82525050565b600060208201905061209a6000830184612076565b92915050565b6000604051905090565b600080fd5b600080fd5b6120bd8161206c565b81146120c857600080fd5b50565b6000813590506120da816120b4565b92915050565b6000602082840312156120f6576120f56120aa565b5b6000612104848285016120cb565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006121388261210d565b9050919050565b6121488161212d565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561218857808201518184015260208101905061216d565b60008484015250505050565b6000601f19601f8301169050919050565b60006121b08261214e565b6121ba8185612159565b93506121ca81856020860161216a565b6121d381612194565b840191505092915050565b60008115159050919050565b6121f3816121de565b82525050565b60006101408201905061220f600083018d61213f565b8181036020830152612221818c6121a5565b90508181036040830152612235818b6121a5565b90508181036060830152612249818a6121a5565b90506122586080830189612076565b61226560a0830188612076565b61227260c0830187612076565b61227f60e08301866121ea565b81810361010083015261229281856121a5565b90506122a26101208301846121ea565b9b9a5050505050505050505050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6122e68161212d565b82525050565b60006122f883836122dd565b60208301905092915050565b6000602082019050919050565b600061231c826122b1565b61232681856122bc565b9350612331836122cd565b8060005b8381101561236257815161234988826122ec565b975061235483612304565b925050600181019050612335565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6123a48161206c565b82525050565b60006123b6838361239b565b60208301905092915050565b6000602082019050919050565b60006123da8261236f565b6123e4818561237a565b93506123ef8361238b565b8060005b8381101561242057815161240788826123aa565b9750612412836123c2565b9250506001810190506123f3565b5085935050505092915050565b600060408201905081810360008301526124478185612311565b9050818103602083015261245b81846123cf565b90509392505050565b61246d8161212d565b811461247857600080fd5b50565b60008135905061248a81612464565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6124d282612194565b810181811067ffffffffffffffff821117156124f1576124f061249a565b5b80604052505050565b60006125046120a0565b905061251082826124c9565b919050565b600067ffffffffffffffff8211156125305761252f61249a565b5b61253982612194565b9050602081019050919050565b82818337600083830152505050565b600061256861256384612515565b6124fa565b90508281526020810184848401111561258457612583612495565b5b61258f848285612546565b509392505050565b600082601f8301126125ac576125ab612490565b5b81356125bc848260208601612555565b91505092915050565b600080600080600080600060e0888a0312156125e4576125e36120aa565b5b60006125f28a828b0161247b565b975050602088013567ffffffffffffffff811115612613576126126120af565b5b61261f8a828b01612597565b965050604088013567ffffffffffffffff8111156126405761263f6120af565b5b61264c8a828b01612597565b955050606088013567ffffffffffffffff81111561266d5761266c6120af565b5b6126798a828b01612597565b945050608061268a8a828b016120cb565b93505060a061269b8a828b016120cb565b92505060c088013567ffffffffffffffff8111156126bc576126bb6120af565b5b6126c88a828b01612597565b91505092959891949750929550565b6126e0816121de565b81146126eb57600080fd5b50565b6000813590506126fd816126d7565b92915050565b6000806040838503121561271a576127196120aa565b5b6000612728858286016120cb565b9250506020612739858286016126ee565b9150509250929050565b60008060008060008060c087890312156127605761275f6120aa565b5b600061276e89828a016120cb565b965050602087013567ffffffffffffffff81111561278f5761278e6120af565b5b61279b89828a01612597565b955050604087013567ffffffffffffffff8111156127bc576127bb6120af565b5b6127c889828a01612597565b94505060606127d989828a016120cb565b93505060806127ea89828a016120cb565b92505060a087013567ffffffffffffffff81111561280b5761280a6120af565b5b61281789828a01612597565b9150509295509295509295565b600061282f8261210d565b9050919050565b61283f81612824565b811461284a57600080fd5b50565b60008135905061285c81612836565b92915050565b600060208284031215612878576128776120aa565b5b60006128868482850161284d565b91505092915050565b60006020820190506128a4600083018461213f565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b60006128f28261214e565b6128fc81856128d6565b935061290c81856020860161216a565b61291581612194565b840191505092915050565b612929816121de565b82525050565b600082825260208201905092915050565b600061294b826122b1565b612955818561292f565b9350612960836122cd565b8060005b8381101561299157815161297888826122ec565b975061298383612304565b925050600181019050612964565b5085935050505092915050565b600082825260208201905092915050565b60006129ba8261236f565b6129c4818561299e565b93506129cf8361238b565b8060005b83811015612a005781516129e788826123aa565b97506129f2836123c2565b9250506001810190506129d3565b5085935050505092915050565b600061018083016000830151612a2660008601826122dd565b5060208301518482036020860152612a3e82826128e7565b91505060408301518482036040860152612a5882826128e7565b91505060608301518482036060860152612a7282826128e7565b9150506080830151612a87608086018261239b565b5060a0830151612a9a60a086018261239b565b5060c0830151612aad60c086018261239b565b5060e0830151612ac060e0860182612920565b50610100830151848203610100860152612ada82826128e7565b915050610120830151848203610120860152612af68282612940565b915050610140830151848203610140860152612b1282826129af565b915050610160830151612b29610160860182612920565b508091505092915050565b6000612b408383612a0d565b905092915050565b6000602082019050919050565b6000612b60826128aa565b612b6a81856128b5565b935083602082028501612b7c856128c6565b8060005b85811015612bb85784840389528151612b998582612b34565b9450612ba483612b48565b925060208a01995050600181019050612b80565b50829750879550505050505092915050565b60006020820190508181036000830152612be48184612b55565b905092915050565b600060208284031215612c0257612c016120aa565b5b6000612c108482850161247b565b91505092915050565b7f496e76616c69642063616d706169676e20494400000000000000000000000000600082015250565b6000612c4f601383612159565b9150612c5a82612c19565b602082019050919050565b60006020820190508181036000830152612c7e81612c42565b9050919050565b7f4f6e6c79207468652063616d706169676e206f776e65722063616e207769746860008201527f6472617720636f6e747269627574696f6e730000000000000000000000000000602082015250565b6000612ce1603283612159565b9150612cec82612c85565b604082019050919050565b60006020820190508181036000830152612d1081612cd4565b9050919050565b7f5468652063616d706169676e20686173206e6f7420656e646564207965740000600082015250565b6000612d4d601e83612159565b9150612d5882612d17565b602082019050919050565b60006020820190508181036000830152612d7c81612d40565b9050919050565b7f5468652063616d706169676e2074617267657420686173206e6f74206265656e60008201527f2072656163686564000000000000000000000000000000000000000000000000602082015250565b6000612ddf602883612159565b9150612dea82612d83565b604082019050919050565b60006020820190508181036000830152612e0e81612dd2565b9050919050565b7f5468652063616d706169676e20616d6f756e742063616e206f6e6c792062652060008201527f636c61696d6564206f6e63650000000000000000000000000000000000000000602082015250565b6000612e71602c83612159565b9150612e7c82612e15565b604082019050919050565b60006020820190508181036000830152612ea081612e64565b9050919050565b7f4e6f20636f6e747269627574696f6e7320746f20776974686472617700000000600082015250565b6000612edd601c83612159565b9150612ee882612ea7565b602082019050919050565b60006020820190508181036000830152612f0c81612ed0565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612f4d8261206c565b9150612f588361206c565b9250828202612f668161206c565b91508282048414831517612f7d57612f7c612f13565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612fbe8261206c565b9150612fc98361206c565b925082612fd957612fd8612f84565b5b828204905092915050565b6000612fef8261206c565b9150612ffa8361206c565b925082820390508181111561301257613011612f13565b5b92915050565b7f5468652063616d706169676e2068617320746f2062652061637469766520746f60008201527f20636f6e74726962757465000000000000000000000000000000000000000000602082015250565b6000613074602b83612159565b915061307f82613018565b604082019050919050565b600060208201905081810360008301526130a381613067565b9050919050565b60006130b58261206c565b91506130c08361206c565b92508282019050808211156130d8576130d7612f13565b5b92915050565b60006060820190506130f36000830186612076565b613100602083018561213f565b61310d6040830184612076565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061315c57607f821691505b60208210810361316f5761316e613115565b5b50919050565b7f5468652063616d706169676e2068617320616c726561647920656e6465640000600082015250565b60006131ab601e83612159565b91506131b682613175565b602082019050919050565b600060208201905081810360008301526131da8161319e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061321b8261206c565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361324d5761324c612f13565b5b600182019050919050565b7f596f7520686176656e2774206d61646520616e7920636f6e747269627574696f60008201527f6e7320746f20746869732063616d706169676e00000000000000000000000000602082015250565b60006132b4603383612159565b91506132bf82613258565b604082019050919050565b600060208201905081810360008301526132e3816132a7565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f54686520646561646c696e652073686f756c642062652061206461746520696e60008201527f2074686520667574757265000000000000000000000000000000000000000000602082015250565b6000613375602b83612159565b915061338082613319565b604082019050919050565b600060208201905081810360008301526133a481613368565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261340d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826133d0565b61341786836133d0565b95508019841693508086168417925050509392505050565b6000819050919050565b600061345461344f61344a8461206c565b61342f565b61206c565b9050919050565b6000819050919050565b61346e83613439565b61348261347a8261345b565b8484546133dd565b825550505050565b600090565b61349761348a565b6134a2818484613465565b505050565b5b818110156134c6576134bb60008261348f565b6001810190506134a8565b5050565b601f82111561350b576134dc816133ab565b6134e5846133c0565b810160208510156134f4578190505b613508613500856133c0565b8301826134a7565b50505b505050565b600082821c905092915050565b600061352e60001984600802613510565b1980831691505092915050565b6000613547838361351d565b9150826002028217905092915050565b6135608261214e565b67ffffffffffffffff8111156135795761357861249a565b5b6135838254613144565b61358e8282856134ca565b600060209050601f8311600181146135c157600084156135af578287015190505b6135b9858261353b565b865550613621565b601f1984166135cf866133ab565b60005b828110156135f7578489015182556001820191506020850194506020810190506135d2565b868310156136145784890151613610601f89168261351d565b8355505b6001600288020188555050505b505050505050565b60006101408201905061363f600083018d612076565b61364c602083018c61213f565b818103604083015261365e818b6121a5565b90508181036060830152613672818a6121a5565b9050818103608083015261368681896121a5565b905061369560a0830188612076565b6136a260c0830187612076565b6136af60e08301866121ea565b8181036101008301526136c281856121a5565b90506136d26101208301846121ea565b9b9a5050505050505050505050565b7f4f6e6c79207468652063616d706169676e206f776e65722063616e206368616e60008201527f67652074686520737461747573206f66207468652063616d706169676e000000602082015250565b600061373d603d83612159565b9150613748826136e1565b604082019050919050565b6000602082019050818103600083015261376c81613730565b9050919050565b7f5468652063616d706169676e20646561646c696e652068617320746f2062652060008201527f73657420746f2061206c61746572206461746500000000000000000000000000602082015250565b60006137cf603383612159565b91506137da82613773565b604082019050919050565b600060208201905081810360008301526137fe816137c2565b9050919050565b600060608201905061381a6000830186612076565b613827602083018561213f565b61383460408301846121ea565b949350505050565b7f4f6e6c79207468652063616d706169676e206f776e65722063616e206564697460008201527f207468652063616d706169676e00000000000000000000000000000000000000602082015250565b6000613898602d83612159565b91506138a38261383c565b604082019050919050565b600060208201905081810360008301526138c78161388b565b9050919050565b600081546138db81613144565b6138e58186612159565b94506001821660008114613900576001811461391657613949565b60ff198316865281151560200286019350613949565b61391f856133ab565b60005b8381101561394157815481890152600182019150602081019050613922565b808801955050505b50505092915050565b600061010082019050613968600083018b612076565b613975602083018a61213f565b818103604083015261398781896138ce565b9050818103606083015261399b81886121a5565b905081810360808301526139af81876121a5565b90506139be60a0830186612076565b6139cb60c0830185612076565b81810360e08301526139dd81846121a5565b90509998505050505050505050565b7f5468652063616d706169676e206861732072656163686564206974277320746160008201527f7267657400000000000000000000000000000000000000000000000000000000602082015250565b6000613a48602483612159565b9150613a53826139ec565b604082019050919050565b60006020820190508181036000830152613a7781613a3b565b9050919050565b7f5468652063616d706169676e20616d6f756e742068617320616c72656164792060008201527f6265656e2077697468647261776e000000000000000000000000000000000000602082015250565b6000613ada602e83612159565b9150613ae582613a7e565b604082019050919050565b60006020820190508181036000830152613b0981613acd565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613b6c602683612159565b9150613b7782613b10565b604082019050919050565b60006020820190508181036000830152613b9b81613b5f565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613bd8602083612159565b9150613be382613ba2565b602082019050919050565b60006020820190508181036000830152613c0781613bcb565b9050919050565b6000613c198261206c565b915060008203613c2c57613c2b612f13565b5b600182039050919050565b7f436f6e7472696275746f72206e6f7420666f756e640000000000000000000000600082015250565b6000613c6d601583612159565b9150613c7882613c37565b602082019050919050565b60006020820190508181036000830152613c9c81613c60565b905091905056fea264697066735822122093c67977f0252fefd49811c899eb7fc0ca1124b131c7e48134d8165640024e3a64736f6c63430008120033