false
false

Contract Address Details

0xefd739b52045d112c37c5d89a8771b31c165879c

Contract Name
DiamondCutFacet
Creator
0x4cbbe9–5bb1f1 at 0x299be8–5e3d39
Balance
0 Xai ( )
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
60135941
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
DiamondCutFacet




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
999999
EVM Version
paris




Verified at
2024-05-20T18:03:41.067239Z

lib/@lagunagames/lg-diamond-template/src/diamond/DiamondCutFacet.sol

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

import {IDiamondCut} from '../interfaces/IDiamondCut.sol';
import {LibContractOwner} from '../libraries/LibContractOwner.sol';
import {LibDiamond} from '../libraries/LibDiamond.sol';

/// @title LG extended DiamondCut Facet
/// @notice Adapted from the Diamond 3 reference implementation by Nick Mudge:
/// @notice https://github.com/mudgen/diamond-3-hardhat
contract DiamondCutFacet is IDiamondCut {
    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @dev The LG implementation DOES NOT SUPPORT initializers!
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    /// @custom:selector 0x1f931c1c == bytes4(keccak256("diamondCut((address,uint8,bytes4[])[],address,bytes)"))
    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external override {
        (_init); // noop
        (_calldata); // noop
        LibDiamond.enforceIsContractOwner();
        LibDiamond.diamondCut(_diamondCut);
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @dev This is a convenience implementation of the above
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @custom:selector 0xe57e69c6 == bytes4(keccak256("diamondCut((address,uint8,bytes4[])[])"))
    function diamondCut(FacetCut[] calldata _diamondCut) external {
        LibDiamond.enforceIsContractOwner();
        LibDiamond.diamondCut(_diamondCut);
    }

    /// @notice Removes one selector from the Diamond, using DiamondCut
    /// @param selector - The byte4 signature for a method selector to remove
    /// @custom:emits FacetCutAction
    function cutSelector(bytes4 selector) external {
        LibContractOwner.enforceIsContractOwner();
        IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
        bytes4[] memory functionSelectors = new bytes4[](1);
        functionSelectors[0] = selector;
        cut[0] = IDiamondCut.FacetCut({
            facetAddress: address(0),
            action: IDiamondCut.FacetCutAction.Remove,
            functionSelectors: functionSelectors
        });
        LibDiamond.diamondCut(cut);
    }

    /// @notice Removes one selector from the Diamond, using removeFunction()
    /// @param selector - The byte4 signature for a method selector to remove
    function deleteSelector(bytes4 selector) external {
        LibContractOwner.enforceIsContractOwner();
        LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
        LibDiamond.removeFunction(ds, ds.selectorToFacetAndPosition[selector].facetAddress, selector);
    }

    /// @notice Removes many selectors from the Diamond, using DiamondCut
    /// @param selectors - Array of byte4 signatures for method selectors to remove
    /// @custom:emits FacetCutAction
    function cutSelectors(bytes4[] memory selectors) external {
        LibContractOwner.enforceIsContractOwner();
        IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
        cut[0] = IDiamondCut.FacetCut({
            facetAddress: address(0),
            action: IDiamondCut.FacetCutAction.Remove,
            functionSelectors: selectors
        });
        LibDiamond.diamondCut(cut);
    }

    /// @notice Removes many selectors from the Diamond, using removeFunctions()
    /// @param selectors - Array of byte4 signatures for method selectors to remove
    function deleteSelectors(bytes4[] memory selectors) external {
        LibContractOwner.enforceIsContractOwner();
        LibDiamond.removeFunctions(address(0), selectors);
    }

    /// @notice Removes any selectors from the Diamond that come from a target
    /// @notice contract address, using DiamondCut.
    /// @param facet - The address of the Facet smart contract to remove
    /// @custom:emits FacetCutAction
    function cutFacet(address facet) external {
        LibContractOwner.enforceIsContractOwner();
        LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
        IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](1);
        cut[0] = IDiamondCut.FacetCut({
            facetAddress: address(0),
            action: IDiamondCut.FacetCutAction.Remove,
            functionSelectors: ds.facetFunctionSelectors[facet].functionSelectors
        });
        LibDiamond.diamondCut(cut);
    }
}
        

