ETH Price: $3,271.74 (+0.69%)
Gas: 1 Gwei

Token

 

Overview

Max Total Supply

272

Holders

134

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
zhukov99.eth
Balance
1
0x4c4791E1259dfD836a8ABc943C1389E244F401D1
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
STDDiamond

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 99999 runs

Other Settings:
default evmVersion, MIT license
File 1 of 34 : IERC173.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173Internal } from './IERC173Internal.sol';

/**
 * @title Contract ownership standard interface
 * @dev see https://eips.ethereum.org/EIPS/eip-173
 */
interface IERC173 is IERC173Internal {
    /**
     * @notice get the ERC173 contract owner
     * @return conrtact owner
     */
    function owner() external view returns (address);

    /**
     * @notice transfer contract ownership to new account
     * @param account address of new owner
     */
    function transferOwnership(address account) external;
}

File 2 of 34 : IERC173Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC173 interface needed by internal functions
 */
interface IERC173Internal {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
}

File 3 of 34 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../IERC173.sol';

interface IOwnable is IERC173 {}

File 4 of 34 : IOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173Internal } from '../IERC173Internal.sol';

interface IOwnableInternal is IERC173Internal {}

File 5 of 34 : ISafeOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnable } from './IOwnable.sol';

interface ISafeOwnable is IOwnable {
    /**
     * @notice get the nominated owner who has permission to call acceptOwnership
     */
    function nomineeOwner() external view returns (address);

    /**
     * @notice accept transfer of contract ownership
     */
    function acceptOwnership() external;
}

File 6 of 34 : ISafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnableInternal } from './IOwnableInternal.sol';

interface ISafeOwnableInternal is IOwnableInternal {}

File 7 of 34 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../IERC173.sol';
import { IOwnable } from './IOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';

/**
 * @title Ownership access control based on ERC173
 */
abstract contract Ownable is IOwnable, OwnableInternal {
    using OwnableStorage for OwnableStorage.Layout;

    /**
     * @inheritdoc IERC173
     */
    function owner() public view virtual returns (address) {
        return _owner();
    }

    /**
     * @inheritdoc IERC173
     */
    function transferOwnership(address account) public virtual onlyOwner {
        _transferOwnership(account);
    }
}

File 8 of 34 : OwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { AddressUtils } from '../../utils/AddressUtils.sol';
import { IERC173 } from '../IERC173.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';

abstract contract OwnableInternal is IOwnableInternal {
    using AddressUtils for address;
    using OwnableStorage for OwnableStorage.Layout;

    modifier onlyOwner() {
        require(msg.sender == _owner(), 'Ownable: sender must be owner');
        _;
    }

    modifier onlyTransitiveOwner() {
        require(
            msg.sender == _transitiveOwner(),
            'Ownable: sender must be transitive owner'
        );
        _;
    }

    function _owner() internal view virtual returns (address) {
        return OwnableStorage.layout().owner;
    }

    function _transitiveOwner() internal view virtual returns (address) {
        address owner = _owner();

        while (owner.isContract()) {
            try IERC173(owner).owner() returns (address transitiveOwner) {
                owner = transitiveOwner;
            } catch {
                return owner;
            }
        }

        return owner;
    }

    function _transferOwnership(address account) internal virtual {
        OwnableStorage.layout().setOwner(account);
        emit OwnershipTransferred(msg.sender, account);
    }
}

File 9 of 34 : OwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library OwnableStorage {
    struct Layout {
        address owner;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.Ownable');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }

    function setOwner(Layout storage l, address owner) internal {
        l.owner = owner;
    }
}

File 10 of 34 : SafeOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Ownable, OwnableStorage } from './Ownable.sol';
import { ISafeOwnable } from './ISafeOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableInternal } from './SafeOwnableInternal.sol';

/**
 * @title Ownership access control based on ERC173 with ownership transfer safety check
 */
abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal {
    /**
     * @inheritdoc ISafeOwnable
     */
    function nomineeOwner() public view virtual returns (address) {
        return _nomineeOwner();
    }

    /**
     * @inheritdoc ISafeOwnable
     */
    function acceptOwnership() public virtual onlyNomineeOwner {
        _acceptOwnership();
    }

    function _transferOwnership(address account)
        internal
        virtual
        override(OwnableInternal, SafeOwnableInternal)
    {
        super._transferOwnership(account);
    }
}

File 11 of 34 : SafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';

abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
    using OwnableStorage for OwnableStorage.Layout;
    using SafeOwnableStorage for SafeOwnableStorage.Layout;

    modifier onlyNomineeOwner() {
        require(
            msg.sender == _nomineeOwner(),
            'SafeOwnable: sender must be nominee owner'
        );
        _;
    }

    /**
     * @notice get the nominated owner who has permission to call acceptOwnership
     */
    function _nomineeOwner() internal view virtual returns (address) {
        return SafeOwnableStorage.layout().nomineeOwner;
    }

    /**
     * @notice accept transfer of contract ownership
     */
    function _acceptOwnership() internal virtual {
        OwnableStorage.Layout storage l = OwnableStorage.layout();
        emit OwnershipTransferred(l.owner, msg.sender);
        l.setOwner(msg.sender);
        SafeOwnableStorage.layout().setNomineeOwner(address(0));
    }

    /**
     * @notice set nominee owner, granting permission to call acceptOwnership
     */
    function _transferOwnership(address account) internal virtual override {
        SafeOwnableStorage.layout().setNomineeOwner(account);
    }
}

File 12 of 34 : SafeOwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library SafeOwnableStorage {
    struct Layout {
        address nomineeOwner;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.SafeOwnable');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }

    function setNomineeOwner(Layout storage l, address nomineeOwner) internal {
        l.nomineeOwner = nomineeOwner;
    }
}

File 13 of 34 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from './IERC165.sol';
import { ERC165Storage } from './ERC165Storage.sol';

/**
 * @title ERC165 implementation
 */
abstract contract ERC165 is IERC165 {
    using ERC165Storage for ERC165Storage.Layout;

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return ERC165Storage.layout().isSupportedInterface(interfaceId);
    }
}

File 14 of 34 : ERC165Storage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC165Storage {
    struct Layout {
        mapping(bytes4 => bool) supportedInterfaces;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC165');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }

    function isSupportedInterface(Layout storage l, bytes4 interfaceId)
        internal
        view
        returns (bool)
    {
        return l.supportedInterfaces[interfaceId];
    }

    function setSupportedInterface(
        Layout storage l,
        bytes4 interfaceId,
        bool status
    ) internal {
        require(interfaceId != 0xffffffff, 'ERC165: invalid interface id');
        l.supportedInterfaces[interfaceId] = status;
    }
}

File 15 of 34 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title ERC165 interface registration interface
 * @dev see https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 {
    /**
     * @notice query whether contract has registered support for given interface
     * @param interfaceId interface id
     * @return bool whether interface is supported
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 16 of 34 : DiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Proxy } from '../../Proxy.sol';
import { IDiamondBase } from './IDiamondBase.sol';
import { DiamondBaseStorage } from './DiamondBaseStorage.sol';

/**
 * @title EIP-2535 "Diamond" proxy base contract
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
abstract contract DiamondBase is IDiamondBase, Proxy {
    /**
     * @inheritdoc Proxy
     */
    function _getImplementation() internal view override returns (address) {
        // inline storage layout retrieval uses less gas
        DiamondBaseStorage.Layout storage l;
        bytes32 slot = DiamondBaseStorage.STORAGE_SLOT;
        assembly {
            l.slot := slot
        }

        address implementation = address(bytes20(l.facets[msg.sig]));

        if (implementation == address(0)) {
            implementation = l.fallbackAddress;
            require(
                implementation != address(0),
                'DiamondBase: no facet found for function signature'
            );
        }

        return implementation;
    }
}

File 17 of 34 : DiamondBaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { AddressUtils } from '../../../utils/AddressUtils.sol';
import { IDiamondWritable } from '../writable/IDiamondWritable.sol';

/**
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
library DiamondBaseStorage {
    using AddressUtils for address;
    using DiamondBaseStorage for DiamondBaseStorage.Layout;

    struct Layout {
        // function selector => (facet address, selector slot position)
        mapping(bytes4 => bytes32) facets;
        // total number of selectors registered
        uint16 selectorCount;
        // array of selector slots with 8 selectors per slot
        mapping(uint256 => bytes32) selectorSlots;
        address fallbackAddress;
    }

    bytes32 constant CLEAR_ADDRESS_MASK =
        bytes32(uint256(0xffffffffffffffffffffffff));
    bytes32 constant CLEAR_SELECTOR_MASK = bytes32(uint256(0xffffffff << 224));

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.DiamondBase');

    event DiamondCut(
        IDiamondWritable.FacetCut[] facetCuts,
        address target,
        bytes data
    );

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }

    /**
     * @notice update functions callable on Diamond proxy
     * @param l storage layout
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional recipient of initialization delegatecall
     * @param data optional initialization call data
     */
    function diamondCut(
        Layout storage l,
        IDiamondWritable.FacetCut[] memory facetCuts,
        address target,
        bytes memory data
    ) internal {
        unchecked {
            uint256 originalSelectorCount = l.selectorCount;
            uint256 selectorCount = originalSelectorCount;
            bytes32 selectorSlot;

            // Check if last selector slot is not full
            if (selectorCount & 7 > 0) {
                // get last selectorSlot
                selectorSlot = l.selectorSlots[selectorCount >> 3];
            }

            for (uint256 i; i < facetCuts.length; i++) {
                IDiamondWritable.FacetCut memory facetCut = facetCuts[i];
                IDiamondWritable.FacetCutAction action = facetCut.action;

                require(
                    facetCut.selectors.length > 0,
                    'DiamondBase: no selectors specified'
                );

                if (action == IDiamondWritable.FacetCutAction.ADD) {
                    (selectorCount, selectorSlot) = l.addFacetSelectors(
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                } else if (action == IDiamondWritable.FacetCutAction.REPLACE) {
                    l.replaceFacetSelectors(facetCut);
                } else if (action == IDiamondWritable.FacetCutAction.REMOVE) {
                    (selectorCount, selectorSlot) = l.removeFacetSelectors(
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                }
            }

            if (selectorCount != originalSelectorCount) {
                l.selectorCount = uint16(selectorCount);
            }

            // If last selector slot is not full
            if (selectorCount & 7 > 0) {
                l.selectorSlots[selectorCount >> 3] = selectorSlot;
            }

            emit DiamondCut(facetCuts, target, data);
            initialize(target, data);
        }
    }

    function addFacetSelectors(
        Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        IDiamondWritable.FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            require(
                facetCut.target == address(this) ||
                    facetCut.target.isContract(),
                'DiamondBase: ADD target has no code'
            );

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];

                require(
                    address(bytes20(oldFacet)) == address(0),
                    'DiamondBase: selector already added'
                );

                // add facet for selector
                l.facets[selector] =
                    bytes20(facetCut.target) |
                    bytes32(selectorCount);
                uint256 selectorInSlotPosition = (selectorCount & 7) << 5;

                // clear selector position in slot and add selector
                selectorSlot =
                    (selectorSlot &
                        ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |
                    (bytes32(selector) >> selectorInSlotPosition);

                // if slot is full then write it to storage
                if (selectorInSlotPosition == 224) {
                    l.selectorSlots[selectorCount >> 3] = selectorSlot;
                    selectorSlot = 0;
                }

                selectorCount++;
            }

            return (selectorCount, selectorSlot);
        }
    }

    function removeFacetSelectors(
        Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        IDiamondWritable.FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            require(
                facetCut.target == address(0),
                'DiamondBase: REMOVE target must be zero address'
            );

            uint256 selectorSlotCount = selectorCount >> 3;
            uint256 selectorInSlotIndex = selectorCount & 7;

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];

                require(
                    address(bytes20(oldFacet)) != address(0),
                    'DiamondBase: selector not found'
                );

                require(
                    address(bytes20(oldFacet)) != address(this),
                    'DiamondBase: selector is immutable'
                );

                if (selectorSlot == 0) {
                    selectorSlotCount--;
                    selectorSlot = l.selectorSlots[selectorSlotCount];
                    selectorInSlotIndex = 7;
                } else {
                    selectorInSlotIndex--;
                }

                bytes4 lastSelector;
                uint256 oldSelectorsSlotCount;
                uint256 oldSelectorInSlotPosition;

                // adding a block here prevents stack too deep error
                {
                    // replace selector with last selector in l.facets
                    lastSelector = bytes4(
                        selectorSlot << (selectorInSlotIndex << 5)
                    );

                    if (lastSelector != selector) {
                        // update last selector slot position info
                        l.facets[lastSelector] =
                            (oldFacet & CLEAR_ADDRESS_MASK) |
                            bytes20(l.facets[lastSelector]);
                    }

                    delete l.facets[selector];
                    uint256 oldSelectorCount = uint16(uint256(oldFacet));
                    oldSelectorsSlotCount = oldSelectorCount >> 3;
                    oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;
                }

                if (oldSelectorsSlotCount != selectorSlotCount) {
                    bytes32 oldSelectorSlot = l.selectorSlots[
                        oldSelectorsSlotCount
                    ];

                    // clears the selector we are deleting and puts the last selector in its place.
                    oldSelectorSlot =
                        (oldSelectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);

                    // update storage with the modified slot
                    l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
                } else {
                    // clears the selector we are deleting and puts the last selector in its place.
                    selectorSlot =
                        (selectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);
                }

                if (selectorInSlotIndex == 0) {
                    delete l.selectorSlots[selectorSlotCount];
                    selectorSlot = 0;
                }
            }

            selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex;

            return (selectorCount, selectorSlot);
        }
    }

    function replaceFacetSelectors(
        Layout storage l,
        IDiamondWritable.FacetCut memory facetCut
    ) internal {
        unchecked {
            require(
                facetCut.target.isContract(),
                'DiamondBase: REPLACE target has no code'
            );

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];
                address oldFacetAddress = address(bytes20(oldFacet));

                require(
                    oldFacetAddress != address(0),
                    'DiamondBase: selector not found'
                );

                require(
                    oldFacetAddress != address(this),
                    'DiamondBase: selector is immutable'
                );

                require(
                    oldFacetAddress != facetCut.target,
                    'DiamondBase: REPLACE target is identical'
                );

                // replace old facet address
                l.facets[selector] =
                    (oldFacet & CLEAR_ADDRESS_MASK) |
                    bytes20(facetCut.target);
            }
        }
    }

    function initialize(address target, bytes memory data) private {
        require(
            (target == address(0)) == (data.length == 0),
            'DiamondBase: invalid initialization parameters'
        );

        if (target != address(0)) {
            if (target != address(this)) {
                require(
                    target.isContract(),
                    'DiamondBase: initialization target has no code'
                );
            }

            (bool success, ) = target.delegatecall(data);

            if (!success) {
                assembly {
                    returndatacopy(0, 0, returndatasize())
                    revert(0, returndatasize())
                }
            }
        }
    }
}

