@etherspot/contracts
Version:
Etherspot Solidity contracts
107 lines • 61.9 kB
JSON
{
"address": "0xf859F683a47b3D0E2A964eFDdf7392972700a101",
"abi": [
{
"anonymous": false,
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "facetAddress",
"type": "address"
},
{
"internalType": "enum IDiamondCut.FacetCutAction",
"name": "action",
"type": "uint8"
},
{
"internalType": "bytes4[]",
"name": "functionSelectors",
"type": "bytes4[]"
}
],
"indexed": false,
"internalType": "struct IDiamondCut.FacetCut[]",
"name": "_diamondCut",
"type": "tuple[]"
},
{
"indexed": false,
"internalType": "address",
"name": "_init",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes",
"name": "_calldata",
"type": "bytes"
}
],
"name": "DiamondCut",
"type": "event"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "facetAddress",
"type": "address"
},
{
"internalType": "enum IDiamondCut.FacetCutAction",
"name": "action",
"type": "uint8"
},
{
"internalType": "bytes4[]",
"name": "functionSelectors",
"type": "bytes4[]"
}
],
"internalType": "struct IDiamondCut.FacetCut[]",
"name": "_diamondCut",
"type": "tuple[]"
},
{
"internalType": "address",
"name": "_init",
"type": "address"
},
{
"internalType": "bytes",
"name": "_calldata",
"type": "bytes"
}
],
"name": "diamondCut",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"transactionHash": "0x02bb6e8045d5d9b7c69dea3802d5e7a6d33a4844dd6f6263dc0c444604ecc450",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x09FD4F6088f2025427AB1e89257A44747081Ed59",
"contractAddress": null,
"transactionIndex": 5,
"gasUsed": "2337199",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xc5868af950eff0612b81b4eaa2c50c6ea5acd1adae1f490ff3ec830778ff4078",
"transactionHash": "0x02bb6e8045d5d9b7c69dea3802d5e7a6d33a4844dd6f6263dc0c444604ecc450",
"logs": [],
"blockNumber": 17842220,
"cumulativeGasUsed": "3051566",
"status": 1,
"byzantium": true
},
"args": [],
"solcInputHash": "7a183f869f73d4ccd46c6d23b208518b",
"metadata": "{\"compiler\":{\"version\":\"0.8.4+commit.c7e474f2\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"enum IDiamondCut.FacetCutAction\",\"name\":\"action\",\"type\":\"uint8\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"internalType\":\"struct IDiamondCut.FacetCut[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"diamondCut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"params\":{\"_calldata\":\"A function call, including function selector and arguments _calldata is executed with delegatecall on _init\",\"_diamondCut\":\"Contains the facet addresses and function selectors\",\"_init\":\"The address of the contract or facet to execute _calldata\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"diamondCut((address,uint8,bytes4[])[],address,bytes)\":{\"notice\":\"Add/replace/remove any number of functions and optionally execute a function with delegatecall\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/bridges/facets/DiamondCutFacet.sol\":\"DiamondCutFacet\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"src/bridges/facets/DiamondCutFacet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\nimport { IDiamondCut } from \\\"../interfaces/IDiamondCut.sol\\\";\\nimport { LibDiamond } from \\\"../libs/LibDiamond.sol\\\";\\n\\ncontract DiamondCutFacet is IDiamondCut {\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external override {\\n LibDiamond.enforceIsContractOwner();\\n LibDiamond.diamondCut(_diamondCut, _init, _calldata);\\n }\\n}\\n\",\"keccak256\":\"0x0387472f18c1949e2a6c12fccb216a6e17a28abbedf81c1d5c7a565c2c618c36\",\"license\":\"MIT\"},\"src/bridges/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\ninterface IDiamondCut {\\n enum FacetCutAction {\\n Add,\\n Replace,\\n Remove\\n }\\n // Add=0, Replace=1, Remove=2\\n\\n struct FacetCut {\\n address facetAddress;\\n FacetCutAction action;\\n bytes4[] functionSelectors;\\n }\\n\\n /// @notice Add/replace/remove any number of functions and optionally execute\\n /// a function with delegatecall\\n /// @param _diamondCut Contains the facet addresses and function selectors\\n /// @param _init The address of the contract or facet to execute _calldata\\n /// @param _calldata A function call, including function selector and arguments\\n /// _calldata is executed with delegatecall on _init\\n function diamondCut(\\n FacetCut[] calldata _diamondCut,\\n address _init,\\n bytes calldata _calldata\\n ) external;\\n\\n event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0x608723d9599dc5de624ca7af0751f834bdff25c5b02bc9e817b6f490d3324069\",\"license\":\"MIT\"},\"src/bridges/libs/LibDiamond.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.4;\\n\\nimport { IDiamondCut } from \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamond {\\n bytes32 internal constant DIAMOND_STORAGE_POSITION = keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n struct FacetAddressAndPosition {\\n address facetAddress;\\n uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n }\\n\\n struct FacetFunctionSelectors {\\n bytes4[] functionSelectors;\\n uint256 facetAddressPosition; // position of facetAddress in facetAddresses array\\n }\\n\\n struct DiamondStorage {\\n // maps function selector to the facet address and\\n // the position of the selector in the facetFunctionSelectors.selectors array\\n mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n // maps facet addresses to function selectors\\n mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n // facet addresses\\n address[] facetAddresses;\\n // Used to query if a contract implements an interface.\\n // Used to implement ERC-165.\\n mapping(bytes4 => bool) supportedInterfaces;\\n // owner of the contract\\n address contractOwner;\\n }\\n\\n function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n bytes32 position = DIAMOND_STORAGE_POSITION;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n ds.slot := position\\n }\\n }\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n function setContractOwner(address _newOwner) internal {\\n DiamondStorage storage ds = diamondStorage();\\n address previousOwner = ds.contractOwner;\\n ds.contractOwner = _newOwner;\\n emit OwnershipTransferred(previousOwner, _newOwner);\\n }\\n\\n function contractOwner() internal view returns (address contractOwner_) {\\n contractOwner_ = diamondStorage().contractOwner;\\n }\\n\\n function enforceIsContractOwner() internal view {\\n require(msg.sender == diamondStorage().contractOwner, \\\"LibDiamond: Must be contract owner\\\");\\n }\\n\\n event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);\\n\\n // Internal function version of diamondCut\\n function diamondCut(\\n IDiamondCut.FacetCut[] memory _diamondCut,\\n address _init,\\n bytes memory _calldata\\n ) internal {\\n for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;\\n if (action == IDiamondCut.FacetCutAction.Add) {\\n addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Replace) {\\n replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else if (action == IDiamondCut.FacetCutAction.Remove) {\\n removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);\\n } else {\\n revert(\\\"LibDiamondCut: Incorrect FacetCutAction\\\");\\n }\\n }\\n emit DiamondCut(_diamondCut, _init, _calldata);\\n initializeDiamondCut(_init, _calldata);\\n }\\n\\n function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress == address(0), \\\"LibDiamondCut: Can't add function that already exists\\\");\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Add facet can't be address(0)\\\");\\n uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);\\n // add new facet address if it does not exist\\n if (selectorPosition == 0) {\\n addFacet(ds, _facetAddress);\\n }\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n require(oldFacetAddress != _facetAddress, \\\"LibDiamondCut: Can't replace function with same function\\\");\\n removeFunction(ds, oldFacetAddress, selector);\\n addFunction(ds, selector, selectorPosition, _facetAddress);\\n selectorPosition++;\\n }\\n }\\n\\n function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {\\n require(_functionSelectors.length > 0, \\\"LibDiamondCut: No selectors in facet to cut\\\");\\n DiamondStorage storage ds = diamondStorage();\\n // if function does not exist then do nothing and return\\n require(_facetAddress == address(0), \\\"LibDiamondCut: Remove facet address must be address(0)\\\");\\n for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {\\n bytes4 selector = _functionSelectors[selectorIndex];\\n address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;\\n removeFunction(ds, oldFacetAddress, selector);\\n }\\n }\\n\\n function addFacet(DiamondStorage storage ds, address _facetAddress) internal {\\n enforceHasContractCode(_facetAddress, \\\"LibDiamondCut: New facet has no code\\\");\\n ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;\\n ds.facetAddresses.push(_facetAddress);\\n }\\n\\n function addFunction(\\n DiamondStorage storage ds,\\n bytes4 _selector,\\n uint96 _selectorPosition,\\n address _facetAddress\\n ) internal {\\n ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);\\n ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;\\n }\\n\\n function removeFunction(\\n DiamondStorage storage ds,\\n address _facetAddress,\\n bytes4 _selector\\n ) internal {\\n require(_facetAddress != address(0), \\\"LibDiamondCut: Can't remove function that doesn't exist\\\");\\n // an immutable function is a function defined directly in a diamond\\n require(_facetAddress != address(this), \\\"LibDiamondCut: Can't remove immutable function\\\");\\n // replace selector with last selector, then delete last selector\\n uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;\\n // if not the same then replace _selector with lastSelector\\n if (selectorPosition != lastSelectorPosition) {\\n bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;\\n ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);\\n }\\n // delete the last selector\\n ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();\\n delete ds.selectorToFacetAndPosition[_selector];\\n\\n // if no more selectors for facet address then delete the facet address\\n if (lastSelectorPosition == 0) {\\n // replace facet address with last facet address and delete last facet address\\n uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n if (facetAddressPosition != lastFacetAddressPosition) {\\n address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;\\n }\\n ds.facetAddresses.pop();\\n delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;\\n }\\n }\\n\\n function initializeDiamondCut(address _init, bytes memory _calldata) internal {\\n if (_init == address(0)) {\\n require(_calldata.length == 0, \\\"LibDiamondCut: _init is address(0) but_calldata is not empty\\\");\\n } else {\\n require(_calldata.length > 0, \\\"LibDiamondCut: _calldata is empty but _init is not address(0)\\\");\\n if (_init != address(this)) {\\n enforceHasContractCode(_init, \\\"LibDiamondCut: _init address has no code\\\");\\n }\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory error) = _init.delegatecall(_calldata);\\n if (!success) {\\n if (error.length > 0) {\\n // bubble up the error\\n revert(string(error));\\n } else {\\n revert(\\\"LibDiamondCut: _init function reverted\\\");\\n }\\n }\\n }\\n }\\n\\n function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {\\n uint256 contractSize;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n contractSize := extcodesize(_contract)\\n }\\n require(contractSize > 0, _errorMessage);\\n }\\n}\\n\",\"keccak256\":\"0x7a82c7c0bd4b049b5471c09127fad37873be021813abbe7ec07edb5a908c35e5\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x608060405234801561001057600080fd5b5061298d806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a60048036038101906100459190611b35565b61004c565b005b6100546100b6565b6100af8585906100649190612387565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610151565b5050505050565b6100be610571565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461014f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101469061204e565b60405180910390fd5b565b60005b8351811015610526576000848281518110610198577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151602001519050600060028111156101e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610219577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156102b6576102b185838151811061025b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106102a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516040015161059e565b610512565b600160028111156102f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610329577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156103c6576103c185838151811061036b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106103b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516040015161083d565b610511565b6002808111156103ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610438577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156104d5576104d085838151811061047a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106104bf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160400151610ae7565b610510565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610507906120ae565b60405180910390fd5b5b5b50808061051e90612412565b915050610154565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161055a93929190611fa7565b60405180910390a161056c8282610c98565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d99061206e565b60405180910390fd5b60006105ec610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561065e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610655906120ce565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1614156106cc576106cb8285610eab565b5b60005b8351811015610836576000848281518110610713577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061212e565b60405180910390fd5b6108138583868a610f86565b838061081e9061245b565b9450505050808061082e90612412565b9150506106cf565b5050505050565b6000815111610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061206e565b60405180910390fd5b600061088b610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f4906120ce565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16141561096b5761096a8285610eab565b5b60005b8351811015610ae05760008482815181106109b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d9061214e565b60405180910390fd5b610ab1858284611133565b610abd8583868a610f86565b8380610ac89061245b565b94505050508080610ad890612412565b91505061096e565b5050505050565b6000815111610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b229061206e565b60405180910390fd5b6000610b35610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9d9061216e565b60405180910390fd5b60005b8251811015610c92576000838281518110610bed577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610c7d848284611133565b50508080610c8a90612412565b915050610ba9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d16576000815114610d11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d089061200e565b60405180910390fd5b610ea7565b6000815111610d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d51906120ee565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610db057610daf826040518060600160405280602881526020016129356028913961187c565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610dd89190611f90565b600060405180830381855af49150503d8060008114610e13576040519150601f19603f3d011682016040523d82523d6000602084013e610e18565b606091505b509150915081610ea457600081511115610e6957806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e609190611fec565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9b9061202e565b60405180910390fd5b50505b5050565b610ecd8160405180606001604052806024815260200161295d6024913961187c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119a9061208e565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611212576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112099061210e565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805490506112e991906122c0565b90508082146114c95760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018281548110611370577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110611412577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908360e01c021790555082866000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505b8460010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805480611543577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002090600891828204019190066004026101000a81549063ffffffff02191690559055846000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000820160146101000a8154906bffffffffffffffffffffffff0219169055505060008114156118755760006001866002018054905061162e91906122c0565b905060008660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001015490508181146117bb5760008760020183815481106116be577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905080886002018381548110611728577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818860010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550505b866002018054806117f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905590558660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001016000905550505b5050505050565b6000823b90506000811182906118c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118bf9190611fec565b60405180910390fd5b50505050565b60006118e16118dc846121b3565b61218e565b9050808382526020820190508285602086028201111561190057600080fd5b60005b8581101561193057816119168882611a49565b845260208401935060208301925050600181019050611903565b5050509392505050565b600061194d611948846121df565b61218e565b9050808382526020820190508285602086028201111561196c57600080fd5b60005b858110156119b657813567ffffffffffffffff81111561198e57600080fd5b80860161199b8982611abd565b8552602085019450602084019350505060018101905061196f565b5050509392505050565b6000813590506119cf816128f6565b92915050565b600082601f8301126119e657600080fd5b81356119f68482602086016118ce565b91505092915050565b60008083601f840112611a1157600080fd5b8235905067ffffffffffffffff811115611a2a57600080fd5b602083019150836020820283011115611a4257600080fd5b9250929050565b600081359050611a588161290d565b92915050565b60008083601f840112611a7057600080fd5b8235905067ffffffffffffffff811115611a8957600080fd5b602083019150836001820283011115611aa157600080fd5b9250929050565b600081359050611ab781612924565b92915050565b600060608284031215611acf57600080fd5b611ad9606061218e565b90506000611ae9848285016119c0565b6000830152506020611afd84828501611aa8565b602083015250604082013567ffffffffffffffff811115611b1d57600080fd5b611b29848285016119d5565b60408301525092915050565b600080600080600060608688031215611b4d57600080fd5b600086013567ffffffffffffffff811115611b6757600080fd5b611b73888289016119ff565b95509550506020611b86888289016119c0565b935050604086013567ffffffffffffffff811115611ba357600080fd5b611baf88828901611a5e565b92509250509295509295909350565b6000611bca8383611cdb565b60208301905092915050565b6000611be28383611f40565b905092915050565b611bf3816122f4565b82525050565b611c02816122f4565b82525050565b6000611c138261222b565b611c1d8185612271565b9350611c288361220b565b8060005b83811015611c59578151611c408882611bbe565b9750611c4b83612257565b925050600181019050611c2c565b5085935050505092915050565b6000611c7182612236565b611c7b8185612282565b935083602082028501611c8d8561221b565b8060005b85811015611cc95784840389528151611caa8582611bd6565b9450611cb583612264565b925060208a01995050600181019050611c91565b50829750879550505050505092915050565b611ce481612306565b82525050565b6000611cf582612241565b611cff8185612293565b9350611d0f8185602086016123ae565b611d188161251d565b840191505092915050565b6000611d2e82612241565b611d3881856122a4565b9350611d488185602086016123ae565b80840191505092915050565b611d5d8161239c565b82525050565b6000611d6e8261224c565b611d7881856122af565b9350611d888185602086016123ae565b611d918161251d565b840191505092915050565b6000611da9603c836122af565b9150611db48261252e565b604082019050919050565b6000611dcc6026836122af565b9150611dd78261257d565b604082019050919050565b6000611def6022836122af565b9150611dfa826125cc565b604082019050919050565b6000611e12602b836122af565b9150611e1d8261261b565b604082019050919050565b6000611e356037836122af565b9150611e408261266a565b604082019050919050565b6000611e586027836122af565b9150611e63826126b9565b604082019050919050565b6000611e7b602c836122af565b9150611e8682612708565b604082019050919050565b6000611e9e603d836122af565b9150611ea982612757565b604082019050919050565b6000611ec1602e836122af565b9150611ecc826127a6565b604082019050919050565b6000611ee46035836122af565b9150611eef826127f5565b604082019050919050565b6000611f076038836122af565b9150611f1282612844565b604082019050919050565b6000611f2a6036836122af565b9150611f3582612893565b604082019050919050565b6000606083016000830151611f586000860182611bea565b506020830151611f6b6020860182611d54565b5060408301518482036040860152611f838282611c08565b9150508091505092915050565b6000611f9c8284611d23565b915081905092915050565b60006060820190508181036000830152611fc18186611c66565b9050611fd06020830185611bf9565b8181036040830152611fe28184611cea565b9050949350505050565b600060208201905081810360008301526120068184611d63565b905092915050565b6000602082019050818103600083015261202781611d9c565b9050919050565b6000602082019050818103600083015261204781611dbf565b9050919050565b6000602082019050818103600083015261206781611de2565b9050919050565b6000602082019050818103600083015261208781611e05565b9050919050565b600060208201905081810360008301526120a781611e28565b9050919050565b600060208201905081810360008301526120c781611e4b565b9050919050565b600060208201905081810360008301526120e781611e6e565b9050919050565b6000602082019050818103600083015261210781611e91565b9050919050565b6000602082019050818103600083015261212781611eb4565b9050919050565b6000602082019050818103600083015261214781611ed7565b9050919050565b6000602082019050818103600083015261216781611efa565b9050919050565b6000602082019050818103600083015261218781611f1d565b9050919050565b60006121986121a9565b90506121a482826123e1565b919050565b6000604051905090565b600067ffffffffffffffff8211156121ce576121cd6124ee565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156121fa576121f96124ee565b5b602082029050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b60006122cb82612365565b91506122d683612365565b9250828210156122e9576122e8612490565b5b828203905092915050565b60006122ff82612345565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6000819050612340826128e2565b919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006bffffffffffffffffffffffff82169050919050565b600061239436848461193a565b905092915050565b60006123a782612332565b9050919050565b60005b838110156123cc5780820151818401526020810190506123b1565b838111156123db576000848401525b50505050565b6123ea8261251d565b810181811067ffffffffffffffff82111715612409576124086124ee565b5b80604052505050565b600061241d82612365565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156124505761244f612490565b5b600182019050919050565b60006124668261236f565b91506bffffffffffffffffffffffff82141561248557612484612490565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860008201527f3029206275745f63616c6c64617461206973206e6f7420656d70747900000000602082015250565b7f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560008201527f7665727465640000000000000000000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60008201527f6572000000000000000000000000000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660008201527f6163657420746f20637574000000000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360008201527f74696f6e207468617420646f65736e2774206578697374000000000000000000602082015250565b7f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560008201527f74416374696f6e00000000000000000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260008201527f6520616464726573732830290000000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460008201527f7920627574205f696e6974206973206e6f742061646472657373283029000000602082015250565b7f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560008201527f7461626c652066756e6374696f6e000000000000000000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60008201527f6e207468617420616c7265616479206578697374730000000000000000000000602082015250565b7f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60008201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000602082015250565b7f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260008201527f657373206d757374206265206164647265737328302900000000000000000000602082015250565b600381106128f3576128f26124bf565b5b50565b6128ff816122f4565b811461290a57600080fd5b50565b61291681612306565b811461292157600080fd5b50565b6003811061293157600080fd5b5056fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e644375743a204e657720666163657420686173206e6f20636f6465a164736f6c6343000804000a",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631f931c1c14610030575b600080fd5b61004a60048036038101906100459190611b35565b61004c565b005b6100546100b6565b6100af8585906100649190612387565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610151565b5050505050565b6100be610571565b60040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461014f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101469061204e565b60405180910390fd5b565b60005b8351811015610526576000848281518110610198577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151602001519050600060028111156101e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610219577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156102b6576102b185838151811061025b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106102a0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516040015161059e565b610512565b600160028111156102f0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610329577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156103c6576103c185838151811061036b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106103b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516040015161083d565b610511565b6002808111156103ff577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816002811115610438577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156104d5576104d085838151811061047a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010151600001518684815181106104bf577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015160400151610ae7565b610510565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610507906120ae565b60405180910390fd5b5b5b50808061051e90612412565b915050610154565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67383838360405161055a93929190611fa7565b60405180910390a161056c8282610c98565b505050565b6000807fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90508091505090565b60008151116105e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105d99061206e565b60405180910390fd5b60006105ec610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561065e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610655906120ce565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff1614156106cc576106cb8285610eab565b5b60005b8351811015610836576000848281518110610713577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610807576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107fe9061212e565b60405180910390fd5b6108138583868a610f86565b838061081e9061245b565b9450505050808061082e90612412565b9150506106cf565b5050505050565b6000815111610881576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108789061206e565b60405180910390fd5b600061088b610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f4906120ce565b60405180910390fd5b60008160010160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018054905090506000816bffffffffffffffffffffffff16141561096b5761096a8285610eab565b5b60005b8351811015610ae05760008482815181106109b2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610aa6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9d9061214e565b60405180910390fd5b610ab1858284611133565b610abd8583868a610f86565b8380610ac89061245b565b94505050508080610ad890612412565b91505061096e565b5050505050565b6000815111610b2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b229061206e565b60405180910390fd5b6000610b35610571565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9d9061216e565b60405180910390fd5b60005b8251811015610c92576000838281518110610bed577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001015190506000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050610c7d848284611133565b50508080610c8a90612412565b915050610ba9565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610d16576000815114610d11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d089061200e565b60405180910390fd5b610ea7565b6000815111610d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d51906120ee565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610db057610daf826040518060600160405280602881526020016129356028913961187c565b5b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610dd89190611f90565b600060405180830381855af49150503d8060008114610e13576040519150601f19603f3d011682016040523d82523d6000602084013e610e18565b606091505b509150915081610ea457600081511115610e6957806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e609190611fec565b60405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9b9061202e565b60405180910390fd5b50505b5050565b610ecd8160405180606001604052806024815260200161295d6024913961187c565b81600201805490508260010160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555081600201819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b81846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508360010160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018390806001815401808255809150506001900390600052602060002090600891828204019190066004029091909190916101000a81548163ffffffff021916908360e01c021790555080846000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156111a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119a9061208e565b60405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611212576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112099061210e565b60405180910390fd5b6000836000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060000160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff169050600060018560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001805490506112e991906122c0565b90508082146114c95760008560010160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018281548110611370577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900460e01b9050808660010160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018481548110611412577f4e487b710000