lib/@lagunagames/lg-diamond-template/src/interfaces/IDiamondCut.sol

//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

interface IDiamondCut {
    enum FacetCutAction {
        Add,
        Replace,
        Remove
    }
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
          

lib/@lagunagames/lg-diamond-template/src/libraries/LibContractOwner.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/// @title Library for the common LG implementation of ERC-173 Contract Ownership Standard
/// @author [email protected]
/// @custom:storage-location erc1967:eip1967.proxy.admin
library LibContractOwner {
    error CallerIsNotContractOwner();

    /// @notice This emits when ownership of a contract changes.
    /// @dev ERC-173
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Emitted when the admin account has changed.
    /// @dev ERC-1967
    event AdminChanged(address previousAdmin, address newAdmin);

    //  @dev Standard storage slot for the ERC-1967 admin address
    //  @dev bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
    bytes32 private constant ADMIN_SLOT_POSITION = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    struct LibOwnerStorage {
        address contractOwner;
    }

    /// @notice Storage slot for Contract Owner state data
    function ownerStorage() internal pure returns (LibOwnerStorage storage storageSlot) {
        bytes32 position = ADMIN_SLOT_POSITION;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            storageSlot.slot := position
        }
    }

    /// @notice Sets the contract owner
    /// @param newOwner The new owner
    /// @custom:emits OwnershipTransferred
    function setContractOwner(address newOwner) internal {
        LibOwnerStorage storage ls = ownerStorage();
        address previousOwner = ls.contractOwner;
        ls.contractOwner = newOwner;
        emit OwnershipTransferred(previousOwner, newOwner);
        emit AdminChanged(previousOwner, newOwner);
    }

    /// @notice Gets the contract owner wallet
    /// @return owner The contract owner
    function contractOwner() internal view returns (address owner) {
        owner = ownerStorage().contractOwner;
    }

    /// @notice Ensures that the caller is the contract owner, or throws an error.
    /// @custom:throws LibAccess: Must be contract owner
    function enforceIsContractOwner() internal view {
        if (msg.sender != ownerStorage().contractOwner) revert CallerIsNotContractOwner();
    }
}
          

lib/@lagunagames/lg-diamond-template/src/libraries/LibDiamond.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IDiamondCut} from '../interfaces/IDiamondCut.sol';
import {LibContractOwner} from './LibContractOwner.sol';

/// @title LibDiamond
/// @notice Library for the common LG implementation of ERC-2535 Diamond Proxy
/// @notice Adapted from the Diamond 3 reference implementation by Nick Mudge:
/// @notice https://github.com/mudgen/diamond-3-hardhat
/// @custom:storage-location erc2535:diamond.standard.diamond.storage
library LibDiamond {
    error InvalidFacetCutAction(IDiamondCut.FacetCutAction action);

    /// @notice Emitted when facets are added or removed
    /// @dev ERC-2535
    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    //  @dev Standard storage slot for the ERC-2535 Diamond storage
    //  @dev keccak256('diamond.standard.diamond.storage')
    bytes32 internal constant DIAMOND_STORAGE_POSITION =
        0xc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c;

    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // true if the diamond has been initialized
        bool initialized; //  THIS IS ONLY SET BY THE DIAMOND CONSTRUCTOR!
    }

    /// @notice Storage slot for Diamond storage
    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

    /// @notice Ensures that the caller is the contract owner, or throws an error.
    /// @dev Passthrough to LibContractOwner.enforceIsContractOwner()
    /// @custom:throws LibAccess: Must be contract owner
    function enforceIsContractOwner() internal view {
        LibContractOwner.enforceIsContractOwner();
    }

    // Internal function version of diamondCut
    function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; ++facetIndex) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert InvalidFacetCutAction(action);
            }
        }
        emit DiamondCut(_diamondCut, address(0), '');
    }

    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            ++selectorPosition;
        }
    }

    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            addFunction(ds, selector, selectorPosition, _facetAddress);
            ++selectorPosition;
        }
    }

    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, 'LibDiamondCut: No selectors in facet to cut');
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), 'LibDiamondCut: Remove facet address must be address(0)');
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; ++selectorIndex) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
        enforceHasContractCode(_facetAddress, 'LibDiamondCut: New facet has no code');
        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
        ds.facetAddresses.push(_facetAddress);
    }

    function addFunction(
        DiamondStorage storage ds,
        bytes4 _selector,
        uint96 _selectorPosition,
        address _facetAddress
    ) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}
          