File 18 of 34 : IDiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IProxy } from '../../IProxy.sol';

interface IDiamondBase is IProxy {}

File 19 of 34 : ISolidStateDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol';
import { IERC165 } from '../../introspection/IERC165.sol';
import { IDiamondBase } from './base/IDiamondBase.sol';
import { IDiamondReadable } from './readable/IDiamondReadable.sol';
import { IDiamondWritable } from './writable/IDiamondWritable.sol';

interface ISolidStateDiamond is
    IDiamondBase,
    IDiamondReadable,
    IDiamondWritable,
    ISafeOwnable,
    IERC165
{
    receive() external payable;

    /**
     * @notice get the address of the fallback contract
     * @return fallback address
     */
    function getFallbackAddress() external view returns (address);

    /**
     * @notice set the address of the fallback contract
     * @param fallbackAddress fallback address
     */
    function setFallbackAddress(address fallbackAddress) external;
}

File 20 of 34 : DiamondReadable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadable } from './IDiamondReadable.sol';

/**
 * @title EIP-2535 "Diamond" proxy introspection contract
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
abstract contract DiamondReadable is IDiamondReadable {
    /**
     * @inheritdoc IDiamondReadable
     */
    function facets() external view returns (Facet[] memory diamondFacets) {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        diamondFacets = new Facet[](l.selectorCount);

        uint8[] memory numFacetSelectors = new uint8[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (diamondFacets[facetIndex].target == facet) {
                        diamondFacets[facetIndex].selectors[
                            numFacetSelectors[facetIndex]
                        ] = selector;
                        // probably will never have more than 256 functions from one facet contract
                        require(numFacetSelectors[facetIndex] < 255);
                        numFacetSelectors[facetIndex]++;
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                diamondFacets[numFacets].target = facet;
                diamondFacets[numFacets].selectors = new bytes4[](
                    l.selectorCount
                );
                diamondFacets[numFacets].selectors[0] = selector;
                numFacetSelectors[numFacets] = 1;
                numFacets++;
            }
        }

        for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
            uint256 numSelectors = numFacetSelectors[facetIndex];
            bytes4[] memory selectors = diamondFacets[facetIndex].selectors;

            // setting the number of selectors
            assembly {
                mstore(selectors, numSelectors)
            }
        }

        // setting the number of facets
        assembly {
            mstore(diamondFacets, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetFunctionSelectors(address facet)
        external
        view
        returns (bytes4[] memory selectors)
    {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        selectors = new bytes4[](l.selectorCount);

        uint256 numSelectors;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));

                if (facet == address(bytes20(l.facets[selector]))) {
                    selectors[numSelectors] = selector;
                    numSelectors++;
                }
            }
        }

        // set the number of selectors in the array
        assembly {
            mstore(selectors, numSelectors)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses)
    {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        addresses = new address[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

            for (
                uint256 selectorSlotIndex;
                selectorSlotIndex < 8;
                selectorSlotIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (facet == addresses[facetIndex]) {
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                addresses[numFacets] = facet;
                numFacets++;
            }
        }

        // set the number of facet addresses in the array
        assembly {
            mstore(addresses, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddress(bytes4 selector)
        external
        view
        returns (address facet)
    {
        facet = address(bytes20(DiamondBaseStorage.layout().facets[selector]));
    }
}

File 21 of 34 : IDiamondReadable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Diamond proxy introspection interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondReadable {
    struct Facet {
        address target;
        bytes4[] selectors;
    }

    /**
     * @notice get all facets and their selectors
     * @return diamondFacets array of structured facet data
     */
    function facets() external view returns (Facet[] memory diamondFacets);

    /**
     * @notice get all selectors for given facet address
     * @param facet address of facet to query
     * @return selectors array of function selectors
     */
    function facetFunctionSelectors(address facet)
        external
        view
        returns (bytes4[] memory selectors);

    /**
     * @notice get addresses of all facets used by diamond
     * @return addresses array of facet addresses
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses);

    /**
     * @notice get the address of the facet associated with given selector
     * @param selector function selector to query
     * @return facet facet address (zero address if not found)
     */
    function facetAddress(bytes4 selector)
        external
        view
        returns (address facet);
}

File 22 of 34 : SolidStateDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnable, Ownable, OwnableInternal, OwnableStorage } from '../../access/ownable/Ownable.sol';
import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol';
import { IERC173 } from '../../access/IERC173.sol';
import { ERC165, IERC165, ERC165Storage } from '../../introspection/ERC165.sol';
import { DiamondBase, DiamondBaseStorage } from './base/DiamondBase.sol';
import { DiamondReadable, IDiamondReadable } from './readable/DiamondReadable.sol';
import { DiamondWritable, IDiamondWritable } from './writable/DiamondWritable.sol';
import { ISolidStateDiamond } from './ISolidStateDiamond.sol';

/**
 * @title SolidState "Diamond" proxy reference implementation
 */
abstract contract SolidStateDiamond is
    ISolidStateDiamond,
    DiamondBase,
    DiamondReadable,
    DiamondWritable,
    SafeOwnable,
    ERC165
{
    using DiamondBaseStorage for DiamondBaseStorage.Layout;
    using ERC165Storage for ERC165Storage.Layout;
    using OwnableStorage for OwnableStorage.Layout;

    constructor() {
        ERC165Storage.Layout storage erc165 = ERC165Storage.layout();
        bytes4[] memory selectors = new bytes4[](12);

        // register DiamondWritable

        selectors[0] = IDiamondWritable.diamondCut.selector;

        erc165.setSupportedInterface(type(IDiamondWritable).interfaceId, true);

        // register DiamondReadable

        selectors[1] = IDiamondReadable.facets.selector;
        selectors[2] = IDiamondReadable.facetFunctionSelectors.selector;
        selectors[3] = IDiamondReadable.facetAddresses.selector;
        selectors[4] = IDiamondReadable.facetAddress.selector;

        erc165.setSupportedInterface(type(IDiamondReadable).interfaceId, true);

        // register ERC165

        selectors[5] = IERC165.supportsInterface.selector;

        erc165.setSupportedInterface(type(IERC165).interfaceId, true);

        // register SafeOwnable

        selectors[6] = Ownable.owner.selector;
        selectors[7] = SafeOwnable.nomineeOwner.selector;
        selectors[8] = Ownable.transferOwnership.selector;
        selectors[9] = SafeOwnable.acceptOwnership.selector;

        erc165.setSupportedInterface(type(IERC173).interfaceId, true);

        // register Diamond

        selectors[10] = SolidStateDiamond.getFallbackAddress.selector;
        selectors[11] = SolidStateDiamond.setFallbackAddress.selector;

        // diamond cut

        FacetCut[] memory facetCuts = new FacetCut[](1);

        facetCuts[0] = FacetCut({
            target: address(this),
            action: IDiamondWritable.FacetCutAction.ADD,
            selectors: selectors
        });

        DiamondBaseStorage.layout().diamondCut(facetCuts, address(0), '');

        // set owner

        OwnableStorage.layout().setOwner(msg.sender);
    }

    receive() external payable {}

    /**
     * @inheritdoc ISolidStateDiamond
     */
    function getFallbackAddress() external view returns (address) {
        return DiamondBaseStorage.layout().fallbackAddress;
    }

    /**
     * @inheritdoc ISolidStateDiamond
     */
    function setFallbackAddress(address fallbackAddress) external onlyOwner {
        DiamondBaseStorage.layout().fallbackAddress = fallbackAddress;
    }

    function _transferOwnership(address account)
        internal
        virtual
        override(OwnableInternal, SafeOwnable)
    {
        super._transferOwnership(account);
    }
}

File 23 of 34 : DiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondWritable } from './IDiamondWritable.sol';

/**
 * @title EIP-2535 "Diamond" proxy update contract
 */
abstract contract DiamondWritable is IDiamondWritable, OwnableInternal {
    using DiamondBaseStorage for DiamondBaseStorage.Layout;

    /**
     * @inheritdoc IDiamondWritable
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external onlyOwner {
        DiamondBaseStorage.layout().diamondCut(facetCuts, target, data);
    }
}

File 24 of 34 : IDiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Diamond proxy upgrade interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondWritable {
    enum FacetCutAction {
        ADD,
        REPLACE,
        REMOVE
    }

    event DiamondCut(FacetCut[] facetCuts, address target, bytes data);

    struct FacetCut {
        address target;
        FacetCutAction action;
        bytes4[] selectors;
    }

    /**
     * @notice update diamond facets and optionally execute arbitrary initialization function
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional target of initialization delegatecall
     * @param data optional initialization function call data
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external;
}

File 25 of 34 : IProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IProxy {
    fallback() external payable;
}

File 26 of 34 : Proxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { AddressUtils } from '../utils/AddressUtils.sol';
import { IProxy } from './IProxy.sol';

/**
 * @title Base proxy contract
 */
abstract contract Proxy is IProxy {
    using AddressUtils for address;

    /**
     * @notice delegate all calls to implementation contract
     * @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts
     * @dev memory location in use by assembly may be unsafe in other contexts
     */
    fallback() external payable virtual {
        address implementation = _getImplementation();

        require(
            implementation.isContract(),
            'Proxy: implementation must be contract'
        );

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(
                gas(),
                implementation,
                0,
                calldatasize(),
                0,
                0
            )
            returndatacopy(0, 0, returndatasize())

            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @notice get logic implementation address
     * @return implementation address
     */
    function _getImplementation() internal virtual returns (address);
}

File 27 of 34 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IERC721Enumerable {
    /**
     * @notice get total token supply
     * @return total supply
     */
    function totalSupply() external view returns (uint256);

    /**
     * @notice get token of given owner at given internal storage index
     * @param owner token holder to query
     * @param index position in owner's token list to query
     * @return tokenId id of retrieved token
     */
    function tokenOfOwnerByIndex(address owner, uint256 index)
        external
        view
        returns (uint256 tokenId);

    /**
     * @notice get token at given internal storage index
     * @param index position in global token list to query
     * @return tokenId id of retrieved token
     */
    function tokenByIndex(uint256 index)
        external
        view
        returns (uint256 tokenId);
}

File 28 of 34 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC165 } from '../../introspection/IERC165.sol';
import { IERC721Internal } from './IERC721Internal.sol';

/**
 * @title ERC721 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721 is IERC721Internal, IERC165 {
    /**
     * @notice query the balance of given address
     * @return balance quantity of tokens held
     */
    function balanceOf(address account) external view returns (uint256 balance);

    /**
     * @notice query the owner of given token
     * @param tokenId token to query
     * @return owner token owner
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice transfer token between given addresses, checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     * @param data data payload
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external payable;

    /**
     * @notice transfer token between given addresses, without checking for ERC721Receiver implementation if applicable
     * @param from sender of token
     * @param to receiver of token
     * @param tokenId token id
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @notice grant approval to given account to spend token
     * @param operator address to be approved
     * @param tokenId token to approve
     */
    function approve(address operator, uint256 tokenId) external payable;

    /**
     * @notice get approval status for given token
     * @param tokenId token to query
     * @return operator address approved to spend token
     */
    function getApproved(uint256 tokenId)
        external
        view
        returns (address operator);

    /**
     * @notice grant approval to or revoke approval from given account to spend all tokens held by sender
     * @param operator address to be approved
     * @param status approval status
     */
    function setApprovalForAll(address operator, bool status) external;

    /**
     * @notice query approval status of given operator with respect to given address
     * @param account address to query for approval granted
     * @param operator address to query for approval received
     * @return status whether operator is approved to spend tokens held by account
     */
    function isApprovedForAll(address account, address operator)
        external
        view
        returns (bool status);
}

File 29 of 34 : IERC721Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Partial ERC721 interface needed by internal functions
 */
interface IERC721Internal {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 indexed tokenId
    );

    event Approval(
        address indexed owner,
        address indexed operator,
        uint256 indexed tokenId
    );

    event ApprovalForAll(
        address indexed owner,
        address indexed operator,
        bool approved
    );
}