Compiler Settings

{"viaIR":true,"remappings":["ds-test/=lib/forge-std/lib/ds-test/src/","forge-std/=lib/forge-std/src/"],"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":999999,"enabled":true,"details":{"yulDetails":{"stackAllocation":true,"optimizerSteps":"dhfoDgvulfnTUtnIf"},"yul":true,"peephole":true,"inliner":true,"deduplicate":true,"cse":true}},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"error","name":"CallerIsNotContractOwner","inputs":[]},{"type":"error","name":"InvalidFacetCutAction","inputs":[{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"}]},{"type":"event","name":"DiamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","indexed":false,"components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address","indexed":false},{"type":"bytes","name":"_calldata","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutFacet","inputs":[{"type":"address","name":"facet","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cutSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelector","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deleteSelectors","inputs":[{"type":"bytes4[]","name":"selectors","internalType":"bytes4[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]},{"type":"address","name":"_init","internalType":"address"},{"type":"bytes","name":"_calldata","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"diamondCut","inputs":[{"type":"tuple[]","name":"_diamondCut","internalType":"struct IDiamondCut.FacetCut[]","components":[{"type":"address","name":"facetAddress","internalType":"address"},{"type":"uint8","name":"action","internalType":"enum IDiamondCut.FacetCutAction"},{"type":"bytes4[]","name":"functionSelectors","internalType":"bytes4[]"}]}]}]
              

Contract Creation Code

0x60806040523461001a57604051611fc36100208239611fc390f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea26469706673582212204c8f26abad050a4c2e8b888a50adb23cd6b84b5d667e0b200800a5ca6553d39064736f6c63430008130033

Deployed ByteCode

0x6080604052600436101561001257600080fd5b60003560e01c80631f931c1c146100825780636463e3a01461007d578063a6638c0e14610078578063debb385614610073578063e0435c0b1461006e578063e57e69c6146100695763ff6f3e0b03610087576103e2565b6103c9565b61038b565b610373565b610347565b61031b565b610192565b600080fd5b909182601f830112156100875781359167ffffffffffffffff831161008757602001926020830284011161008757565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b73ffffffffffffffffffffffffffffffffffffffff81165b0361008757565b90503590610104826100d8565b565b909182601f830112156100875781359167ffffffffffffffff831161008757602001926001830284011161008757565b919060608382031261008757823567ffffffffffffffff8111610087578161015f91850161008c565b92909361016f83602083016100f7565b92604082013567ffffffffffffffff81116100875761018e9201610106565b9091565b34610087576101ae6101a5366004610136565b939290926104dc565b604051005b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761022257604052565b6101b3565b9061010461023460405190565b92836101e2565b67ffffffffffffffff81116102225760208091020190565b7fffffffff0000000000000000000000000000000000000000000000000000000081166100f0565b9050359061010482610253565b9092919261029d6102988261023b565b610227565b938185526020808601920283019281841161008757915b8383106102c15750505050565b602080916102cf848661027b565b8152019201916102b4565b9080601f83011215610087578160206100d593359101610288565b9060208282031261008757813567ffffffffffffffff8111610087576100d592016102da565b34610087576101ae61032e3660046102f5565b610801565b90602082820312610087576100d5916100f7565b34610087576101ae61035a366004610333565b610b64565b90602082820312610087576100d59161027b565b34610087576101ae61038636600461035f565b6106b7565b34610087576101ae61039e36600461035f565b6107d2565b9060208282031261008757813567ffffffffffffffff81116100875761018e920161008c565b34610087576101ae6103dc3660046103a3565b906104fb565b34610087576101ae6103f53660046102f5565b610835565b6003111561008757565b90503590610104826103fa565b919091606081840312610087576104286060610227565b92600061043582846100f7565b90850152602061044782828501610404565b90850152604082013567ffffffffffffffff81116100875761046992016102da565b6040830152565b92919061047f6102988261023b565b93818552602080860192028101918383116100875781905b8382106104a5575050505050565b813567ffffffffffffffff8111610087576020916104c68784938701610411565b815201910190610497565b6100d5913691610470565b90915061010493506104f692506104f1610cb1565b6104d1565b610ec2565b610104916104f6916104f1610cb1565b6100d56100d56100d59290565b906105256102988361023b565b918252565b6100d56060610227565b61053c61052a565b600080825260208201526060604082015290565b6100d5610534565b60005b82811061056757505050565b602090610572610550565b818401520161055b565b9061010461059261058c84610518565b9361023b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401610558565b369037565b906101046105d261058c84610518565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001602084016105bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90610635825190565b811015610646576020809102010190565b6105fd565b9052565b6100bc6100d56100d59290565b6100d59061064f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6003111561069e57565b610665565b9061010482610694565b9061064b906106a3565b610104906106c3610beb565b6107876107816106d3600161050b565b926106e66106e08561057c565b946105c2565b6107256000926106fe6106f88561050b565b8461062c565b907fffffffff00000000000000000000000000000000000000000000000000000000169052565b6107696107318361065c565b91610469600261076061074261052a565b73ffffffffffffffffffffffffffffffffffffffff90961687870152565b602085016106ad565b61077b6107758361050b565b8661062c565b5261050b565b8261062c565b50610ec2565b907fffffffff00000000000000000000000000000000000000000000000000000000165b600052602052604060002090565b6100d5906100bc565b6100d590546107bf565b610104906107de610beb565b6107e6610ca9565b6107fb60006107f5848461078d565b016107c8565b90611cc3565b6101049061080d610beb565b610787610781610825610820600161050b565b61057c565b926000906107696107318361065c565b61010490610841610beb565b61084b600061065c565b6115f4565b6100bc6100d56100d59273ffffffffffffffffffffffffffffffffffffffff1690565b6100d590610850565b6100d590610873565b906107b19061087c565b6100d59060201c60e01b90565b6100d59060401c60e01b90565b6100d59060601c60e01b90565b6100d59060801c60e01b90565b6100d59060a01c60e01b90565b6100d59060c01c60e01b90565b906109026108f66108ec845490565b8084529260200190565b92600052602060002090565b906000915b600783018211610a82575490808310610a64575b808310610a47575b808310610a2a575b808310610a0d575b8083106109f0575b8083106109d3575b8083106109b6575b821061095657505090565b826109af600193946109896020947fffffffff000000000000000000000000000000000000000000000000000000001690565b7fffffffff00000000000000000000000000000000000000000000000000000000169052565b0191505090565b91926020816109ca600193610989866108d0565b0193019161094b565b91926020816109e7600193610989866108c3565b01930191610943565b9192602081610a04600193610989866108b6565b0193019161093b565b9192602081610a21600193610989866108a9565b01930191610933565b9192602081610a3e6001936109898661089c565b0193019161092b565b9192602081610a5b6001936109898661088f565b01930191610923565b9192602081610a796001936109898660e01b90565b0193019161091b565b9260016020610989610b25600894838080808080808f5497610aa8816109898b60e01b90565b01610ab6816109898a61088f565b01610ac4816109898961089c565b01610ad281610989886108a9565b01610ae081610989876108b6565b01610aee81610989866108c3565b01610afc81610989856108d0565b019283917fffffffff000000000000000000000000000000000000000000000000000000001690565b019401920191610907565b906100d5916108dd565b90610104610b5492610b4b60405190565b93848092610b30565b03836101e2565b6100d590610b3a565b61010490610b70610beb565b610787610781610bb2610b81610ca9565b610769610469600192610be6610b996108208661050b565b986000968791610ba88361065c565b9760029501610885565b0191610bdd610bbf61052a565b73ffffffffffffffffffffffffffffffffffffffff90971688880152565b602086016106ad565b610b5b565b33610c19610bff6100bc60006107f5610c78565b9173ffffffffffffffffffffffffffffffffffffffff1690565b03610c2057565b6040517ff5d3c8cc000000000000000000000000000000000000000000000000000000008152600490fd5b0390fd5b6100d57fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610361050b565b6100d5610c4f565b6100d57fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c61050b565b6100d5610c80565b610104610beb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610d155760010190565b610cb9565b6100d590516106a3565b6100d5906106a3565b61064b90610d24565b6020810192916101049190610d2d565b0190565b90610d60610d596108ec845190565b9260200190565b9060005b818110610d715750505090565b909192610db0610da960019286517fffffffff0000000000000000000000000000000000000000000000000000000016815260200190565b9460200190565b929101610d64565b805173ffffffffffffffffffffffffffffffffffffffff1682526100d5916060810191604090610df060208201516020850190610d2d565b0151906040818403910152610d4a565b906100d591610db8565b90610e20610e16835190565b8083529160200190565b9081610e326020830284019460200190565b926000915b838310610e4657505050505090565b90919293946020610e69610e6283856001950387528951610e00565b9760200190565b9301930191939290610e37565b60608082526100d59392610eb091610e919190840190610e0a565b73ffffffffffffffffffffffffffffffffffffffff9093166020830152565b60408183039101526000815260200190565b9060005b610ed16100d5845190565b81101561101b57610eee6020610ee7838661062c565b5101610d1a565b600090610efa826106a3565b610f03826106a3565b03610f59575090610f4f610f3a610f5493610f1e848861062c565b51015173ffffffffffffffffffffffffffffffffffffffff1690565b6040610f46848861062c565b5101519061124c565b610ce8565b610ec6565b610f6360016106a3565b610f6c826106a3565b03610f9c575090610f4f610f87610f5493610f1e848861062c565b6040610f93848861062c565b5101519061144d565b610fa660026106a3565b610faf826106a3565b03610fdf575090610f4f610fca610f5493610f1e848861062c565b6040610fd6848861062c565b510151906115f4565b610c4b90610fec60405190565b9182917f32191c2900000000000000000000000000000000000000000000000000000000835260048301610d36565b5090611027600061065c565b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6739161105e61105560405190565b92839283610e76565b0390a1565b1561106a57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201527f6163657420746f206375740000000000000000000000000000000000000000006064820152608490fd5b156110f657565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201527f65206164647265737328302900000000000000000000000000000000000000006064820152608490fd5b6111886100d56100d59290565b6bffffffffffffffffffffffff1690565b156111a057565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c72656164792065786973747300000000000000000000006064820152608490fd5b6bffffffffffffffffffffffff166bffffffffffffffffffffffff8114610d155760010190565b9190611256815190565b61127260009161126c6112688461050b565b9190565b11611063565b61127a610ca9565b6112838261065c565b6112bc73ffffffffffffffffffffffffffffffffffffffff821673ffffffffffffffffffffffffffffffffffffffff88165b14156110ef565b6112da6112d5846112d08960018701610885565b015490565b61117b565b93846112fa6112e88661117b565b916bffffffffffffffffffffffff1690565b146113b2575b6000945b61130f6100d5835190565b8610156113a85761139c816113978a6113a2948961139161136c826107f58f6113638f9161133d908f61062c565b517fffffffff000000000000000000000000000000000000000000000000000000001690565b9586910161078d565b61138b73ffffffffffffffffffffffffffffffffffffffff8c16610bff565b14611199565b8961197e565b611225565b95610ce8565b94611304565b5050505050509050565b6113bc87846117ff565b611300565b156113c857565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e00000000000000006064820152608490fd5b815191929161146460009161126c6112688461050b565b61146c610ca9565b9061149861147c6100bc8361065c565b73ffffffffffffffffffffffffffffffffffffffff85166112b5565b6114ac6112d5826112d08660018701610885565b94856114ba6112e88461117b565b14611559575b6000955b6114cf6100d5835190565b87101561155057611544816113978761154a94876113918a6115068f6107f56114fc61133d87938f61062c565b809681950161078d565b61153e73ffffffffffffffffffffffffffffffffffffffff871673ffffffffffffffffffffffffffffffffffffffff831614156113c1565b8c611cc3565b96610ce8565b956114c4565b50505050509050565b61156384846117ff565b6114c0565b1561156f57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d7573742062652061646472657373283029000000000000000000006064820152608490fd5b8151600093929061160b9061126c6112688761050b565b61162c611616610ca9565b92611626610bff6100bc8861065c565b14611568565b60005b61163a6100d5835190565b8110156116705780610f4f61165561133d61166b948661062c565b611665886107f583828a0161078d565b86611cc3565b61162f565b5050509050565b67ffffffffffffffff811161022257602090601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b9061052561029883611677565b6116c960246116b2565b7f4c69624469616d6f6e644375743a204e657720666163657420686173206e6f2060208201527f636f646500000000000000000000000000000000000000000000000000000000604082015290565b6100d56116bf565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905b9181191691161790565b9061175e6100d56117659261050b565b8254611720565b9055565b805482101561064657611783600191600052602060002090565b91020190600090565b919060086117449102916117b373ffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b91906117c96100d56117659361087c565b90835461178c565b908154916801000000000000000083101561022257826117f991600161010495018155611769565b906117b8565b9061183c61010492611818611812611718565b84611f74565b6100d560028201916001611836868261182f875490565b9401610885565b0161174e565b6117d1565b907fffffffffffffffffffffffff00000000000000000000000000000000000000009060a01b611744565b6111886100d56100d5926bffffffffffffffffffffffff1690565b906118976100d56117659261186c565b8254611841565b80549192918310156106465760086118bd600492600052602060002090565b8185040193060290565b919060086117449102916117b363ffffffff841b90565b919061191561190f611765937fffffffff000000000000000000000000000000000000000000000000000000001690565b60e01c90565b9083546118c7565b908154916801000000000000000083101561022257826119459160016101049501815561189e565b906118de565b9073ffffffffffffffffffffffffffffffffffffffff90611744565b906119776100d56117659261087c565b825461194b565b8184936119bb6000946119b686610d466101049a60016119c0996119b085820199866119aa8a8d61078d565b01611887565b01610885565b61191d565b61078d565b01611967565b156119cd57565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e27742065786973740000000000000000006064820152608490fd5b15611a5957565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e0000000000000000000000000000000000006064820152608490fd5b6100d59060a01c611188565b6100d59054611ade565b6100d56100d56100d5926bffffffffffffffffffffffff1690565b91908203918211610d1557565b6100d5916008021c60e01b90565b906100d59154611b1c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b610104916000916118de565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611ba8838361189e565b90611b64565b55565b611b35565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600060045260246000fd5b90600003611bf35760009055565b611bb6565b6100d59081565b6100d59054611bf8565b6100d5916008021c6100bc565b906100d59154611c09565b610104916000916117b8565b80548015611bb1577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190611bae611c658383611769565b90611c21565b919060086117449102916117b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b9190611caf6100d56117659361050b565b908354611c6b565b61010491600091611c9e565b611d789092919283600093611cfb611cdd6100bc8761065c565b73ffffffffffffffffffffffffffffffffffffffff841614156119c6565b611d28611d0a6100bc3061087c565b73ffffffffffffffffffffffffffffffffffffffff84161415611a52565b611da985611da481860193611d4f611d4a84611d44848961078d565b01611aea565b611af4565b94611d61846112d08960018c01610885565b87858a60019c8d94611d728661050b565b90611b0f565b809a611d818290565b8103611e59575b5050611d9f92506119bb93610d4691019e8f610885565b611b70565b611be5565b611db56112688661050b565b14611dc2575b5050505050565b611e1a94611e0f611e0a6002611e149501611de7611dde825490565b611d728961050b565b611dfb88611df58888610885565b01611bff565b88828203611e24575b50505090565b611c2d565b610885565b01611cb7565b3880808080611dbb565b611836611e3d611e37611e519587611769565b90611c16565b611e4b816117f98689611769565b88610885565b388088611e04565b6112d5856119458387611e84611e90611e8a611e989984611e9f9f611e84906119aa9e01998a610885565b0161189e565b90611b2a565b9a8b95610885565b928561078d565b8887858a8938611d88565b60005b838110611ebd5750506000910152565b8181015183820152602001611ead565b611eee611ef7602093610d4693611ee2815190565b80835293849260200190565b95869101611eaa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b60208082526100d592910190611ecd565b15611f385750565b610c4b90611f4560405190565b9182917f08c379a000000000000000000000000000000000000000000000000000000000835260048301611f1f565b61010491903b611f87611268600061050b565b11611f3056fea26469706673582212204c8f26abad050a4c2e8b888a50adb23cd6b84b5d667e0b200800a5ca6553d39064736f6c63430008130033