File 30 of 34 : ERC721MetadataStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC721MetadataStorage {
    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC721Metadata');

    struct Layout {
        string name;
        string symbol;
        string baseURI;
        mapping(uint256 => string) tokenURIs;
    }

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

File 31 of 34 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC721Internal } from '../IERC721Internal.sol';

/**
 * @title ERC721Metadata interface
 */
interface IERC721Metadata is IERC721Internal {
    /**
     * @notice get token name
     * @return token name
     */
    function name() external view returns (string memory);

    /**
     * @notice get token symbol
     * @return token symbol
     */
    function symbol() external view returns (string memory);

    /**
     * @notice get generated URI for given token
     * @return token URI
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

File 32 of 34 : AddressUtils.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { UintUtils } from './UintUtils.sol';

library AddressUtils {
    using UintUtils for uint256;

    function toString(address account) internal pure returns (string memory) {
        return uint256(uint160(account)).toHexString(20);
    }

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function sendValue(address payable account, uint256 amount) internal {
        (bool success, ) = account.call{ value: amount }('');
        require(success, 'AddressUtils: failed to send value');
    }

    function functionCall(address target, bytes memory data)
        internal
        returns (bytes memory)
    {
        return
            functionCall(target, data, 'AddressUtils: failed low-level call');
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory error
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, error);
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                'AddressUtils: failed low-level call with value'
            );
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) internal returns (bytes memory) {
        require(
            address(this).balance >= value,
            'AddressUtils: insufficient balance for call'
        );
        return _functionCallWithValue(target, data, value, error);
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) private returns (bytes memory) {
        require(
            isContract(target),
            'AddressUtils: function call to non-contract'
        );

        (bool success, bytes memory returnData) = target.call{ value: value }(
            data
        );

        if (success) {
            return returnData;
        } else if (returnData.length > 0) {
            assembly {
                let returnData_size := mload(returnData)
                revert(add(32, returnData), returnData_size)
            }
        } else {
            revert(error);
        }
    }
}

File 33 of 34 : UintUtils.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title utility functions for uint256 operations
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
library UintUtils {
    bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';

    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return '0';
        }

        uint256 temp = value;
        uint256 digits;

        while (temp != 0) {
            digits++;
            temp /= 10;
        }

        bytes memory buffer = new bytes(digits);

        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }

        return string(buffer);
    }

    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return '0x00';
        }

        uint256 length = 0;

        for (uint256 temp = value; temp != 0; temp >>= 8) {
            unchecked {
                length++;
            }
        }

        return toHexString(value, length);
    }

    function toHexString(uint256 value, uint256 length)
        internal
        pure
        returns (string memory)
    {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = '0';
        buffer[1] = 'x';

        unchecked {
            for (uint256 i = 2 * length + 1; i > 1; --i) {
                buffer[i] = HEX_SYMBOLS[value & 0xf];
                value >>= 4;
            }
        }

        require(value == 0, 'UintUtils: hex length insufficient');

        return string(buffer);
    }
}

File 34 of 34 : STDDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { IERC721 } from '@solidstate/contracts/token/ERC721/IERC721.sol';
import { IERC721Metadata } from '@solidstate/contracts/token/ERC721/metadata/IERC721Metadata.sol';
import { IERC721Enumerable } from '@solidstate/contracts/token/ERC721/enumerable/IERC721Enumerable.sol';
import { ERC721MetadataStorage } from '@solidstate/contracts/token/ERC721/metadata/ERC721MetadataStorage.sol';
import { ERC165Storage } from '@solidstate/contracts/introspection/ERC165Storage.sol';
import { SolidStateDiamond } from '@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol';

contract STDDiamond is SolidStateDiamond {
	constructor()
		SolidStateDiamond() payable
	{
		// Update metadata
		ERC721MetadataStorage.layout().name = 'Spin the Dart';
		ERC721MetadataStorage.layout().symbol = 'STD';

		ERC165Storage.Layout storage erc165 = ERC165Storage.layout();

		// Add ERC165 data
		erc165.supportedInterfaces[type(IERC721).interfaceId] = true;
		erc165.supportedInterfaces[type(IERC721Metadata).interfaceId] = true;
		erc165.supportedInterfaces[type(IERC721Enumerable).interfaceId] = true;
	}
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 99999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritable.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritable.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritable.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritable.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260006200001b6200056a60201b620011791760201c565b60408051600c8082526101a08201909252919250600091906020820161018080368337019050509050631f931c1c60e01b816000815181106200006257620000626200115d565b6001600160e01b03199092166020928302919091018201526200009c9083906307e4c70760e21b906001906200119d6200058e821b17901c565b637a0ed62760e01b81600181518110620000ba57620000ba6200115d565b6001600160e01b03199092166020928302919091019091015280516356fe50af60e11b9082906002908110620000f457620000f46200115d565b6001600160e01b03199092166020928302919091019091015280516314bbdacb60e21b90829060039081106200012e576200012e6200115d565b6001600160e01b03199092166020928302919091019091015280516366ffd66360e11b90829060049081106200016857620001686200115d565b6001600160e01b0319909216602092830291909101820152620001a29083906348e2b09360e01b906001906200119d6200058e821b17901c565b6301ffc9a760e01b81600581518110620001c057620001c06200115d565b6001600160e01b0319909216602092830291909101820152620001fa9083906301ffc9a760e01b906001906200119d6200058e821b17901c565b638da5cb5b60e01b816006815181106200021857620002186200115d565b6001600160e01b031990921660209283029190910190910152805163455a8a8560e11b90829060079081106200025257620002526200115d565b6001600160e01b031990921660209283029190910190910152805163f2fde38b60e01b90829060089081106200028c576200028c6200115d565b6001600160e01b03199092166020928302919091019091015280516379ba509760e01b9082906009908110620002c657620002c66200115d565b6001600160e01b0319909216602092830291909101820152620003009083906307f5828d60e41b906001906200119d6200058e821b17901c565b632c40805960e01b81600a815181106200031e576200031e6200115d565b6001600160e01b0319909216602092830291909101909101528051639142376560e01b908290600b9081106200035857620003586200115d565b6001600160e01b03199290921660209283029190910190910152604080516001808252818301909252600091816020015b604080516060808201835260008083526020830152918101919091528152602001906001900390816200038957905050604080516060810190915230815290915060208101600081526020018381525081600081518110620003ef57620003ef6200115d565b60200260200101819052506200043c81600060405180602001604052806000815250620004266200061c60201b6200128d1760201c565b6200064060201b620012b117909392919060201c565b6200046a33620004566200086c60201b620014de1760201c565b6200089060201b620015021790919060201c565b5050506040518060400160405280600d81526020016c14dc1a5b881d1a194811185c9d609a1b815250620004a8620008ad60201b620015441760201c565b90620004b5908262001217565b506040518060400160405280600381526020016214d51160ea1b815250620004e7620008ad60201b620015441760201c565b60010190620004f7908262001217565b5060006200050f6200056a60201b620011791760201c565b6380ac58cd60e01b600090815260209190915260408082208054600160ff199182168117909255635b5e139f60e01b8452828420805482168317905563780e9d6360e01b84529190922080549091169091179055506200145c565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003620005ee5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e746572666163652069640000000060448201526064015b60405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600184015461ffff811690819060009060071615620006715750600381901c60009081526002870160205260409020545b60005b8651811015620007da5760008782815181106200069557620006956200115d565b602002602001015190506000816020015190506000826040015151116200070b5760405162461bcd60e51b815260206004820152602360248201527f4469616d6f6e64426173653a206e6f2073656c6563746f7273207370656369666044820152621a595960ea1b6064820152608401620005e5565b600081600281111562000722576200072262001173565b036200075157620007468585848d620008d160201b6200156817909392919060201c565b9095509350620007cf565b600181600281111562000768576200076862001173565b036200078e5762000788828b62000aa360201b620017e51790919060201c565b620007cf565b6002816002811115620007a557620007a562001173565b03620007cf57620007c98585848d62000ce460201b62001b4217909392919060201c565b90955093505b505060010162000674565b50828214620007f75760018701805461ffff191661ffff84161790555b60078216156200081a57600382901c600090815260028801602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738686866040516200084f9392919062001337565b60405180910390a162000863858562000fb2565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b805160009081906001600160a01b03163014806200090d57506200090d83600001516001600160a01b03166200114160201b6200052c1760201c565b620009675760405162461bcd60e51b815260206004820152602360248201527f4469616d6f6e64426173653a204144442074617267657420686173206e6f20636044820152626f646560e81b6064820152608401620005e5565b60005b83604001515181101562000a96576000846040015182815181106200099357620009936200115d565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1562000a1c5760405162461bcd60e51b815260206004820152602360248201527f4469616d6f6e64426173653a2073656c6563746f7220616c726561647920616460448201526219195960ea1b6064820152608401620005e5565b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c1999909916179781900362000a8657600389901c600090815260028b0160205260408120989098555b505050600195860195016200096a565b5093959294509192505050565b62000ac681600001516001600160a01b03166200114160201b6200052c1760201c565b62000b245760405162461bcd60e51b815260206004820152602760248201527f4469616d6f6e64426173653a205245504c4143452074617267657420686173206044820152666e6f20636f646560c81b6064820152608401620005e5565b60005b81604001515181101562000cdf5760008260400151828151811062000b505762000b506200115d565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c8062000bcd5760405162461bcd60e51b815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e64006044820152606401620005e5565b306001600160a01b0382160362000c215760405162461bcd60e51b8152602060048201526022602482015260008051602062003f978339815191526044820152616c6560f01b6064820152608401620005e5565b84600001516001600160a01b0316816001600160a01b03160362000c995760405162461bcd60e51b815260206004820152602860248201527f4469616d6f6e64426173653a205245504c41434520746172676574206973206960448201526719195b9d1a58d85b60c21b6064820152608401620005e5565b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166001600160601b039190911617905560010162000b27565b505050565b805160009081906001600160a01b03161562000d5b5760405162461bcd60e51b815260206004820152602f60248201527f4469616d6f6e64426173653a2052454d4f564520746172676574206d7573742060448201526e6265207a65726f206164647265737360881b6064820152608401620005e5565b600385901c6007861660005b85604001515181101562000f9e5760008660400151828151811062000d905762000d906200115d565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c62000e0c5760405162461bcd60e51b815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e64006044820152606401620005e5565b30606082901c0362000e5b5760405162461bcd60e51b8152602060048201526022602482015260008051602062003f978339815191526044820152616c6560f01b6064820152608401620005e5565b600089900362000e8957600019909401600081815260028c0160205260409020549850936007935062000e91565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161462000ee4576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166001600160601b0386161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821462000f4957600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905562000f6d565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000362000f8c57600088815260028f01602052604081208190559b505b50506001909301925062000d67915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514620010265760405162461bcd60e51b815260206004820152602e60248201527f4469616d6f6e64426173653a20696e76616c696420696e697469616c697a617460448201526d696f6e20706172616d657465727360901b6064820152608401620005e5565b6001600160a01b038216156200113d576001600160a01b0382163014620010cb5762001066826001600160a01b03166200114160201b6200052c1760201c565b620010cb5760405162461bcd60e51b815260206004820152602e60248201527f4469616d6f6e64426173653a20696e697469616c697a6174696f6e207461726760448201526d657420686173206e6f20636f646560901b6064820152608401620005e5565b6000826001600160a01b031682604051620010e791906200143e565b600060405180830381855af49150503d806000811462001124576040519150601f19603f3d011682016040523d82523d6000602084013e62001129565b606091505b505090508062000cdf573d6000803e3d6000fd5b5050565b3b151590565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b600181811c908216806200119e57607f821691505b602082108103620011bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000cdf57600081815260208120601f850160051c81016020861015620011ee5750805b601f850160051c820191505b818110156200120f57828155600101620011fa565b505050505050565b81516001600160401b0381111562001233576200123362001147565b6200124b8162001244845462001189565b84620011c5565b602080601f8311600181146200128357600084156200126a5750858301515b600019600386901b1c1916600185901b1785556200120f565b600085815260208120601f198616915b82811015620012b45788860151825594840194600190910190840162001293565b5085821015620012d35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60005b8381101562001300578181015183820152602001620012e6565b50506000910152565b6000815180845262001323816020860160208601620012e3565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b848110156200140c57898403607f19018652815180516001600160a01b03168552838101518986019060038110620013a857634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b80831015620013f65783516001600160e01b0319168252928601926001929092019190860190620013ca565b5097850197955050509082019060010162001360565b50506001600160a01b038a1690880152868103604088015262001430818962001309565b9a9950505050505050505050565b6000825162001452818460208701620012e3565b9190910192915050565b612b2b806200146c6000396000f3fe6080604052600436106100cb5760003560e01c80638ab5150a11610074578063adfca15e1161004e578063adfca15e14610361578063cdffacc61461038e578063f2fde38b146103ff576100d2565b80638ab5150a146103175780638da5cb5b1461032c5780639142376514610341576100d2565b806352ef6b2c116100a557806352ef6b2c146102be57806379ba5097146102e05780637a0ed627146102f5576100d2565b806301ffc9a7146101ad5780631f931c1c146102335780632c40805914610253576100d2565b366100d257005b60006100dc61041f565b905073ffffffffffffffffffffffffffffffffffffffff81163b610187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f50726f78793a20696d706c656d656e746174696f6e206d75737420626520636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156101a6573d6000f35b3d6000fd5b005b3480156101b957600080fd5b5061021e6101c8366004612360565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b506101ab61024e3660046123e8565b610532565b34801561025f57600080fd5b507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc965473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b3480156102ca57600080fd5b506102d361062b565b60405161022a919061249a565b3480156102ec57600080fd5b506101ab610840565b34801561030157600080fd5b5061030a61090c565b60405161022a9190612551565b34801561032357600080fd5b50610299610dfa565b34801561033857600080fd5b50610299610e09565b34801561034d57600080fd5b506101ab61035c3660046125f9565b610e13565b34801561036d57600080fd5b5061038161037c3660046125f9565b610f15565b60405161022a9190612614565b34801561039a57600080fd5b506102996103a9366004612360565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c90565b34801561040b57600080fd5b506101ab61041a3660046125f9565b6110d1565b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9360208190526040822054819060601c806105255750600382015473ffffffffffffffffffffffffffffffffffffffff1680610525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4469616d6f6e64426173653a206e6f20666163657420666f756e6420666f722060448201527f66756e6374696f6e207369676e61747572650000000000000000000000000000606482015260840161017e565b9392505050565b3b151590565b61053a611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b6106246105db8587612739565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061061c925061128d915050565b9291906112b1565b5050505050565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff81111561068e5761068e61266e565b6040519080825280602002602001820160405280156106b7578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610838576000818152600285016020526040812054905b600881101561082357836106f68161289c565b600188015490955061ffff168511905061082357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b888110156107b9578a8181518110610764576107646128d4565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107a757600191506107b9565b806107b18161289c565b91505061074a565b5080156107c857505050610811565b818a89815181106107db576107db6128d4565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528761080a8161289c565b9850505050505b8061081b8161289c565b9150506106e3565b505080806108309061289c565b9150506106c0565b505082525090565b610848611fd2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f536166654f776e61626c653a2073656e646572206d757374206265206e6f6d6960448201527f6e6565206f776e65720000000000000000000000000000000000000000000000606482015260840161017e565b61090a611ffa565b565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff81111561096f5761096f61266e565b6040519080825280602002602001820160405280156109b557816020015b60408051808201909152600081526060602082015281526020019060019003908161098d5790505b50600182015490925060009061ffff1667ffffffffffffffff8111156109dd576109dd61266e565b604051908082528060200260200182016040528015610a06578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610d88576000818152600286016020526040812054905b6008811015610d735783610a458161289c565b600189015490955061ffff1685119050610d7357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015610bfa578273ffffffffffffffffffffffffffffffffffffffff168c8281518110610aca57610aca6128d4565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610be857838c8281518110610b0457610b046128d4565b6020026020010151602001518b8381518110610b2257610b226128d4565b602002602001015160ff1681518110610b3d57610b3d6128d4565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610b9d57610b9d6128d4565b602002602001015160ff1610610bb257600080fd5b898181518110610bc457610bc46128d4565b602002602001018051809190610bd990612903565b60ff1690525060019150610bfa565b80610bf28161289c565b915050610a99565b508015610c0957505050610d61565b818b8981518110610c1c57610c1c6128d4565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260018a015461ffff1667ffffffffffffffff811115610c6257610c6261266e565b604051908082528060200260200182016040528015610c8b578160200160208202803683370190505b508b8981518110610c9e57610c9e6128d4565b602002602001015160200181905250828b8981518110610cc057610cc06128d4565b602002602001015160200151600081518110610cde57610cde6128d4565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610d3e57610d3e6128d4565b60ff9092166020928302919091019091015287610d5a8161289c565b9850505050505b80610d6b8161289c565b915050610a32565b50508080610d809061289c565b915050610a0f565b5060005b82811015610def576000848281518110610da857610da86128d4565b602002602001015160ff1690506000878381518110610dc957610dc96128d4565b602002602001015160200151905081815250508080610de79061289c565b915050610d8c565b508185525050505090565b6000610e04611fd2565b905090565b6000610e04611f92565b610e1b611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff811115610f7857610f7861266e565b604051908082528060200260200182016040528015610fa1578160200160208202803683370190505b50915060008060005b600184015461ffff168210156110c7576000818152600285016020526040812054905b60088110156110b25783610fe08161289c565b600188015490955061ffff16851190506110b257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a160361109f5780888781518110611060576110606128d4565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101528561109b8161289c565b9650505b50806110aa8161289c565b915050610fcd565b505080806110bf9061289c565b915050610faa565b5050825250919050565b6110d9611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461116d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b611176816120f1565b50565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b7fffffffff000000000000000000000000000000000000000000000000000000008083169003611229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640161017e565b7fffffffff00000000000000000000000000000000000000000000000000000000919091166000908152602092909252604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600184015461ffff8116908190600090600716156112e15750600381901c60009081526002870160205260409020545b60005b8651811015611435576000878281518110611301576113016128d4565b602002602001015190506000816020015190506000826040015151116113a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a206e6f2073656c6563746f72732073706563696660448201527f6965640000000000000000000000000000000000000000000000000000000000606482015260840161017e565b60008160028111156113bd576113bd612922565b036113d8576113ce8a868685611568565b909550935061142b565b60018160028111156113ec576113ec612922565b03611400576113fb8a836117e5565b61142b565b600281600281111561141457611414612922565b0361142b576114258a868685611b42565b90955093505b50506001016112e4565b5082821461146e576001870180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561149057600382901c600090815260028801602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738686866040516114c3939291906129bf565b60405180910390a16114d585856120fa565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91909116179055565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b8051600090819073ffffffffffffffffffffffffffffffffffffffff163014806115a95750825173ffffffffffffffffffffffffffffffffffffffff163b15155b611635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a204144442074617267657420686173206e6f206360448201527f6f64650000000000000000000000000000000000000000000000000000000000606482015260840161017e565b60005b8360400151518110156117d85760008460400151828151811061165d5761165d6128d4565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c15611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a2073656c6563746f7220616c726561647920616460448201527f6465640000000000000000000000000000000000000000000000000000000000606482015260840161017e565b85517fffffffff00000000000000000000000000000000000000000000000000000000838116600081815260208d90526040902060609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168b1790925560058a901b60e090811692831c91831c199990991617978190036117c957600389901c600090815260028b0160205260408120989098555b50505060019586019501611638565b5093959294509192505050565b805173ffffffffffffffffffffffffffffffffffffffff163b61188a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4469616d6f6e64426173653a205245504c41434520746172676574206861732060448201527f6e6f20636f646500000000000000000000000000000000000000000000000000606482015260840161017e565b60005b816040015151811015611b3d576000826040015182815181106118b2576118b26128d4565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291869052604090912054909150606081901c8061195f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e6400604482015260640161017e565b3073ffffffffffffffffffffffffffffffffffffffff821603611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4469616d6f6e64426173653a2073656c6563746f7220697320696d6d7574616260448201527f6c65000000000000000000000000000000000000000000000000000000000000606482015260840161017e565b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4469616d6f6e64426173653a205245504c41434520746172676574206973206960448201527f64656e746963616c000000000000000000000000000000000000000000000000606482015260840161017e565b5083517fffffffff0000000000000000000000000000000000000000000000000000000092909216600090815260208690526040902060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9190911617905560010161188d565b505050565b8051600090819073ffffffffffffffffffffffffffffffffffffffff1615611bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4469616d6f6e64426173653a2052454d4f564520746172676574206d7573742060448201527f6265207a65726f20616464726573730000000000000000000000000000000000606482015260840161017e565b600385901c6007861660005b856040015151811015611f7e57600086604001518281518110611c1d57611c1d6128d4565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918c9052604090912054909150606081901c611cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e6400604482015260640161017e565b30606082901c03611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4469616d6f6e64426173653a2073656c6563746f7220697320696d6d7574616260448201527f6c65000000000000000000000000000000000000000000000000000000000000606482015260840161017e565b6000899003611da6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909401600081815260028c01602052604090205498509360079350611dcc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301925b600584901b89901b6000807fffffffff0000000000000000000000000000000000000000000000000000000080841690861614611e6b577fffffffff000000000000000000000000000000000000000000000000000000008316600090815260208f90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff86161790555b50507fffffffff000000000000000000000000000000000000000000000000000000008316600090815260208d90526040812055611fff600383901c1660e0600584901b16878214611efe57600082815260028f016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611f4f565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b86600003611f6d57600088815260028f01602052604081208190559b505b505060019093019250611bf8915050565b5060039190911b1796939550929350505050565b60007f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804605b5473ffffffffffffffffffffffffffffffffffffffff16919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890611fb6565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804608054604051339173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561117660007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b9081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91909116179055565b611176816122fd565b80511573ffffffffffffffffffffffffffffffffffffffff831615146121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4469616d6f6e64426173653a20696e76616c696420696e697469616c697a617460448201527f696f6e20706172616d6574657273000000000000000000000000000000000000606482015260840161017e565b73ffffffffffffffffffffffffffffffffffffffff8216156122f95773ffffffffffffffffffffffffffffffffffffffff8216301461227f5773ffffffffffffffffffffffffffffffffffffffff82163b61227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4469616d6f6e64426173653a20696e697469616c697a6174696f6e207461726760448201527f657420686173206e6f20636f6465000000000000000000000000000000000000606482015260840161017e565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516122a69190612ad9565b600060405180830381855af49150503d80600081146122e1576040519150601f19603f3d011682016040523d82523d6000602084013e6122e6565b606091505b5050905080611b3d573d6000803e3d6000fd5b5050565b61117681611176817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906120ae565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461235b57600080fd5b919050565b60006020828403121561237257600080fd5b6105258261232b565b803573ffffffffffffffffffffffffffffffffffffffff8116811461235b57600080fd5b60008083601f8401126123b157600080fd5b50813567ffffffffffffffff8111156123c957600080fd5b6020830191508360208285010111156123e157600080fd5b9250929050565b60008060008060006060868803121561240057600080fd5b853567ffffffffffffffff8082111561241857600080fd5b818801915088601f83011261242c57600080fd5b81358181111561243b57600080fd5b8960208260051b850101111561245057600080fd5b602083019750809650506124666020890161237b565b9450604088013591508082111561247c57600080fd5b506124898882890161239f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156124e857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016124b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156125465781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101612508565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156125eb578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526125d8878501826124f4565b9588019593505090860190600101612578565b509098975050505050505050565b60006020828403121561260b57600080fd5b6105258261237b565b6020808252825182820181905260009190848201906040850190845b818110156124e85783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101612630565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156126c0576126c061266e565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561270d5761270d61266e565b604052919050565b600067ffffffffffffffff82111561272f5761272f61266e565b5060051b60200190565b600061274c61274784612715565b6126c6565b83815260208082019190600586811b86013681111561276a57600080fd5b865b8181101561286057803567ffffffffffffffff8082111561278d5760008081fd5b818a019150606082360312156127a35760008081fd5b6127ab61269d565b6127b48361237b565b815286830135600381106127c85760008081fd5b81880152604083810135838111156127e05760008081fd5b939093019236601f8501126127f757600092508283fd5b8335925061280761274784612715565b83815292871b840188019288810190368511156128245760008081fd5b948901945b848610156128495761283a8661232b565b82529489019490890190612829565b91830191909152508852505094830194830161276c565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036128cd576128cd61286d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff81036129195761291961286d565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b8381101561296c578181015183820152602001612954565b50506000910152565b6000815180845261298d816020860160208601612951565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015612a9c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8803018652825173ffffffffffffffffffffffffffffffffffffffff81511688528481015160038110612a6d577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b88860152604090810151908801899052612a89898901826124f4565b97505094830194918301916001016129e9565b50505073ffffffffffffffffffffffffffffffffffffffff89169087015250508381036040850152612ace8186612975565b979650505050505050565b60008251612aeb818460208701612951565b919091019291505056fea26469706673582212201ea4979c112f2595668803808f7fd45309944af7e78c8843e28222516896194564736f6c634300081100334469616d6f6e64426173653a2073656c6563746f7220697320696d6d75746162

Deployed Bytecode

0x6080604052600436106100cb5760003560e01c80638ab5150a11610074578063adfca15e1161004e578063adfca15e14610361578063cdffacc61461038e578063f2fde38b146103ff576100d2565b80638ab5150a146103175780638da5cb5b1461032c5780639142376514610341576100d2565b806352ef6b2c116100a557806352ef6b2c146102be57806379ba5097146102e05780637a0ed627146102f5576100d2565b806301ffc9a7146101ad5780631f931c1c146102335780632c40805914610253576100d2565b366100d257005b60006100dc61041f565b905073ffffffffffffffffffffffffffffffffffffffff81163b610187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f50726f78793a20696d706c656d656e746174696f6e206d75737420626520636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b3660008037600080366000845af43d6000803e8080156101a6573d6000f35b3d6000fd5b005b3480156101b957600080fd5b5061021e6101c8366004612360565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561023f57600080fd5b506101ab61024e3660046123e8565b610532565b34801561025f57600080fd5b507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc965473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b3480156102ca57600080fd5b506102d361062b565b60405161022a919061249a565b3480156102ec57600080fd5b506101ab610840565b34801561030157600080fd5b5061030a61090c565b60405161022a9190612551565b34801561032357600080fd5b50610299610dfa565b34801561033857600080fd5b50610299610e09565b34801561034d57600080fd5b506101ab61035c3660046125f9565b610e13565b34801561036d57600080fd5b5061038161037c3660046125f9565b610f15565b60405161022a9190612614565b34801561039a57600080fd5b506102996103a9366004612360565b7fffffffff000000000000000000000000000000000000000000000000000000001660009081527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c90565b34801561040b57600080fd5b506101ab61041a3660046125f9565b6110d1565b600080357fffffffff000000000000000000000000000000000000000000000000000000001681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9360208190526040822054819060601c806105255750600382015473ffffffffffffffffffffffffffffffffffffffff1680610525576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4469616d6f6e64426173653a206e6f20666163657420666f756e6420666f722060448201527f66756e6374696f6e207369676e61747572650000000000000000000000000000606482015260840161017e565b9392505050565b3b151590565b61053a611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b6106246105db8587612739565b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061061c925061128d915050565b9291906112b1565b5050505050565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff81111561068e5761068e61266e565b6040519080825280602002602001820160405280156106b7578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610838576000818152600285016020526040812054905b600881101561082357836106f68161289c565b600188015490955061ffff168511905061082357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604081205460601c90805b888110156107b9578a8181518110610764576107646128d4565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036107a757600191506107b9565b806107b18161289c565b91505061074a565b5080156107c857505050610811565b818a89815181106107db576107db6128d4565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101528761080a8161289c565b9850505050505b8061081b8161289c565b9150506106e3565b505080806108309061289c565b9150506106c0565b505082525090565b610848611fd2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610902576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f536166654f776e61626c653a2073656e646572206d757374206265206e6f6d6960448201527f6e6565206f776e65720000000000000000000000000000000000000000000000606482015260840161017e565b61090a611ffa565b565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff81111561096f5761096f61266e565b6040519080825280602002602001820160405280156109b557816020015b60408051808201909152600081526060602082015281526020019060019003908161098d5790505b50600182015490925060009061ffff1667ffffffffffffffff8111156109dd576109dd61266e565b604051908082528060200260200182016040528015610a06578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610d88576000818152600286016020526040812054905b6008811015610d735783610a458161289c565b600189015490955061ffff1685119050610d7357600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020899052604081205460601c90805b88811015610bfa578273ffffffffffffffffffffffffffffffffffffffff168c8281518110610aca57610aca6128d4565b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610be857838c8281518110610b0457610b046128d4565b6020026020010151602001518b8381518110610b2257610b226128d4565b602002602001015160ff1681518110610b3d57610b3d6128d4565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610b9d57610b9d6128d4565b602002602001015160ff1610610bb257600080fd5b898181518110610bc457610bc46128d4565b602002602001018051809190610bd990612903565b60ff1690525060019150610bfa565b80610bf28161289c565b915050610a99565b508015610c0957505050610d61565b818b8981518110610c1c57610c1c6128d4565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905260018a015461ffff1667ffffffffffffffff811115610c6257610c6261266e565b604051908082528060200260200182016040528015610c8b578160200160208202803683370190505b508b8981518110610c9e57610c9e6128d4565b602002602001015160200181905250828b8981518110610cc057610cc06128d4565b602002602001015160200151600081518110610cde57610cde6128d4565b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610d3e57610d3e6128d4565b60ff9092166020928302919091019091015287610d5a8161289c565b9850505050505b80610d6b8161289c565b915050610a32565b50508080610d809061289c565b915050610a0f565b5060005b82811015610def576000848281518110610da857610da86128d4565b602002602001015160ff1690506000878381518110610dc957610dc96128d4565b602002602001015160200151905081815250508080610de79061289c565b915050610d8c565b508185525050505090565b6000610e04611fd2565b905090565b6000610e04611f92565b610e1b611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94546060907f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff1667ffffffffffffffff811115610f7857610f7861266e565b604051908082528060200260200182016040528015610fa1578160200160208202803683370190505b50915060008060005b600184015461ffff168210156110c7576000818152600285016020526040812054905b60088110156110b25783610fe08161289c565b600188015490955061ffff16851190506110b257600581901b82901b7fffffffff00000000000000000000000000000000000000000000000000000000811660009081526020889052604090205460601c73ffffffffffffffffffffffffffffffffffffffff8a160361109f5780888781518110611060576110606128d4565b7fffffffff00000000000000000000000000000000000000000000000000000000909216602092830291909101909101528561109b8161289c565b9650505b50806110aa8161289c565b915050610fcd565b505080806110bf9061289c565b915050610faa565b5050825250919050565b6110d9611f92565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461116d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000604482015260640161017e565b611176816120f1565b50565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b7fffffffff000000000000000000000000000000000000000000000000000000008083169003611229576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640161017e565b7fffffffff00000000000000000000000000000000000000000000000000000000919091166000908152602092909252604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600184015461ffff8116908190600090600716156112e15750600381901c60009081526002870160205260409020545b60005b8651811015611435576000878281518110611301576113016128d4565b602002602001015190506000816020015190506000826040015151116113a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a206e6f2073656c6563746f72732073706563696660448201527f6965640000000000000000000000000000000000000000000000000000000000606482015260840161017e565b60008160028111156113bd576113bd612922565b036113d8576113ce8a868685611568565b909550935061142b565b60018160028111156113ec576113ec612922565b03611400576113fb8a836117e5565b61142b565b600281600281111561141457611414612922565b0361142b576114258a868685611b42565b90955093505b50506001016112e4565b5082821461146e576001870180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001661ffff84161790555b600782161561149057600382901c600090815260028801602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738686866040516114c3939291906129bf565b60405180910390a16114d585856120fa565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91909116179055565b7f99574a7094154bb123ae6ae102096f0bf9679b85a5cd1e727aaa0ae5f132e6b190565b8051600090819073ffffffffffffffffffffffffffffffffffffffff163014806115a95750825173ffffffffffffffffffffffffffffffffffffffff163b15155b611635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a204144442074617267657420686173206e6f206360448201527f6f64650000000000000000000000000000000000000000000000000000000000606482015260840161017e565b60005b8360400151518110156117d85760008460400151828151811061165d5761165d6128d4565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918a9052604090912054909150606081901c15611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f4469616d6f6e64426173653a2073656c6563746f7220616c726561647920616460448201527f6465640000000000000000000000000000000000000000000000000000000000606482015260840161017e565b85517fffffffff00000000000000000000000000000000000000000000000000000000838116600081815260208d90526040902060609390931b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168b1790925560058a901b60e090811692831c91831c199990991617978190036117c957600389901c600090815260028b0160205260408120989098555b50505060019586019501611638565b5093959294509192505050565b805173ffffffffffffffffffffffffffffffffffffffff163b61188a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f4469616d6f6e64426173653a205245504c41434520746172676574206861732060448201527f6e6f20636f646500000000000000000000000000000000000000000000000000606482015260840161017e565b60005b816040015151811015611b3d576000826040015182815181106118b2576118b26128d4565b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815291869052604090912054909150606081901c8061195f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e6400604482015260640161017e565b3073ffffffffffffffffffffffffffffffffffffffff821603611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4469616d6f6e64426173653a2073656c6563746f7220697320696d6d7574616260448201527f6c65000000000000000000000000000000000000000000000000000000000000606482015260840161017e565b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f4469616d6f6e64426173653a205245504c41434520746172676574206973206960448201527f64656e746963616c000000000000000000000000000000000000000000000000606482015260840161017e565b5083517fffffffff0000000000000000000000000000000000000000000000000000000092909216600090815260208690526040902060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff9190911617905560010161188d565b505050565b8051600090819073ffffffffffffffffffffffffffffffffffffffff1615611bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4469616d6f6e64426173653a2052454d4f564520746172676574206d7573742060448201527f6265207a65726f20616464726573730000000000000000000000000000000000606482015260840161017e565b600385901c6007861660005b856040015151811015611f7e57600086604001518281518110611c1d57611c1d6128d4565b6020908102919091018101517fffffffff0000000000000000000000000000000000000000000000000000000081166000908152918c9052604090912054909150606081901c611cc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4469616d6f6e64426173653a2073656c6563746f72206e6f7420666f756e6400604482015260640161017e565b30606082901c03611d5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f4469616d6f6e64426173653a2073656c6563746f7220697320696d6d7574616260448201527f6c65000000000000000000000000000000000000000000000000000000000000606482015260840161017e565b6000899003611da6577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909401600081815260028c01602052604090205498509360079350611dcc565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301925b600584901b89901b6000807fffffffff0000000000000000000000000000000000000000000000000000000080841690861614611e6b577fffffffff000000000000000000000000000000000000000000000000000000008316600090815260208f90526040902080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff86161790555b50507fffffffff000000000000000000000000000000000000000000000000000000008316600090815260208d90526040812055611fff600383901c1660e0600584901b16878214611efe57600082815260028f016020526040902080547fffffffff0000000000000000000000000000000000000000000000000000000080841c19909116908516831c179055611f4f565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b86600003611f6d57600088815260028f01602052604081208190559b505b505060019093019250611bf8915050565b5060039190911b1796939550929350505050565b60007f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804605b5473ffffffffffffffffffffffffffffffffffffffff16919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890611fb6565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804608054604051339173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a380547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561117660007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b9081547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff91909116179055565b611176816122fd565b80511573ffffffffffffffffffffffffffffffffffffffff831615146121a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4469616d6f6e64426173653a20696e76616c696420696e697469616c697a617460448201527f696f6e20706172616d6574657273000000000000000000000000000000000000606482015260840161017e565b73ffffffffffffffffffffffffffffffffffffffff8216156122f95773ffffffffffffffffffffffffffffffffffffffff8216301461227f5773ffffffffffffffffffffffffffffffffffffffff82163b61227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4469616d6f6e64426173653a20696e697469616c697a6174696f6e207461726760448201527f657420686173206e6f20636f6465000000000000000000000000000000000000606482015260840161017e565b60008273ffffffffffffffffffffffffffffffffffffffff16826040516122a69190612ad9565b600060405180830381855af49150503d80600081146122e1576040519150601f19603f3d011682016040523d82523d6000602084013e6122e6565b606091505b5050905080611b3d573d6000803e3d6000fd5b5050565b61117681611176817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906120ae565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461235b57600080fd5b919050565b60006020828403121561237257600080fd5b6105258261232b565b803573ffffffffffffffffffffffffffffffffffffffff8116811461235b57600080fd5b60008083601f8401126123b157600080fd5b50813567ffffffffffffffff8111156123c957600080fd5b6020830191508360208285010111156123e157600080fd5b9250929050565b60008060008060006060868803121561240057600080fd5b853567ffffffffffffffff8082111561241857600080fd5b818801915088601f83011261242c57600080fd5b81358181111561243b57600080fd5b8960208260051b850101111561245057600080fd5b602083019750809650506124666020890161237b565b9450604088013591508082111561247c57600080fd5b506124898882890161239f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156124e857835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016124b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156125465781517fffffffff000000000000000000000000000000000000000000000000000000001687529582019590820190600101612508565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156125eb578883037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00185528151805173ffffffffffffffffffffffffffffffffffffffff1684528701518784018790526125d8878501826124f4565b9588019593505090860190600101612578565b509098975050505050505050565b60006020828403121561260b57600080fd5b6105258261237b565b6020808252825182820181905260009190848201906040850190845b818110156124e85783517fffffffff000000000000000000000000000000000000000000000000000000001683529284019291840191600101612630565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156126c0576126c061266e565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561270d5761270d61266e565b604052919050565b600067ffffffffffffffff82111561272f5761272f61266e565b5060051b60200190565b600061274c61274784612715565b6126c6565b83815260208082019190600586811b86013681111561276a57600080fd5b865b8181101561286057803567ffffffffffffffff8082111561278d5760008081fd5b818a019150606082360312156127a35760008081fd5b6127ab61269d565b6127b48361237b565b815286830135600381106127c85760008081fd5b81880152604083810135838111156127e05760008081fd5b939093019236601f8501126127f757600092508283fd5b8335925061280761274784612715565b83815292871b840188019288810190368511156128245760008081fd5b948901945b848610156128495761283a8661232b565b82529489019490890190612829565b91830191909152508852505094830194830161276c565b5092979650505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036128cd576128cd61286d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff821660ff81036129195761291961286d565b60010192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60005b8381101561296c578181015183820152602001612954565b50506000910152565b6000815180845261298d816020860160208601612951565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015612a9c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8803018652825173ffffffffffffffffffffffffffffffffffffffff81511688528481015160038110612a6d577f4e487b710000000000000000000000000000000000000000000000000000000084526021600452602484fd5b88860152604090810151908801899052612a89898901826124f4565b97505094830194918301916001016129e9565b50505073ffffffffffffffffffffffffffffffffffffffff89169087015250508381036040850152612ace8186612975565b979650505050505050565b60008251612aeb818460208701612951565b919091019291505056fea26469706673582212201ea4979c112f2595668803808f7fd45309944af7e78c8843e28222516896194564736f6c63430008110033

Deployed Bytecode Sourcemap

630:519:33:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;582:22:16;607:20;:18;:20::i;:::-;582:45;-1:-1:-1;659:25:16;;;438:20:31;638:112:16;;;;;;;216:2:34;638:112:16;;;198:21:34;255:2;235:18;;;228:30;294:34;274:18;;;267:62;365:8;345:18;;;338:36;391:19;;638:112:16;;;;;;;;;803:14;800:1;797;784:34;1000:1;981;949:14;930:1;898:14;875:5;845:170;1049:16;1046:1;1043;1028:38;1087:6;1106:66;;;;1221:16;1218:1;1211:27;1106:66;1141:16;1138:1;1131:27;1080:172;;329:154:12;;;;;;;;;;-1:-1:-1;329:154:12;;;;;:::i;:::-;577:34:13;;397:4:12;577:34:13;;;215:48;577:34;;;;;;;;;329:154:12;;;;999:14:34;;992:22;974:41;;962:2;947:18;329:154:12;;;;;;;;515:217:24;;;;;;;;;;-1:-1:-1;515:217:24;;;;;:::i;:::-;;:::i;2938:129:18:-;;;;;;;;;;-1:-1:-1;3017:43:18;;;;2938:129;;;2902:42:34;2890:55;;;2872:74;;2860:2;2845:18;2938:129:18;2726:226:34;4295:1474:22;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;670:94:9:-;;;;;;;;;;;;;:::i;436:2549:22:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;515:101:9:-;;;;;;;;;;;;;:::i;472:87:6:-;;;;;;;;;;;;;:::i;3127:150:18:-;;;;;;;;;;-1:-1:-1;3127:150:18;;;;;:::i;:::-;;:::i;3043:1194:22:-;;;;;;;;;;-1:-1:-1;3043:1194:22;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5827:192::-;;;;;;;;;;-1:-1:-1;5827:192:22;;;;;:::i;:::-;5966:44;;5913:13;5966:44;;;992:53:20;5966:44:22;;;;;;5950:62;;;5827:192;608:113:6;;;;;;;;;;-1:-1:-1;608:113:6;;;;;:::i;:::-;;:::i;423:649:19:-;485:7;769;;;;760:17;;992:53:20;760:17:19;;;;;;;;992:53:20;;744:35:19;;;790:244;;-1:-1:-1;855:17:19;;;;;;;886:137;;;;;;;6402:2:34;886:137:19;;;6384:21:34;6441:2;6421:18;;;6414:30;6480:34;6460:18;;;6453:62;6551:20;6531:18;;;6524:48;6589:19;;886:137:19;6200:414:34;886:137:19;1051:14;423:649;-1:-1:-1;;;423:649:19:o;309:190:31:-;438:20;484:8;;;309:190::o;515:217:24:-;478:8:7;:6;:8::i;:::-;464:22;;:10;:22;;;456:64;;;;;;;6821:2:34;456:64:7;;;6803:21:34;6860:2;6840:18;;;6833:30;6899:31;6879:18;;;6872:59;6948:18;;456:64:7;6619:353:34;456:64:7;662:63:24::1;;701:9:::0;;662:63:::1;:::i;:::-;712:6;720:4;;662:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;662:27:24::1;::::0;-1:-1:-1;662:25:24::1;::::0;-1:-1:-1;;662:27:24:i:1;:::-;:38:::0;:63;;:38:::1;:63::i;:::-;515:217:::0;;;;;:::o;4295:1474:22:-;4512:15;;4368:26;;992:53:20;;4512:15:22;;4498:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4498:30:22;;4486:42;;4538:17;4565:21;4602:17;4597:1037;4637:15;;;;;;4621:31;;4597:1037;;;4681:12;4696:26;;;:15;;;:26;;;;;;;4737:887;4822:1;4802:17;:21;4737:887;;;4893:15;;;;:::i;:::-;4947;;;;4893;;-1:-1:-1;4947:15:22;;4931:31;;;-1:-1:-1;4986:5:22;4927:83;5083:1;5062:22;;;5053:32;;;5136:18;;;5028:15;5136:18;;;;;;;;;;;5120:36;;;5028:15;5211:238;5249:9;5236:10;:22;5211:238;;;5309:9;5319:10;5309:21;;;;;;;;:::i;:::-;;;;;;;5300:30;;:5;:30;;;5296:135;;5373:4;5358:19;;5403:5;;5296:135;5260:12;;;;:::i;:::-;;;;5211:238;;;;5471:12;5467:67;;;5507:8;;;;;5467:67;5575:5;5552:9;5562;5552:20;;;;;;;;:::i;:::-;:28;;;;:20;;;;;;;;;;;:28;5598:11;;;;:::i;:::-;;;;4875:749;;;4737:887;4841:19;;;;:::i;:::-;;;;4737:887;;;;4667:967;4654:11;;;;;:::i;:::-;;;;4597:1037;;;-1:-1:-1;;5725:28:22;;-1:-1:-1;5732:9:22;4295:1474::o;670:94:9:-;572:15:10;:13;:15::i;:::-;558:29;;:10;:29;;;537:117;;;;;;;11254:2:34;537:117:10;;;11236:21:34;11293:2;11273:18;;;11266:30;11332:34;11312:18;;;11305:62;11403:11;11383:18;;;11376:39;11432:19;;537:117:10;11052:405:34;537:117:10;739:18:9::1;:16;:18::i;:::-;670:94::o:0;436:2549:22:-;621:15;;477:28;;992:53:20;;621:15:22;;609:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;609:28:22;;;;;;;;;;;;;;;-1:-1:-1;695:15:22;;;;593:44;;-1:-1:-1;648:32:22;;695:15;;683:28;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;683:28:22;;648:63;;721:17;748:21;828:17;823:1681;863:15;;;;;;847:31;;823:1681;;;907:12;922:26;;;:15;;;:26;;;;;;;963:1531;1048:1;1028:17;:21;963:1531;;;1119:15;;;;:::i;:::-;1173;;;;1119;;-1:-1:-1;1173:15:22;;1157:31;;;-1:-1:-1;1212:5:22;1153:83;1309:1;1288:22;;;1279:32;;;1362:18;;;1254:15;1362:18;;;;;;;;;;;1346:36;;;1254:15;1437:633;1475:9;1462:10;:22;1437:633;;;1562:5;1526:41;;:13;1540:10;1526:25;;;;;;;;:::i;:::-;;;;;;;:32;;;:41;;;1522:530;;1718:8;1595:13;1609:10;1595:25;;;;;;;;:::i;:::-;;;;;;;:35;;;1660:17;1678:10;1660:29;;;;;;;;:::i;:::-;;;;;;;1595:120;;;;;;;;;;:::i;:::-;;;;;;:131;;;;;;;;;;;;;1892:3;1860:17;1878:10;1860:29;;;;;;;;:::i;:::-;;;;;;;:35;;;1852:44;;;;;;1922:17;1940:10;1922:29;;;;;;;;:::i;:::-;;;;;;:31;;;;;;;;:::i;:::-;;;;;-1:-1:-1;1994:4:22;;-1:-1:-1;2024:5:22;;1522:530;1486:12;;;;:::i;:::-;;;;1437:633;;;;2092:12;2088:67;;;2128:8;;;;;2088:67;2207:5;2173:13;2187:9;2173:24;;;;;;;;:::i;:::-;;;;;;;;;;;:39;;;;;;2301:15;;;;;;2267:67;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2267:67:22;;2230:13;2244:9;2230:24;;;;;;;;:::i;:::-;;;;;;;:34;;:104;;;;2392:8;2352:13;2366:9;2352:24;;;;;;;;:::i;:::-;;;;;;;:34;;;2387:1;2352:37;;;;;;;;:::i;:::-;;;;;;:48;;;;;;;;;;;;;2449:1;2418:17;2436:9;2418:28;;;;;;;;:::i;:::-;:32;;;;:28;;;;;;;;;;;:32;2468:11;;;;:::i;:::-;;;;1101:1393;;;963:1531;1067:19;;;;:::i;:::-;;;;963:1531;;;;893:1611;880:11;;;;;:::i;:::-;;;;823:1681;;;;2519:18;2514:350;2552:9;2539:10;:22;2514:350;;;2591:20;2614:17;2632:10;2614:29;;;;;;;;:::i;:::-;;;;;;;2591:52;;;;2657:25;2685:13;2699:10;2685:25;;;;;;;;:::i;:::-;;;;;;;:35;;;2657:63;;2827:12;2816:9;2809:31;2791:63;;2563:12;;;;;:::i;:::-;;;;2514:350;;;;2959:9;2944:13;2937:32;2923:56;;;;436:2549;:::o;515:101:9:-;568:7;594:15;:13;:15::i;:::-;587:22;;515:101;:::o;472:87:6:-;518:7;544:8;:6;:8::i;3127:150:18:-;478:8:7;:6;:8::i;:::-;464:22;;:10;:22;;;456:64;;;;;;;6821:2:34;456:64:7;;;6803:21:34;6860:2;6840:18;;;6833:30;6899:31;6879:18;;;6872:59;6948:18;;456:64:7;6619:353:34;456:64:7;3209:43:18;:61;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;3127:150::o;3043:1194:22:-;3279:15;;3137:25;;992:53:20;;3279:15:22;;3266:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3266:29:22;;3254:41;;3306:20;3336:21;3416:17;3411:694;3451:15;;;;;;3435:31;;3411:694;;;3495:12;3510:26;;;:15;;;:26;;;;;;;3551:544;3636:1;3616:17;:21;3551:544;;;3707:15;;;;:::i;:::-;3761;;;;3707;;-1:-1:-1;3761:15:22;;3745:31;;;-1:-1:-1;3800:5:22;3741:83;3897:1;3876:22;;;3867:32;;;3948:18;;;3842:15;3948:18;;;;;;;;;;;3932:36;;3923:45;;;;3919:162;;4018:8;3992:9;4002:12;3992:23;;;;;;;;:::i;:::-;:34;;;;:23;;;;;;;;;;;:34;4048:14;;;;:::i;:::-;;;;3919:162;-1:-1:-1;3655:19:22;;;;:::i;:::-;;;;3551:544;;;;3481:624;3468:11;;;;;:::i;:::-;;;;3411:694;;;-1:-1:-1;;4190:31:22;;-1:-1:-1;4197:9:22;3043:1194;-1:-1:-1;3043:1194:22:o;608:113:6:-;478:8:7;:6;:8::i;:::-;464:22;;:10;:22;;;456:64;;;;;;;6821:2:34;456:64:7;;;6803:21:34;6860:2;6840:18;;;6833:30;6899:31;6879:18;;;6872:59;6948:18;;456:64:7;6619:353:34;456:64:7;687:27:6::1;706:7;687:18;:27::i;:::-;608:113:::0;:::o;270:159:13:-;215:48;;270:159::o;624:257::-;763:25;;;;;;755:66;;;;;;;11844:2:34;755:66:13;;;11826:21:34;11883:2;11863:18;;;11856:30;11922;11902:18;;;11895:58;11970:18;;755:66:13;11642:352:34;755:66:13;831:34;;;;;:21;:34;;;;;;;;;;;;:43;;;;;;;;;;;;;624:257::o;1172:159:20:-;992:53;;1172:159::o;1636:2064::-;1868:15;;;;;;;;;;1836:29;;2066:1;2050:17;:21;2046:151;;-1:-1:-1;2180:1:20;2163:18;;;2147:35;;;;:15;;;:35;;;;;;2046:151;2216:9;2211:1077;2231:9;:16;2227:1;:20;2211:1077;;;2272:41;2316:9;2326:1;2316:12;;;;;;;;:::i;:::-;;;;;;;2272:56;;2346:38;2387:8;:15;;;2346:56;;2478:1;2450:8;:18;;;:25;:29;2421:135;;;;;;;12201:2:34;2421:135:20;;;12183:21:34;12240:2;12220:18;;;12213:30;12279:34;12259:18;;;12252:62;12350:5;12330:18;;;12323:33;12373:19;;2421:135:20;11999:399:34;2421:135:20;2589:35;2579:6;:45;;;;;;;;:::i;:::-;;2575:699;;2680:152;:1;2725:13;2764:12;2802:8;2680:19;:152::i;:::-;2648:184;;-1:-1:-1;2648:184:20;-1:-1:-1;2575:699:20;;;2871:39;2861:6;:49;;;;;;;;:::i;:::-;;2857:417;;2934:33;:1;2958:8;2934:23;:33::i;:::-;2857:417;;;3006:38;2996:6;:48;;;;;;;;:::i;:::-;;2992:282;;3100:155;:1;3148:13;3187:12;3225:8;3100:22;:155::i;:::-;3068:187;;-1:-1:-1;3068:187:20;-1:-1:-1;2992:282:20;-1:-1:-1;;2249:3:20;;2211:1077;;;;3323:21;3306:13;:38;3302:116;;3364:15;;;:39;;;;;;;;;;3302:116;3501:1;3485:17;;:21;3481:110;;3559:1;3542:18;;;3526:35;;;;:15;;;:35;;;;;:50;;;3481:110;3610:35;3621:9;3632:6;3640:4;3610:35;;;;;;;;:::i;:::-;;;;;;;;3659:24;3670:6;3678:4;3659:10;:24::i;:::-;1812:1882;;;1636:2064;;;;:::o;242:159:8:-;186:49;;242:159::o;407:92::-;477:15;;;;;;;;;;;;407:92::o;347:159:29:-;143:56;;347:159::o;3706:1646:20:-;3972:15;;3895:7;;;;3972:32;;3999:4;3972:32;;:84;;-1:-1:-1;4028:15:20;;:26;;438:20:31;484:8;;4028:28:20;3947:178;;;;;;;15154:2:34;3947:178:20;;;15136:21:34;15193:2;15173:18;;;15166:30;15232:34;15212:18;;;15205:62;15303:5;15283:18;;;15276:33;15326:19;;3947:178:20;14952:399:34;3947:178:20;4145:9;4140:1145;4160:8;:18;;;:25;4156:1;:29;4140:1145;;;4210:15;4228:8;:18;;;4247:1;4228:21;;;;;;;;:::i;:::-;;;;;;;;;;;;4286:18;;;4267:16;4286:18;;;;;;;;;;;;4228:21;;-1:-1:-1;4352:26:20;;;;:40;4323:146;;;;;;;15558:2:34;4323:146:20;;;15540:21:34;15597:2;15577:18;;;15570:30;15636:34;15616:18;;;15609:62;15707:5;15687:18;;;15680:33;15730:19;;4323:146:20;15356:399:34;4323:146:20;4579:15;;4530:18;;;;4618:22;4530:18;;;;;;;;;;4571:24;;;;;:69;;;;4530:110;;;4714:1;4691:24;;;;;;;4950:43;;;4879:45;;;4877:48;4838:87;;;;4837:157;;5077:29;;;5073:164;;5163:1;5146:18;;;5130:35;;;;:15;;;:35;;;;;:50;;;;5073:164;-1:-1:-1;;;5255:15:20;;;;;4187:3;4140:1145;;;-1:-1:-1;5307:13:20;;5322:12;;-1:-1:-1;3706:1646:20;;-1:-1:-1;;;3706:1646:20:o;9135:1216::-;9317:15;;:26;;438:20:31;9292:126:20;;;;;;;15962:2:34;9292:126:20;;;15944:21:34;16001:2;15981:18;;;15974:30;16040:34;16020:18;;;16013:62;16111:9;16091:18;;;16084:37;16138:19;;9292:126:20;15760:403:34;9292:126:20;9438:9;9433:902;9453:8;:18;;;:25;9449:1;:29;9433:902;;;9503:15;9521:8;:18;;;9540:1;9521:21;;;;;;;;:::i;:::-;;;;;;;;;;;;9579:18;;;9560:16;9579:18;;;;;;;;;;;;9521:21;;-1:-1:-1;9641:26:20;;;;;9686:131;;;;;;;16370:2:34;9686:131:20;;;16352:21:34;16409:2;16389:18;;;16382:30;16448:33;16428:18;;;16421:61;16499:18;;9686:131:20;16168:355:34;9686:131:20;9892:4;9865:32;;;;9836:137;;;;;;;16730:2:34;9836:137:20;;;16712:21:34;16769:2;16749:18;;;16742:30;16808:34;16788:18;;;16781:62;16879:4;16859:18;;;16852:32;16901:19;;9836:137:20;16528:398:34;9836:137:20;10040:8;:15;;;10021:34;;:15;:34;;;9992:145;;;;;;;17133:2:34;9992:145:20;;;17115:21:34;17172:2;17152:18;;;17145:30;17211:34;17191:18;;;17184:62;17282:10;17262:18;;;17255:38;17310:19;;9992:145:20;16931:404:34;9992:145:20;-1:-1:-1;10304:15:20;;10201:18;;;;;10304:15;10201:18;;;;;;;;;;10296:24;;;;;10242:78;;;10243:29;;;;10242:78;10201:119;;9480:3;;9433:902;;;;9135:1216;;:::o;5358:3771::-;5627:15;;5550:7;;;;5627:29;;;5602:135;;;;;;;17542:2:34;5602:135:20;;;17524:21:34;17581:2;17561:18;;;17554:30;17620:34;17600:18;;;17593:62;17691:17;17671:18;;;17664:45;17726:19;;5602:135:20;17340:411:34;5602:135:20;5797:1;5780:18;;;5858:1;5842:17;;5752:25;5874:3111;5894:8;:18;;;:25;5890:1;:29;5874:3111;;;5944:15;5962:8;:18;;;5981:1;5962:21;;;;;;;;:::i;:::-;;;;;;;;;;;;6020:18;;;6001:16;6020:18;;;;;;;;;;;;5962:21;;-1:-1:-1;6086:26:20;;;;6057:142;;;;;;;16370:2:34;6057:142:20;;;16352:21:34;16409:2;16389:18;;;16382:30;16448:33;16428:18;;;16421:61;16499:18;;6057:142:20;16168:355:34;6057:142:20;6285:4;6247:26;;;;:43;6218:148;;;;;;;16730:2:34;6218:148:20;;;16712:21:34;16769:2;16749:18;;;16742:30;16808:34;16788:18;;;16781:62;16879:4;16859:18;;;16852:32;16901:19;;6218:148:20;16528:398:34;6218:148:20;6405:1;6389:17;;;6385:267;;6430:19;;;;6486:34;;;;:15;;;:34;;;;;;;-1:-1:-1;6430:19:20;6564:1;;-1:-1:-1;6385:267:20;;;6612:21;;;;;6385:267;7055:1;7032:24;;;7015:42;;;6670:19;;7106:24;;;;;;;;7102:292;;7348:22;;;:8;:22;;;;;;;;;;;;7278:93;;;7279:29;;7278:93;7225:146;;7102:292;-1:-1:-1;;7423:18:20;;;:8;:18;;;;;;;;;;7416:25;7561:21;7581:1;7561:21;;;;7632:27;7658:1;7632:27;;;;7700:42;;;7696:1107;;7766:23;7792:84;;;:15;;;:84;;;;;;;8200:21;8090:80;;;8088:83;8042:129;;;8200:21;;;:50;;8041:210;8335:56;;7696:1107;;;8758:25;8741:12;8733:21;;;:50;;8678:25;917:17;901:35;;8623:80;;8621:83;8578:12;:126;8577:207;8538:246;;7696:1107;8825:19;8848:1;8825:24;8821:150;;8880:34;;;;:15;;;:34;;;;;8873:41;;;8880:34;-1:-1:-1;8821:150:20;-1:-1:-1;;5921:3:20;;;;;-1:-1:-1;5874:3111:20;;-1:-1:-1;;5874:3111:20;;-1:-1:-1;9037:1:20;9016:22;;;;9015:46;;9099:12;;-1:-1:-1;5358:3771:20;;-1:-1:-1;;;;5358:3771:20:o;728:111:7:-;777:7;186:49:8;803:23:7;:29;;;;728:111;-1:-1:-1;728:111:7:o;776:129:10:-;832:7;197:53:11;858:27:10;257:159:11;980:272:10;186:49:8;1128:7:10;;1107:41;;1137:10;;1107:41;1128:7;;1107:41;;1035:31;;1107:41;477:15:8;;;;1169:10:10;477:15:8;;;1190:55:10;1242:1;197:53:11;1190:27:10;:43;477:15:8;;;;;;;;;;;;407:92;3283:179:18;3422:33;3447:7;3422:24;:33::i;10357:729:20:-;10478:11;;:16;10452:20;;;;10451:44;10430:137;;;;;;;17958:2:34;10430:137:20;;;17940:21:34;17997:2;17977:18;;;17970:30;18036:34;18016:18;;;18009:62;18107:16;18087:18;;;18080:44;18141:19;;10430:137:20;17756:410:34;10430:137:20;10582:20;;;;10578:502;;10622:23;;;10640:4;10622:23;10618:198;;10694:17;;;438:20:31;10665:136:20;;;;;;;18373:2:34;10665:136:20;;;18355:21:34;18412:2;18392:18;;;18385:30;18451:34;18431:18;;;18424:62;18522:16;18502:18;;;18495:44;18556:19;;10665:136:20;18171:410:34;10665:136:20;10831:12;10849:6;:19;;10869:4;10849:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10830:44;;;10894:7;10889:181;;10973:16;10970:1;;10952:38;11021:16;10970:1;11011:27;10578:502;10357:729;;:::o;770:187:9:-;917:33;942:7;1433:52:10;1477:7;197:53:11;1433:27:10;257:159:11;421:219:34;488:20;;548:66;537:78;;527:89;;517:117;;630:1;627;620:12;517:117;421:219;;;:::o;645:184::-;703:6;756:2;744:9;735:7;731:23;727:32;724:52;;;772:1;769;762:12;724:52;795:28;813:9;795:28;:::i;1026:196::-;1094:20;;1154:42;1143:54;;1133:65;;1123:93;;1212:1;1209;1202:12;1227:347;1278:8;1288:6;1342:3;1335:4;1327:6;1323:17;1319:27;1309:55;;1360:1;1357;1350:12;1309:55;-1:-1:-1;1383:20:34;;1426:18;1415:30;;1412:50;;;1458:1;1455;1448:12;1412:50;1495:4;1487:6;1483:17;1471:29;;1547:3;1540:4;1531:6;1523;1519:19;1515:30;1512:39;1509:59;;;1564:1;1561;1554:12;1509:59;1227:347;;;;;:::o;1579:1010::-;1722:6;1730;1738;1746;1754;1807:2;1795:9;1786:7;1782:23;1778:32;1775:52;;;1823:1;1820;1813:12;1775:52;1863:9;1850:23;1892:18;1933:2;1925:6;1922:14;1919:34;;;1949:1;1946;1939:12;1919:34;1987:6;1976:9;1972:22;1962:32;;2032:7;2025:4;2021:2;2017:13;2013:27;2003:55;;2054:1;2051;2044:12;2003:55;2094:2;2081:16;2120:2;2112:6;2109:14;2106:34;;;2136:1;2133;2126:12;2106:34;2191:7;2184:4;2174:6;2171:1;2167:14;2163:2;2159:23;2155:34;2152:47;2149:67;;;2212:1;2209;2202:12;2149:67;2243:4;2239:2;2235:13;2225:23;;2267:6;2257:16;;;2292:40;2326:4;2315:9;2311:20;2292:40;:::i;:::-;2282:50;;2385:2;2374:9;2370:18;2357:32;2341:48;;2414:2;2404:8;2401:16;2398:36;;;2430:1;2427;2420:12;2398:36;;2469:60;2521:7;2510:8;2499:9;2495:24;2469:60;:::i;:::-;1579:1010;;;;-1:-1:-1;1579:1010:34;;-1:-1:-1;2548:8:34;;2443:86;1579:1010;-1:-1:-1;;;1579:1010:34:o;2957:681::-;3128:2;3180:21;;;3250:13;;3153:18;;;3272:22;;;3099:4;;3128:2;3351:15;;;;3325:2;3310:18;;;3099:4;3394:218;3408:6;3405:1;3402:13;3394:218;;;3473:13;;3488:42;3469:62;3457:75;;3587:15;;;;3552:12;;;;3430:1;3423:9;3394:218;;;-1:-1:-1;3629:3:34;;2957:681;-1:-1:-1;;;;;;2957:681:34:o;3643:507::-;3695:3;3733:5;3727:12;3760:6;3755:3;3748:19;3786:4;3815:2;3810:3;3806:12;3799:19;;3852:2;3845:5;3841:14;3873:1;3883:242;3897:6;3894:1;3891:13;3883:242;;;3962:13;;3977:66;3958:86;3946:99;;4065:12;;;;4100:15;;;;3919:1;3912:9;3883:242;;;-1:-1:-1;4141:3:34;;3643:507;-1:-1:-1;;;;;3643:507:34:o;4155:1141::-;4343:4;4372:2;4412;4401:9;4397:18;4442:2;4431:9;4424:21;4465:6;4500;4494:13;4531:6;4523;4516:22;4557:2;4547:12;;4590:2;4579:9;4575:18;4568:25;;4652:2;4642:6;4639:1;4635:14;4624:9;4620:30;4616:39;4690:2;4682:6;4678:15;4711:1;4721:546;4735:6;4732:1;4729:13;4721:546;;;4800:22;;;4824:66;4796:95;4784:108;;4915:13;;4960:9;;4971:42;4956:58;4941:74;;5054:11;;5048:18;5086:15;;;5079:27;;;5129:58;5171:15;;;5048:18;5129:58;:::i;:::-;5245:12;;;;5119:68;-1:-1:-1;;5210:15:34;;;;4757:1;4750:9;4721:546;;;-1:-1:-1;5284:6:34;;4155:1141;-1:-1:-1;;;;;;;;4155:1141:34:o;5301:186::-;5360:6;5413:2;5401:9;5392:7;5388:23;5384:32;5381:52;;;5429:1;5426;5419:12;5381:52;5452:29;5471:9;5452:29;:::i;5492:703::-;5661:2;5713:21;;;5783:13;;5686:18;;;5805:22;;;5632:4;;5661:2;5884:15;;;;5858:2;5843:18;;;5632:4;5927:242;5941:6;5938:1;5935:13;5927:242;;;6006:13;;6021:66;6002:86;5990:99;;6144:15;;;;6109:12;;;;5963:1;5956:9;5927:242;;6977:184;7029:77;7026:1;7019:88;7126:4;7123:1;7116:15;7150:4;7147:1;7140:15;7166:253;7238:2;7232:9;7280:4;7268:17;;7315:18;7300:34;;7336:22;;;7297:62;7294:88;;;7362:18;;:::i;:::-;7398:2;7391:22;7166:253;:::o;7424:334::-;7495:2;7489:9;7551:2;7541:13;;7556:66;7537:86;7525:99;;7654:18;7639:34;;7675:22;;;7636:62;7633:88;;;7701:18;;:::i;:::-;7737:2;7730:22;7424:334;;-1:-1:-1;7424:334:34:o;7763:191::-;7831:4;7864:18;7856:6;7853:30;7850:56;;;7886:18;;:::i;:::-;-1:-1:-1;7931:1:34;7927:14;7943:4;7923:25;;7763:191::o;7959:2510::-;8129:9;8164:72;8180:55;8228:6;8180:55;:::i;:::-;8164:72;:::i;:::-;8270:19;;;8308:4;8328:12;;;;8258:3;8359:1;8394:15;;;8383:27;;8433:14;8422:26;;8419:46;;;8461:1;8458;8451:12;8419:46;8485:5;8499:1937;8515:6;8510:3;8507:15;8499:1937;;;8601:3;8588:17;8628:18;8678:2;8665:11;8662:19;8659:109;;;8722:1;8751:2;8747;8740:14;8659:109;8802:11;8795:5;8791:23;8781:33;;8859:4;8854:2;8838:14;8834:23;8830:34;8827:124;;;8905:1;8934:2;8930;8923:14;8827:124;8979:22;;:::i;:::-;9030;9049:2;9030:22;:::i;:::-;9021:7;9014:39;9102:2;9098;9094:11;9081:25;9141:1;9132:7;9129:14;9119:112;;9185:1;9214:2;9210;9203:14;9119:112;9251:16;;;9244:33;9300:2;9342:11;;;9329:25;9370:14;;;9367:104;;;9425:1;9454:2;9450;9443:14;9367:104;9495:15;;;;;9553:14;9546:4;9537:14;;9533:35;9523:136;;9611:1;9600:12;;9641:3;9636;9629:16;9523:136;9696:3;9683:17;9672:28;;9726:69;9742:52;9790:3;9742:52;:::i;9726:69::-;9839:18;;;9935:12;;;9926:22;;9922:31;;;9879:14;;;;9982;9969:28;;9966:121;;;10039:1;10069:3;10064;10057:16;9966:121;10113:12;;;;10138:179;10156:8;10149:5;10146:19;10138:179;;;10238:24;10256:5;10238:24;:::i;:::-;10224:39;;10177:14;;;;10289;;;;10138:179;;;10337:16;;;10330:31;;;;-1:-1:-1;10374:20:34;;-1:-1:-1;;10414:12:34;;;;8532;;8499:1937;;;-1:-1:-1;10458:5:34;;7959:2510;-1:-1:-1;;;;;;;7959:2510:34:o;10474:184::-;10526:77;10523:1;10516:88;10623:4;10620:1;10613:15;10647:4;10644:1;10637:15;10663:195;10702:3;10733:66;10726:5;10723:77;10720:103;;10803:18;;:::i;:::-;-1:-1:-1;10850:1:34;10839:13;;10663:195::o;10863:184::-;10915:77;10912:1;10905:88;11012:4;11009:1;11002:15;11036:4;11033:1;11026:15;11462:175;11499:3;11543:4;11536:5;11532:16;11572:4;11563:7;11560:17;11557:43;;11580:18;;:::i;:::-;11629:1;11616:15;;11462:175;-1:-1:-1;;11462:175:34:o;12403:184::-;12455:77;12452:1;12445:88;12552:4;12549:1;12542:15;12576:4;12573:1;12566:15;12592:250;12677:1;12687:113;12701:6;12698:1;12695:13;12687:113;;;12777:11;;;12771:18;12758:11;;;12751:39;12723:2;12716:10;12687:113;;;-1:-1:-1;;12834:1:34;12816:16;;12809:27;12592:250::o;12847:329::-;12888:3;12926:5;12920:12;12953:6;12948:3;12941:19;12969:76;13038:6;13031:4;13026:3;13022:14;13015:4;13008:5;13004:16;12969:76;:::i;:::-;13090:2;13078:15;13095:66;13074:88;13065:98;;;;13165:4;13061:109;;12847:329;-1:-1:-1;;12847:329:34:o;13181:1766::-;13449:4;13478:2;13518;13507:9;13503:18;13548:2;13537:9;13530:21;13571:6;13606;13600:13;13637:6;13629;13622:22;13675:3;13664:9;13660:19;13653:26;;13738:3;13728:6;13725:1;13721:14;13710:9;13706:30;13702:40;13688:54;;13761:4;13800:2;13792:6;13788:15;13821:1;13842;13852:924;13868:6;13863:3;13860:15;13852:924;;;13961:66;13949:9;13941:6;13937:22;13933:95;13928:3;13921:108;14058:6;14052:13;14108:42;14103:2;14097:9;14093:58;14085:6;14078:74;14199:2;14195;14191:11;14185:18;14243:1;14229:12;14226:19;14216:227;;14287:77;14284:1;14277:88;14392:4;14389:1;14382:15;14424:4;14421:1;14414:15;14216:227;14463:15;;;14456:37;14516:4;14561:11;;;14555:18;14593:15;;;14586:27;;;14636:60;14680:15;;;14555:18;14636:60;:::i;:::-;14626:70;-1:-1:-1;;14754:12:34;;;;14719:15;;;;13894:1;13885:11;13852:924;;;-1:-1:-1;;;2671:42:34;2660:54;;14812:18;;;2648:67;-1:-1:-1;;14869:22:34;;;14862:4;14847:20;;14840:52;14909:32;14873:6;14926;14909:32;:::i;:::-;14901:40;13181:1766;-1:-1:-1;;;;;;;13181:1766:34:o;18586:287::-;18715:3;18753:6;18747:13;18769:66;18828:6;18823:3;18816:4;18808:6;18804:17;18769:66;:::i;:::-;18851:16;;;;;18586:287;-1:-1:-1;;18586:287:34:o

Swarm Source

ipfs://1ea4979c112f2595668803808f7fd45309944af7e78c8843e282225168961945
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.