Token Mu Gold

Overview ERC20

Price
$1.67 @ 0.164716 AVAX
Fully Diluted Market Cap
Total Supply:
100,000 MUG

Holders:
385 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

OVERVIEW

Mu Coin is the entry point into the Mu Ecosystem. It is a speculative token by nature. It serves to main functions in the Mu Ecosystem.


Update? Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MuGold

Compiler Version
v0.8.2+commit.661d1103

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at snowtrace.io on 2022-01-17
*/

// File: @openzeppelin/contracts/utils/math/SafeCast.sol


// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        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);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed 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";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts/utils/cryptography/draft-EIP712.sol


// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)

pragma solidity ^0.8.0;


/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// File: @openzeppelin/contracts/utils/Counters.sol


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

// File: @openzeppelin/contracts/utils/Arrays.sol


// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)

pragma solidity ^0.8.0;


/**
 * @dev Collection of functions related to array types.
 */
library Arrays {
    /**
     * @dev Searches a sorted `array` and returns the first index that contains
     * a value greater or equal to `element`. If no such index exists (i.e. all
     * values in the array are strictly less than `element`), the array length is
     * returned. Time complexity O(log n).
     *
     * `array` is expected to be sorted in ascending order, and to contain no
     * repeated elements.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        unchecked {
            _approve(sender, _msgSender(), currentAllowance - amount);
        }

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[sender] = senderBalance - amount;
        }
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);

        _afterTokenTransfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)

pragma solidity ^0.8.0;






/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * _Available since v3.4._
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping(address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private immutable _PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @dev See {IERC20Permit-permit}.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual override {
        require(block.timestamp <= deadline, "ERC20Permit: expired deadline");

        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC20Permit: invalid signature");

        _approve(owner, spender, value);
    }

    /**
     * @dev See {IERC20Permit-nonces}.
     */
    function nonces(address owner) public view virtual override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    /**
     * @dev "Consume a nonce": return the current value and increment.
     *
     * _Available since v4.1._
     */
    function _useNonce(address owner) internal virtual returns (uint256 current) {
        Counters.Counter storage nonce = _nonces[owner];
        current = nonce.current();
        nonce.increment();
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Votes.sol)

pragma solidity ^0.8.0;





/**
 * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,
 * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.
 *
 * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.
 *
 * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either
 * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting
 * power can be queried through the public accessors {getVotes} and {getPastVotes}.
 *
 * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it
 * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
 * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this
 * will significantly increase the base gas cost of transfers.
 *
 * _Available since v4.2._
 */
abstract contract ERC20Votes is ERC20Permit {
    struct Checkpoint {
        uint32 fromBlock;
        uint224 votes;
    }

    bytes32 private constant _DELEGATION_TYPEHASH =
        keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

    mapping(address => address) private _delegates;
    mapping(address => Checkpoint[]) private _checkpoints;
    Checkpoint[] private _totalSupplyCheckpoints;

    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Get the `pos`-th checkpoint for `account`.
     */
    function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {
        return _checkpoints[account][pos];
    }

    /**
     * @dev Get number of checkpoints for `account`.
     */
    function numCheckpoints(address account) public view virtual returns (uint32) {
        return SafeCast.toUint32(_checkpoints[account].length);
    }

    /**
     * @dev Get the address `account` is currently delegating to.
     */
    function delegates(address account) public view virtual returns (address) {
        return _delegates[account];
    }

    /**
     * @dev Gets the current votes balance for `account`
     */
    function getVotes(address account) public view returns (uint256) {
        uint256 pos = _checkpoints[account].length;
        return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
    }

    /**
     * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_checkpoints[account], blockNumber);
    }

    /**
     * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.
     * It is but NOT the sum of all the delegated votes!
     *
     * Requirements:
     *
     * - `blockNumber` must have been already mined
     */
    function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {
        require(blockNumber < block.number, "ERC20Votes: block not yet mined");
        return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);
    }

    /**
     * @dev Lookup a value in a list of (sorted) checkpoints.
     */
    function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {
        // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.
        //
        // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).
        // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.
        // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)
        // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)
        // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not
        // out of bounds (in which case we're looking too far in the past and the result is 0).
        // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is
        // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out
        // the same.
        uint256 high = ckpts.length;
        uint256 low = 0;
        while (low < high) {
            uint256 mid = Math.average(low, high);
            if (ckpts[mid].fromBlock > blockNumber) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        return high == 0 ? 0 : ckpts[high - 1].votes;
    }

    /**
     * @dev Delegate votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) public virtual {
        _delegate(_msgSender(), delegatee);
    }

    /**
     * @dev Delegates votes from signer to `delegatee`
     */
    function delegateBySig(
        address delegatee,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(block.timestamp <= expiry, "ERC20Votes: signature expired");
        address signer = ECDSA.recover(
            _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),
            v,
            r,
            s
        );
        require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce");
        _delegate(signer, delegatee);
    }

    /**
     * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).
     */
    function _maxSupply() internal view virtual returns (uint224) {
        return type(uint224).max;
    }

    /**
     * @dev Snapshots the totalSupply after it has been increased.
     */
    function _mint(address account, uint256 amount) internal virtual override {
        super._mint(account, amount);
        require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes");

        _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);
    }

    /**
     * @dev Snapshots the totalSupply after it has been decreased.
     */
    function _burn(address account, uint256 amount) internal virtual override {
        super._burn(account, amount);

        _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);
    }

    /**
     * @dev Move voting power when tokens are transferred.
     *
     * Emits a {DelegateVotesChanged} event.
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._afterTokenTransfer(from, to, amount);

        _moveVotingPower(delegates(from), delegates(to), amount);
    }

    /**
     * @dev Change delegation for `delegator` to `delegatee`.
     *
     * Emits events {DelegateChanged} and {DelegateVotesChanged}.
     */
    function _delegate(address delegator, address delegatee) internal virtual {
        address currentDelegate = delegates(delegator);
        uint256 delegatorBalance = balanceOf(delegator);
        _delegates[delegator] = delegatee;

        emit DelegateChanged(delegator, currentDelegate, delegatee);

        _moveVotingPower(currentDelegate, delegatee, delegatorBalance);
    }

    function _moveVotingPower(
        address src,
        address dst,
        uint256 amount
    ) private {
        if (src != dst && amount > 0) {
            if (src != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);
                emit DelegateVotesChanged(src, oldWeight, newWeight);
            }

            if (dst != address(0)) {
                (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);
                emit DelegateVotesChanged(dst, oldWeight, newWeight);
            }
        }
    }

    function _writeCheckpoint(
        Checkpoint[] storage ckpts,
        function(uint256, uint256) view returns (uint256) op,
        uint256 delta
    ) private returns (uint256 oldWeight, uint256 newWeight) {
        uint256 pos = ckpts.length;
        oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;
        newWeight = op(oldWeight, delta);

        if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {
            ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);
        } else {
            ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));
        }
    }

    function _add(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    function _subtract(uint256 a, uint256 b) private pure returns (uint256) {
        return a - b;
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol)

pragma solidity ^0.8.0;




/**
 * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and
 * total supply at the time are recorded for later access.
 *
 * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.
 * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different
 * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be
 * used to create an efficient ERC20 forking mechanism.
 *
 * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a
 * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot
 * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id
 * and the account address.
 *
 * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it
 * return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this
 * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.
 *
 * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient
 * alternative consider {ERC20Votes}.
 *
 * ==== Gas Costs
 *
 * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log
 * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much
 * smaller since identical balances in subsequent snapshots are stored as a single entry.
 *
 * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is
 * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent
 * transfers will have normal cost until the next snapshot, and so on.
 */

abstract contract ERC20Snapshot is ERC20 {
    // Inspired by Jordi Baylina's MiniMeToken to record historical balances:
    // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol

    using Arrays for uint256[];
    using Counters for Counters.Counter;

    // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a
    // Snapshot struct, but that would impede usage of functions that work on an array.
    struct Snapshots {
        uint256[] ids;
        uint256[] values;
    }

    mapping(address => Snapshots) private _accountBalanceSnapshots;
    Snapshots private _totalSupplySnapshots;

    // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.
    Counters.Counter private _currentSnapshotId;

    /**
     * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.
     */
    event Snapshot(uint256 id);

    /**
     * @dev Creates a new snapshot and returns its snapshot id.
     *
     * Emits a {Snapshot} event that contains the same id.
     *
     * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a
     * set of accounts, for example using {AccessControl}, or it may be open to the public.
     *
     * [WARNING]
     * ====
     * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,
     * you must consider that it can potentially be used by attackers in two ways.
     *
     * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow
     * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target
     * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs
     * section above.
     *
     * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.
     * ====
     */
    function _snapshot() internal virtual returns (uint256) {
        _currentSnapshotId.increment();

        uint256 currentId = _getCurrentSnapshotId();
        emit Snapshot(currentId);
        return currentId;
    }

    /**
     * @dev Get the current snapshotId
     */
    function _getCurrentSnapshotId() internal view virtual returns (uint256) {
        return _currentSnapshotId.current();
    }

    /**
     * @dev Retrieves the balance of `account` at the time `snapshotId` was created.
     */
    function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);

        return snapshotted ? value : balanceOf(account);
    }

    /**
     * @dev Retrieves the total supply at the time `snapshotId` was created.
     */
    function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {
        (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);

        return snapshotted ? value : totalSupply();
    }

    // Update balance and/or total supply snapshots before the values are modified. This is implemented
    // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        if (from == address(0)) {
            // mint
            _updateAccountSnapshot(to);
            _updateTotalSupplySnapshot();
        } else if (to == address(0)) {
            // burn
            _updateAccountSnapshot(from);
            _updateTotalSupplySnapshot();
        } else {
            // transfer
            _updateAccountSnapshot(from);
            _updateAccountSnapshot(to);
        }
    }

    function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {
        require(snapshotId > 0, "ERC20Snapshot: id is 0");
        require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id");

        // When a valid snapshot is queried, there are three possibilities:
        //  a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never
        //  created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds
        //  to this id is the current one.
        //  b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the
        //  requested id, and its value is the one to return.
        //  c) More snapshots were created after the requested one, and the queried value was later modified. There will be
        //  no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is
        //  larger than the requested one.
        //
        // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if
        // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does
        // exactly this.

        uint256 index = snapshots.ids.findUpperBound(snapshotId);

        if (index == snapshots.ids.length) {
            return (false, 0);
        } else {
            return (true, snapshots.values[index]);
        }
    }

    function _updateAccountSnapshot(address account) private {
        _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));
    }

    function _updateTotalSupplySnapshot() private {
        _updateSnapshot(_totalSupplySnapshots, totalSupply());
    }

    function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {
        uint256 currentId = _getCurrentSnapshotId();
        if (_lastSnapshotId(snapshots.ids) < currentId) {
            snapshots.ids.push(currentId);
            snapshots.values.push(currentValue);
        }
    }

    function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {
        if (ids.length == 0) {
            return 0;
        } else {
            return ids[ids.length - 1];
        }
    }
}

// File: contracts/MuGold.sol


pragma solidity ^0.8.2;






/// @custom:security-contact [email protected]
contract MuGold is ERC20, ERC20Snapshot, Ownable, ERC20Permit, ERC20Votes {
    constructor() ERC20("Mu Gold", "MUG") ERC20Permit("Mu Gold") {
        _mint(msg.sender, 100000 * 10 ** decimals());
    }

    function snapshot() public onlyOwner {
        _snapshot();
    }

    // The following functions are overrides required by Solidity.

    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Snapshot)
    {
        super._beforeTokenTransfer(from, to, amount);
    }

    function _afterTokenTransfer(address from, address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._afterTokenTransfer(from, to, amount);
    }

    function _mint(address to, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._mint(to, amount);
    }

    function _burn(address account, uint256 amount)
        internal
        override(ERC20, ERC20Votes)
    {
        super._burn(account, amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20Votes.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610140908152503480156200003a57600080fd5b506040518060400160405280600781526020017f4d7520476f6c6400000000000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600781526020017f4d7520476f6c64000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f4d5547000000000000000000000000000000000000000000000000000000000081525081600390805190602001906200012c92919062001021565b5080600490805190602001906200014592919062001021565b505050620001686200015c6200026360201b60201c565b6200026b60201b60201c565b60008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a08181525050620001d18184846200033160201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508061012081815250505050505050506200025d33620002336200036d60201b60201c565b600a62000241919062001398565b620186a0620002519190620014d5565b6200037660201b60201c565b6200177d565b600033905090565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600083838346306040516020016200034e959493929190620011a0565b6040516020818303038152906040528051906020012090509392505050565b60006012905090565b6200038d82826200039160201b620014711760201c565b5050565b620003a882826200044f60201b620014fe1760201c565b620003b8620005c860201b60201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16620003e6620005ec60201b60201c565b11156200042a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200042190620011fd565b60405180910390fd5b62000449600d620005f660201b6200165e17836200060e60201b60201c565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620004c2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004b99062001263565b60405180910390fd5b620004d6600083836200092b60201b60201c565b8060026000828254620004ea9190620012e0565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254620005419190620012e0565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620005a8919062001285565b60405180910390a3620005c4600083836200094860201b60201c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000600254905090565b60008183620006069190620012e0565b905092915050565b60008060008580549050905060008114620006a7578560018262000633919062001536565b815481106200066b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16620006aa565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250620006d683858760201c565b91506000811180156200075357504386600183620006f5919062001536565b815481106200072d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b1562000818576200076f826200096560201b620016741760201c565b866001836200077f919062001536565b81548110620007b7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555062000922565b8560405180604001604052806200083a43620009d360201b620016df1760201c565b63ffffffff1681526020016200085b856200096560201b620016741760201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b6200094383838362000a2960201b620017321760201c565b505050565b6200096083838362000b2460201b620017ec1760201c565b505050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115620009cb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009c2906200121f565b60405180910390fd5b819050919050565b600063ffffffff801682111562000a21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a189062001241565b60405180910390fd5b819050919050565b62000a4183838362000b7460201b620018171760201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141562000a9e5762000a888262000b7960201b60201c565b62000a9862000bdc60201b60201c565b62000b1f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000afb5762000ae58362000b7960201b60201c565b62000af562000bdc60201b60201c565b62000b1e565b62000b0c8362000b7960201b60201c565b62000b1d8262000b7960201b60201c565b5b5b505050565b62000b3c83838362000c0060201b6200181c1760201c565b62000b6f62000b518462000c0560201b60201c565b62000b628462000c0560201b60201c565b8362000c6e60201b60201c565b505050565b505050565b62000bd9600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002062000bcd8362000e9160201b60201c565b62000ed960201b60201c565b50565b62000bfe600662000bf2620005ec60201b60201c565b62000ed960201b60201c565b565b505050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801562000cab5750600081115b1562000e8c57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000d9e5760008062000d45600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002062000f6560201b6200182117856200060e60201b60201c565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000d93929190620012a2565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462000e8b5760008062000e32600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020620005f660201b6200165e17856200060e60201b60201c565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000e80929190620012a2565b60405180910390a250505b5b505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600062000eeb62000f7d60201b60201c565b90508062000f028460000162000f9b60201b60201c565b101562000f605782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b6000818362000f75919062001536565b905092915050565b600062000f9660086200101360201b620018371760201c565b905090565b6000808280549050141562000fb457600090506200100e565b816001838054905062000fc8919062001536565b8154811062001000577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490505b919050565b600081600001549050919050565b8280546200102f90620015c6565b90600052602060002090601f0160209004810192826200105357600085556200109f565b82601f106200106e57805160ff19168380011785556200109f565b828001600101855582156200109f579182015b828111156200109e57825182559160200191906001019062001081565b5b509050620010ae9190620010b2565b5090565b5b80821115620010cd576000816000905550600101620010b3565b5090565b620010dc8162001571565b82525050565b620010ed8162001585565b82525050565b600062001102603083620012cf565b91506200110f8262001667565b604082019050919050565b600062001129602783620012cf565b91506200113682620016b6565b604082019050919050565b600062001150602683620012cf565b91506200115d8262001705565b604082019050919050565b600062001177601f83620012cf565b9150620011848262001754565b602082019050919050565b6200119a81620015af565b82525050565b600060a082019050620011b76000830188620010e2565b620011c66020830187620010e2565b620011d56040830186620010e2565b620011e460608301856200118f565b620011f36080830184620010d1565b9695505050505050565b600060208201905081810360008301526200121881620010f3565b9050919050565b600060208201905081810360008301526200123a816200111a565b9050919050565b600060208201905081810360008301526200125c8162001141565b9050919050565b600060208201905081810360008301526200127e8162001168565b9050919050565b60006020820190506200129c60008301846200118f565b92915050565b6000604082019050620012b960008301856200118f565b620012c860208301846200118f565b9392505050565b600082825260208201905092915050565b6000620012ed82620015af565b9150620012fa83620015af565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620013325762001331620015fc565b5b828201905092915050565b6000808291508390505b60018511156200138f57808604811115620013675762001366620015fc565b5b6001851615620013775780820291505b808102905062001387856200165a565b945062001347565b94509492505050565b6000620013a582620015af565b9150620013b283620015b9565b9250620013e17fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620013e9565b905092915050565b600082620013fb5760019050620014ce565b816200140b5760009050620014ce565b81600181146200142457600281146200142f5762001465565b6001915050620014ce565b60ff841115620014445762001443620015fc565b5b8360020a9150848211156200145e576200145d620015fc565b5b50620014ce565b5060208310610133831016604e8410600b84101617156200149f5782820a905083811115620014995762001498620015fc565b5b620014ce565b620014ae84848460016200133d565b92509050818404811115620014c857620014c7620015fc565b5b81810290505b9392505050565b6000620014e282620015af565b9150620014ef83620015af565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156200152b576200152a620015fc565b5b828202905092915050565b60006200154382620015af565b91506200155083620015af565b925082821015620015665762001565620015fc565b5b828203905092915050565b60006200157e826200158f565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006002820490506001821680620015df57607f821691505b60208210811415620015f657620015f56200162b565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008160011c9050919050565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b60805160a05160c05160601c60e0516101005161012051610140516145da620017db60003960006110c101526000611d4701526000611d8901526000611d6801526000611c9d01526000611cf301526000611d1c01526145da6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80637ecebe00116100f9578063a457c2d711610097578063d505accf11610071578063d505accf14610569578063dd62ed3e14610585578063f1127ed8146105b5578063f2fde38b146105e5576101c4565b8063a457c2d7146104ed578063a9059cbb1461051d578063c3cda5201461054d576101c4565b806395d89b41116100d357806395d89b41146104655780639711715a14610483578063981b24d01461048d5780639ab24eb0146104bd576101c4565b80637ecebe00146103e75780638da5cb5b146104175780638e539e8c14610435576101c4565b80633a46b1a8116101665780635c19a95c116101405780635c19a95c146103615780636fcfff451461037d57806370a08231146103ad578063715018a6146103dd576101c4565b80633a46b1a8146102d15780634ee2cd7e14610301578063587cde1e14610331576101c4565b806323b872dd116101a257806323b872dd14610235578063313ce567146102655780633644e5151461028357806339509351146102a1576101c4565b806306fdde03146101c9578063095ea7b3146101e757806318160ddd14610217575b600080fd5b6101d1610601565b6040516101de9190613905565b60405180910390f35b61020160048036038101906101fc91906131b3565b610693565b60405161020e9190613791565b60405180910390f35b61021f6106b1565b60405161022c9190613c42565b60405180910390f35b61024f600480360381019061024a91906130c6565b6106bb565b60405161025c9190613791565b60405180910390f35b61026d6107b3565b60405161027a9190613ca1565b60405180910390f35b61028b6107bc565b60405161029891906137ac565b60405180910390f35b6102bb60048036038101906102b691906131b3565b6107cb565b6040516102c89190613791565b60405180910390f35b6102eb60048036038101906102e691906131b3565b610877565b6040516102f89190613c42565b60405180910390f35b61031b600480360381019061031691906131b3565b61090b565b6040516103289190613c42565b60405180910390f35b61034b60048036038101906103469190613061565b61097b565b6040516103589190613776565b60405180910390f35b61037b60048036038101906103769190613061565b6109e4565b005b61039760048036038101906103929190613061565b6109f8565b6040516103a49190613c86565b60405180910390f35b6103c760048036038101906103c29190613061565b610a4c565b6040516103d49190613c42565b60405180910390f35b6103e5610a94565b005b61040160048036038101906103fc9190613061565b610b1c565b60405161040e9190613c42565b60405180910390f35b61041f610b6c565b60405161042c9190613776565b60405180910390f35b61044f600480360381019061044a91906132b4565b610b96565b60405161045c9190613c42565b60405180910390f35b61046d610bec565b60405161047a9190613905565b60405180910390f35b61048b610c7e565b005b6104a760048036038101906104a291906132b4565b610d05565b6040516104b49190613c42565b60405180910390f35b6104d760048036038101906104d29190613061565b610d36565b6040516104e49190613c42565b60405180910390f35b610507600480360381019061050291906131b3565b610e6d565b6040516105149190613791565b60405180910390f35b610537600480360381019061053291906131b3565b610f58565b6040516105449190613791565b60405180910390f35b610567600480360381019061056291906131ef565b610f76565b005b610583600480360381019061057e9190613115565b61107a565b005b61059f600480360381019061059a919061308a565b6111bc565b6040516105ac9190613c42565b60405180910390f35b6105cf60048036038101906105ca9190613278565b611243565b6040516105dc9190613c27565b60405180910390f35b6105ff60048036038101906105fa9190613061565b611379565b005b60606003805461061090613e68565b80601f016020809104026020016040519081016040528092919081815260200182805461063c90613e68565b80156106895780601f1061065e57610100808354040283529160200191610689565b820191906000526020600020905b81548152906001019060200180831161066c57829003601f168201915b5050505050905090565b60006106a76106a0611845565b848461184d565b6001905092915050565b6000600254905090565b60006106c8848484611a18565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610713611845565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610793576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078a90613ae7565b60405180910390fd5b6107a78561079f611845565b85840361184d565b60019150509392505050565b60006012905090565b60006107c6611c99565b905090565b600061086d6107d8611845565b8484600160006107e6611845565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546108689190613ce3565b61184d565b6001905092915050565b60004382106108bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108b290613987565b60405180910390fd5b610903600c60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002083611db3565b905092915050565b600080600061095884600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611f0b565b915091508161096f5761096a85610a4c565b610971565b805b9250505092915050565b6000600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6109f56109ef611845565b82612027565b50565b6000610a45600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805490506116df565b9050919050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610a9c611845565b73ffffffffffffffffffffffffffffffffffffffff16610aba610b6c565b73ffffffffffffffffffffffffffffffffffffffff1614610b10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0790613b27565b60405180910390fd5b610b1a6000612141565b565b6000610b65600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611837565b9050919050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000438210610bda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd190613987565b60405180910390fd5b610be5600d83611db3565b9050919050565b606060048054610bfb90613e68565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2790613e68565b8015610c745780601f10610c4957610100808354040283529160200191610c74565b820191906000526020600020905b815481529060010190602001808311610c5757829003601f168201915b5050505050905090565b610c86611845565b73ffffffffffffffffffffffffffffffffffffffff16610ca4610b6c565b73ffffffffffffffffffffffffffffffffffffffff1614610cfa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf190613b27565b60405180910390fd5b610d02612207565b50565b6000806000610d15846006611f0b565b9150915081610d2b57610d266106b1565b610d2d565b805b92505050919050565b600080600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050905060008114610e4457600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600182610dd29190613d6a565b81548110610e09577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16610e47565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b60008060016000610e7c611845565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610f39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f3090613be7565b60405180910390fd5b610f4d610f44611845565b8585840361184d565b600191505092915050565b6000610f6c610f65611845565b8484611a18565b6001905092915050565b83421115610fb9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb0906139a7565b60405180910390fd5b600061101b6110137fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf898989604051602001610ff89493929190613828565b6040516020818303038152906040528051906020012061225d565b858585612277565b9050611026816122a2565b8614611067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105e906139e7565b60405180910390fd5b6110718188612027565b50505050505050565b834211156110bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b490613a47565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008888886110ec8c6122a2565b89604051602001611102969594939291906137c7565b60405160208183030381529060405280519060200120905060006111258261225d565b9050600061113582878787612277565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119c90613ac7565b60405180910390fd5b6111b08a8a8a61184d565b50505050505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b61124b612fba565b600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106112c8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b611381611845565b73ffffffffffffffffffffffffffffffffffffffff1661139f610b6c565b73ffffffffffffffffffffffffffffffffffffffff16146113f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ec90613b27565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145c90613a07565b60405180910390fd5b61146e81612141565b50565b61147b82826114fe565b611483612300565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166114a96106b1565b11156114ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114e190613b07565b60405180910390fd5b6114f8600d61165e83612324565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561156e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161156590613c07565b60405180910390fd5b61157a6000838361260e565b806002600082825461158c9190613ce3565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546115e19190613ce3565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516116469190613c42565b60405180910390a361165a6000838361261e565b5050565b6000818361166c9190613ce3565b905092915050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff80168211156116d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ce90613b47565b60405180910390fd5b819050919050565b600063ffffffff801682111561172a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172190613b87565b60405180910390fd5b819050919050565b61173d838383611817565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156117885761177b8261262e565b611783612681565b6117e7565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156117d3576117c68361262e565b6117ce612681565b6117e6565b6117dc8361262e565b6117e58261262e565b5b5b505050565b6117f783838361181c565b6118126118038461097b565b61180c8461097b565b83612695565b505050565b505050565b505050565b6000818361182f9190613d6a565b905092915050565b600081600001549050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156118bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b490613ba7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561192d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192490613a27565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611a0b9190613c42565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7f90613b67565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611af8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aef90613967565b60405180910390fd5b611b0383838361260e565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611b89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8090613a67565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611c1c9190613ce3565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c809190613c42565b60405180910390a3611c9384848461261e565b50505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16148015611d1557507f000000000000000000000000000000000000000000000000000000000000000046145b15611d42577f00000000000000000000000000000000000000000000000000000000000000009050611db0565b611dad7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061288e565b90505b90565b6000808380549050905060005b81811015611e58576000611dd482846128c8565b905084868281548110611e10577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff161115611e4257809250611e52565b600181611e4f9190613ce3565b91505b50611dc0565b60008214611ee05784600183611e6e9190613d6a565b81548110611ea5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16611ee3565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b60008060008411611f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f4890613bc7565b60405180910390fd5b611f596128ee565b841115611f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f9290613947565b60405180910390fd5b6000611fb385856000016128ff90919063ffffffff16565b90508360000180549050811415611fd1576000809250925050612020565b600184600101828154811061200f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015492509250505b9250929050565b60006120328361097b565b9050600061203f84610a4c565b905082600b60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a461213b828483612695565b50505050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006122136008612a25565b600061221d6128ee565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb678160405161224e9190613c42565b60405180910390a18091505090565b600061227061226a611c99565b83612a3b565b9050919050565b600080600061228887878787612a6e565b9150915061229581612b7b565b8192505050949350505050565b600080600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506122ef81611837565b91506122fa81612a25565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b600080600085805490509050600081146123b857856001826123469190613d6a565b8154811061237d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166123bb565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1692506123e983858763ffffffff16565b9150600081118015612462575043866001836124059190613d6a565b8154811061243c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b156125155761247082611674565b8660018361247e9190613d6a565b815481106124b5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612605565b85604051806040016040528061252a436116df565b63ffffffff16815260200161253e85611674565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b612619838383611732565b505050565b6126298383836117ec565b505050565b61267e600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061267983610a4c565b612ecc565b50565b612693600661268e6106b1565b612ecc565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141580156126d15750600081115b1561288957600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146127af57600080612758600c60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061182185612324565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a72483836040516127a4929190613c5d565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461288857600080612831600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061165e85612324565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405161287d929190613c5d565b60405180910390a250505b5b505050565b600083838346306040516020016128a995949392919061386d565b6040516020818303038152906040528051906020012090509392505050565b600060028284186128d99190613d39565b8284166128e69190613ce3565b905092915050565b60006128fa6008611837565b905090565b600080838054905014156129165760009050612a1f565b600080848054905090505b808210156129a057600061293583836128c8565b905084868281548110612971577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154111561298a5780915061299a565b6001816129979190613ce3565b92505b50612921565b6000821180156129fe575083856001846129ba9190613d6a565b815481106129f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154145b15612a1957600182612a109190613d6a565b92505050612a1f565b81925050505b92915050565b6001816000016000828254019250508190555050565b60008282604051602001612a5092919061373f565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115612aa9576000600391509150612b72565b601b8560ff1614158015612ac15750601c8560ff1614155b15612ad3576000600491509150612b72565b600060018787878760405160008152602001604052604051612af894939291906138c0565b6020604051602081039080840390855afa158015612b1a573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612b6957600060019250925050612b72565b80600092509250505b94509492505050565b60006004811115612bb5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612bee577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612bf957612ec9565b60016004811115612c33577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612c6c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612cad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca490613927565b60405180910390fd5b60026004811115612ce7577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612d20577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612d61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d58906139c7565b60405180910390fd5b60036004811115612d9b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612dd4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612e15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e0c90613a87565b60405180910390fd5b600480811115612e4e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115612e87577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415612ec8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ebf90613aa7565b60405180910390fd5b5b50565b6000612ed66128ee565b905080612ee584600001612f47565b1015612f425782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b60008082805490501415612f5e5760009050612fb5565b8160018380549050612f709190613d6a565b81548110612fa7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490505b919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b60008135905061300781614531565b92915050565b60008135905061301c81614548565b92915050565b6000813590506130318161455f565b92915050565b60008135905061304681614576565b92915050565b60008135905061305b8161458d565b92915050565b60006020828403121561307357600080fd5b600061308184828501612ff8565b91505092915050565b6000806040838503121561309d57600080fd5b60006130ab85828601612ff8565b92505060206130bc85828601612ff8565b9150509250929050565b6000806000606084860312156130db57600080fd5b60006130e986828701612ff8565b93505060206130fa86828701612ff8565b925050604061310b86828701613022565b9150509250925092565b600080600080600080600060e0888a03121561313057600080fd5b600061313e8a828b01612ff8565b975050602061314f8a828b01612ff8565b96505060406131608a828b01613022565b95505060606131718a828b01613022565b94505060806131828a828b0161304c565b93505060a06131938a828b0161300d565b92505060c06131a48a828b0161300d565b91505092959891949750929550565b600080604083850312156131c657600080fd5b60006131d485828601612ff8565b92505060206131e585828601613022565b9150509250929050565b60008060008060008060c0878903121561320857600080fd5b600061321689828a01612ff8565b965050602061322789828a01613022565b955050604061323889828a01613022565b945050606061324989828a0161304c565b935050608061325a89828a0161300d565b92505060a061326b89828a0161300d565b9150509295509295509295565b6000806040838503121561328b57600080fd5b600061329985828601612ff8565b92505060206132aa85828601613037565b9150509250929050565b6000602082840312156132c657600080fd5b60006132d484828501613022565b91505092915050565b6132e681613d9e565b82525050565b6132f581613db0565b82525050565b61330481613dbc565b82525050565b61331b61331682613dbc565b613e9a565b82525050565b600061332c82613cbc565b6133368185613cc7565b9350613346818560208601613e35565b61334f81613f31565b840191505092915050565b6000613367601883613cc7565b915061337282613f42565b602082019050919050565b600061338a601d83613cc7565b915061339582613f6b565b602082019050919050565b60006133ad602383613cc7565b91506133b882613f94565b604082019050919050565b60006133d0601f83613cc7565b91506133db82613fe3565b602082019050919050565b60006133f3601d83613cc7565b91506133fe8261400c565b602082019050919050565b6000613416601f83613cc7565b915061342182614035565b602082019050919050565b6000613439601983613cc7565b91506134448261405e565b602082019050919050565b600061345c602683613cc7565b915061346782614087565b604082019050919050565b600061347f602283613cc7565b915061348a826140d6565b604082019050919050565b60006134a2600283613cd8565b91506134ad82614125565b600282019050919050565b60006134c5601d83613cc7565b91506134d08261414e565b602082019050919050565b60006134e8602683613cc7565b91506134f382614177565b604082019050919050565b600061350b602283613cc7565b9150613516826141c6565b604082019050919050565b600061352e602283613cc7565b915061353982614215565b604082019050919050565b6000613551601e83613cc7565b915061355c82614264565b602082019050919050565b6000613574602883613cc7565b915061357f8261428d565b604082019050919050565b6000613597603083613cc7565b91506135a2826142dc565b604082019050919050565b60006135ba602083613cc7565b91506135c58261432b565b602082019050919050565b60006135dd602783613cc7565b91506135e882614354565b604082019050919050565b6000613600602583613cc7565b915061360b826143a3565b604082019050919050565b6000613623602683613cc7565b915061362e826143f2565b604082019050919050565b6000613646602483613cc7565b915061365182614441565b604082019050919050565b6000613669601683613cc7565b915061367482614490565b602082019050919050565b600061368c602583613cc7565b9150613697826144b9565b604082019050919050565b60006136af601f83613cc7565b91506136ba82614508565b602082019050919050565b6040820160008201516136db6000850182613712565b5060208201516136ee60208501826136f4565b50505050565b6136fd81613de6565b82525050565b61370c81613e0e565b82525050565b61371b81613e18565b82525050565b61372a81613e18565b82525050565b61373981613e28565b82525050565b600061374a82613495565b9150613756828561330a565b602082019150613766828461330a565b6020820191508190509392505050565b600060208201905061378b60008301846132dd565b92915050565b60006020820190506137a660008301846132ec565b92915050565b60006020820190506137c160008301846132fb565b92915050565b600060c0820190506137dc60008301896132fb565b6137e960208301886132dd565b6137f660408301876132dd565b6138036060830186613703565b6138106080830185613703565b61381d60a0830184613703565b979650505050505050565b600060808201905061383d60008301876132fb565b61384a60208301866132dd565b6138576040830185613703565b6138646060830184613703565b95945050505050565b600060a08201905061388260008301886132fb565b61388f60208301876132fb565b61389c60408301866132fb565b6138a96060830185613703565b6138b660808301846132dd565b9695505050505050565b60006080820190506138d560008301876132fb565b6138e26020830186613730565b6138ef60408301856132fb565b6138fc60608301846132fb565b95945050505050565b6000602082019050818103600083015261391f8184613321565b905092915050565b600060208201905081810360008301526139408161335a565b9050919050565b600060208201905081810360008301526139608161337d565b9050919050565b60006020820190508181036000830152613980816133a0565b9050919050565b600060208201905081810360008301526139a0816133c3565b9050919050565b600060208201905081810360008301526139c0816133e6565b9050919050565b600060208201905081810360008301526139e081613409565b9050919050565b60006020820190508181036000830152613a008161342c565b9050919050565b60006020820190508181036000830152613a208161344f565b9050919050565b60006020820190508181036000830152613a4081613472565b9050919050565b60006020820190508181036000830152613a60816134b8565b9050919050565b60006020820190508181036000830152613a80816134db565b9050919050565b60006020820190508181036000830152613aa0816134fe565b9050919050565b60006020820190508181036000830152613ac081613521565b9050919050565b60006020820190508181036000830152613ae081613544565b9050919050565b60006020820190508181036000830152613b0081613567565b9050919050565b60006020820190508181036000830152613b208161358a565b9050919050565b60006020820190508181036000830152613b40816135ad565b9050919050565b60006020820190508181036000830152613b60816135d0565b9050919050565b60006020820190508181036000830152613b80816135f3565b9050919050565b60006020820190508181036000830152613ba081613616565b9050919050565b60006020820190508181036000830152613bc081613639565b9050919050565b60006020820190508181036000830152613be08161365c565b9050919050565b60006020820190508181036000830152613c008161367f565b9050919050565b60006020820190508181036000830152613c20816136a2565b9050919050565b6000604082019050613c3c60008301846136c5565b92915050565b6000602082019050613c576000830184613703565b92915050565b6000604082019050613c726000830185613703565b613c7f6020830184613703565b9392505050565b6000602082019050613c9b6000830184613721565b92915050565b6000602082019050613cb66000830184613730565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000613cee82613e0e565b9150613cf983613e0e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613d2e57613d2d613ea4565b5b828201905092915050565b6000613d4482613e0e565b9150613d4f83613e0e565b925082613d5f57613d5e613ed3565b5b828204905092915050565b6000613d7582613e0e565b9150613d8083613e0e565b925082821015613d9357613d92613ea4565b5b828203905092915050565b6000613da982613dc6565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b60005b83811015613e53578082015181840152602081019050613e38565b83811115613e62576000848401525b50505050565b60006002820490506001821680613e8057607f821691505b60208210811415613e9457613e93613f02565b5b50919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230536e617073686f743a206964206973203000000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b61453a81613d9e565b811461454557600080fd5b50565b61455181613dbc565b811461455c57600080fd5b50565b61456881613e0e565b811461457357600080fd5b50565b61457f81613e18565b811461458a57600080fd5b50565b61459681613e28565b81146145a157600080fd5b5056fea26469706673582212204377bfaf84ebcb29b406347a2dbd095642c53da27dc690f105c5bc60db79d21e64736f6c63430008020033

Deployed ByteCode Sourcemap

72062:1076:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40282:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42449:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41402:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43100:492;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41244:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52675:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44001:215;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56438:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68050:266;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55838:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58877:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55594:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41573:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33703:103;;;:::i;:::-;;52417:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33052:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56978:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40501:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72275:67;;;:::i;:::-;;68420:234;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56041:195;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44719:413;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41913:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59064:582;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51706:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42151:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55364:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33961:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40282:100;40336:13;40369:5;40362:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40282:100;:::o;42449:169::-;42532:4;42549:39;42558:12;:10;:12::i;:::-;42572:7;42581:6;42549:8;:39::i;:::-;42606:4;42599:11;;42449:169;;;;:::o;41402:108::-;41463:7;41490:12;;41483:19;;41402:108;:::o;43100:492::-;43240:4;43257:36;43267:6;43275:9;43286:6;43257:9;:36::i;:::-;43306:24;43333:11;:19;43345:6;43333:19;;;;;;;;;;;;;;;:33;43353:12;:10;:12::i;:::-;43333:33;;;;;;;;;;;;;;;;43306:60;;43405:6;43385:16;:26;;43377:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;43492:57;43501:6;43509:12;:10;:12::i;:::-;43542:6;43523:16;:25;43492:8;:57::i;:::-;43580:4;43573:11;;;43100:492;;;;;:::o;41244:93::-;41302:5;41327:2;41320:9;;41244:93;:::o;52675:115::-;52735:7;52762:20;:18;:20::i;:::-;52755:27;;52675:115;:::o;44001:215::-;44089:4;44106:80;44115:12;:10;:12::i;:::-;44129:7;44175:10;44138:11;:25;44150:12;:10;:12::i;:::-;44138:25;;;;;;;;;;;;;;;:34;44164:7;44138:34;;;;;;;;;;;;;;;;:47;;;;:::i;:::-;44106:8;:80::i;:::-;44204:4;44197:11;;44001:215;;;;:::o;56438:251::-;56519:7;56561:12;56547:11;:26;56539:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;56627:54;56646:12;:21;56659:7;56646:21;;;;;;;;;;;;;;;56669:11;56627:18;:54::i;:::-;56620:61;;56438:251;;;;:::o;68050:266::-;68137:7;68158:16;68176:13;68193:55;68202:10;68214:24;:33;68239:7;68214:33;;;;;;;;;;;;;;;68193:8;:55::i;:::-;68157:91;;;;68268:11;:40;;68290:18;68300:7;68290:9;:18::i;:::-;68268:40;;;68282:5;68268:40;68261:47;;;;68050:266;;;;:::o;55838:119::-;55903:7;55930:10;:19;55941:7;55930:19;;;;;;;;;;;;;;;;;;;;;;;;;55923:26;;55838:119;;;:::o;58877:105::-;58940:34;58950:12;:10;:12::i;:::-;58964:9;58940;:34::i;:::-;58877:105;:::o;55594:151::-;55664:6;55690:47;55708:12;:21;55721:7;55708:21;;;;;;;;;;;;;;;:28;;;;55690:17;:47::i;:::-;55683:54;;55594:151;;;:::o;41573:127::-;41647:7;41674:9;:18;41684:7;41674:18;;;;;;;;;;;;;;;;41667:25;;41573:127;;;:::o;33703:103::-;33283:12;:10;:12::i;:::-;33272:23;;:7;:5;:7::i;:::-;:23;;;33264:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;33768:30:::1;33795:1;33768:18;:30::i;:::-;33703:103::o:0;52417:128::-;52486:7;52513:24;:7;:14;52521:5;52513:14;;;;;;;;;;;;;;;:22;:24::i;:::-;52506:31;;52417:128;;;:::o;33052:87::-;33098:7;33125:6;;;;;;;;;;;33118:13;;33052:87;:::o;56978:242::-;57048:7;57090:12;57076:11;:26;57068:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;57156:56;57175:23;57200:11;57156:18;:56::i;:::-;57149:63;;56978:242;;;:::o;40501:104::-;40557:13;40590:7;40583:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40501:104;:::o;72275:67::-;33283:12;:10;:12::i;:::-;33272:23;;:7;:5;:7::i;:::-;:23;;;33264:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;72323:11:::1;:9;:11::i;:::-;;72275:67::o:0;68420:234::-;68492:7;68513:16;68531:13;68548:43;68557:10;68569:21;68548:8;:43::i;:::-;68512:79;;;;68611:11;:35;;68633:13;:11;:13::i;:::-;68611:35;;;68625:5;68611:35;68604:42;;;;68420:234;;;:::o;56041:195::-;56097:7;56117:11;56131:12;:21;56144:7;56131:21;;;;;;;;;;;;;;;:28;;;;56117:42;;56184:1;56177:3;:8;:51;;56192:12;:21;56205:7;56192:21;;;;;;;;;;;;;;;56220:1;56214:3;:7;;;;:::i;:::-;56192:30;;;;;;;;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;56177:51;;;56188:1;56177:51;56170:58;;;;;56041:195;;;:::o;44719:413::-;44812:4;44829:24;44856:11;:25;44868:12;:10;:12::i;:::-;44856:25;;;;;;;;;;;;;;;:34;44882:7;44856:34;;;;;;;;;;;;;;;;44829:61;;44929:15;44909:16;:35;;44901:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;45022:67;45031:12;:10;:12::i;:::-;45045:7;45073:15;45054:16;:34;45022:8;:67::i;:::-;45120:4;45113:11;;;44719:413;;;;:::o;41913:175::-;41999:4;42016:42;42026:12;:10;:12::i;:::-;42040:9;42051:6;42016:9;:42::i;:::-;42076:4;42069:11;;41913:175;;;;:::o;59064:582::-;59282:6;59263:15;:25;;59255:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;59333:14;59350:174;59378:87;54615:71;59438:9;59449:5;59456:6;59405:58;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59395:69;;;;;;59378:16;:87::i;:::-;59480:1;59496;59512;59350:13;:174::i;:::-;59333:191;;59552:17;59562:6;59552:9;:17::i;:::-;59543:5;:26;59535:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;59610:28;59620:6;59628:9;59610;:28::i;:::-;59064:582;;;;;;;:::o;51706:645::-;51950:8;51931:15;:27;;51923:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;52005:18;52047:16;52065:5;52072:7;52081:5;52088:16;52098:5;52088:9;:16::i;:::-;52106:8;52036:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;52026:90;;;;;;52005:111;;52129:12;52144:28;52161:10;52144:16;:28::i;:::-;52129:43;;52185:14;52202:28;52216:4;52222:1;52225;52228;52202:13;:28::i;:::-;52185:45;;52259:5;52249:15;;:6;:15;;;52241:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;52312:31;52321:5;52328:7;52337:5;52312:8;:31::i;:::-;51706:645;;;;;;;;;;:::o;42151:151::-;42240:7;42267:11;:18;42279:5;42267:18;;;;;;;;;;;;;;;:27;42286:7;42267:27;;;;;;;;;;;;;;;;42260:34;;42151:151;;;;:::o;55364:150::-;55443:17;;:::i;:::-;55480:12;:21;55493:7;55480:21;;;;;;;;;;;;;;;55502:3;55480:26;;;;;;;;;;;;;;;;;;;;;;;;;55473:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55364:150;;;;:::o;33961:201::-;33283:12;:10;:12::i;:::-;33272:23;;:7;:5;:7::i;:::-;:23;;;33264:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;34070:1:::1;34050:22;;:8;:22;;;;34042:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;34126:28;34145:8;34126:18;:28::i;:::-;33961:201:::0;:::o;59952:290::-;60037:28;60049:7;60058:6;60037:11;:28::i;:::-;60101:12;:10;:12::i;:::-;60084:29;;:13;:11;:13::i;:::-;:29;;60076:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;60179:55;60196:23;60221:4;60227:6;60179:16;:55::i;:::-;;;59952:290;;:::o;46642:399::-;46745:1;46726:21;;:7;:21;;;;46718:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;46796:49;46825:1;46829:7;46838:6;46796:20;:49::i;:::-;46874:6;46858:12;;:22;;;;;;;:::i;:::-;;;;;;;;46913:6;46891:9;:18;46901:7;46891:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;46956:7;46935:37;;46952:1;46935:37;;;46965:6;46935:37;;;;;;:::i;:::-;;;;;;;;46985:48;47013:1;47017:7;47026:6;46985:19;:48::i;:::-;46642:399;;:::o;62796:98::-;62854:7;62885:1;62881;:5;;;;:::i;:::-;62874:12;;62796:98;;;;:::o;1195:195::-;1252:7;1289:17;1280:26;;:5;:26;;1272:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;1376:5;1361:21;;1195:195;;;:::o;3165:190::-;3221:6;3257:16;3248:25;;:5;:25;;3240:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;3341:5;3327:20;;3165:190;;;:::o;68871:622::-;69014:44;69041:4;69047:2;69051:6;69014:26;:44::i;:::-;69091:1;69075:18;;:4;:18;;;69071:415;;;69131:26;69154:2;69131:22;:26::i;:::-;69172:28;:26;:28::i;:::-;69071:415;;;69236:1;69222:16;;:2;:16;;;69218:268;;;69276:28;69299:4;69276:22;:28::i;:::-;69319;:26;:28::i;:::-;69218:268;;;69405:28;69428:4;69405:22;:28::i;:::-;69448:26;69471:2;69448:22;:26::i;:::-;69218:268;69071:415;68871:622;;;:::o;60670:262::-;60812:43;60838:4;60844:2;60848:6;60812:25;:43::i;:::-;60868:56;60885:15;60895:4;60885:9;:15::i;:::-;60902:13;60912:2;60902:9;:13::i;:::-;60917:6;60868:16;:56::i;:::-;60670:262;;;:::o;49383:125::-;;;;:::o;50112:124::-;;;;:::o;62902:103::-;62965:7;62996:1;62992;:5;;;;:::i;:::-;62985:12;;62902:103;;;;:::o;27648:114::-;27713:7;27740;:14;;;27733:21;;27648:114;;;:::o;31776:98::-;31829:7;31856:10;31849:17;;31776:98;:::o;48403:380::-;48556:1;48539:19;;:5;:19;;;;48531:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;48637:1;48618:21;;:7;:21;;;;48610:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;48721:6;48691:11;:18;48703:5;48691:18;;;;;;;;;;;;;;;:27;48710:7;48691:27;;;;;;;;;;;;;;;:36;;;;48759:7;48743:32;;48752:5;48743:32;;;48768:6;48743:32;;;;;;:::i;:::-;;;;;;;;48403:380;;;:::o;45622:733::-;45780:1;45762:20;;:6;:20;;;;45754:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;45864:1;45843:23;;:9;:23;;;;45835:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;45919:47;45940:6;45948:9;45959:6;45919:20;:47::i;:::-;45979:21;46003:9;:17;46013:6;46003:17;;;;;;;;;;;;;;;;45979:41;;46056:6;46039:13;:23;;46031:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;46177:6;46161:13;:22;46141:9;:17;46151:6;46141:17;;;;;;;;;;;;;;;:42;;;;46229:6;46205:9;:20;46215:9;46205:20;;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;46270:9;46253:35;;46262:6;46253:35;;;46281:6;46253:35;;;;;;:::i;:::-;;;;;;;;46301:46;46321:6;46329:9;46340:6;46301:19;:46::i;:::-;45622:733;;;;:::o;23010:314::-;23063:7;23104:12;23087:29;;23095:4;23087:29;;;:66;;;;;23137:16;23120:13;:33;23087:66;23083:234;;;23177:24;23170:31;;;;23083:234;23241:64;23263:10;23275:12;23289:15;23241:21;:64::i;:::-;23234:71;;23010:314;;:::o;57309:1482::-;57408:7;58427:12;58442:5;:12;;;;58427:27;;58465:11;58491:236;58504:4;58498:3;:10;58491:236;;;58525:11;58539:23;58552:3;58557:4;58539:12;:23::i;:::-;58525:37;;58604:11;58581:5;58587:3;58581:10;;;;;;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;:34;;;58577:139;;;58643:3;58636:10;;58577:139;;;58699:1;58693:3;:7;;;;:::i;:::-;58687:13;;58577:139;58491:236;;;;58754:1;58746:4;:9;:37;;58762:5;58775:1;58768:4;:8;;;;:::i;:::-;58762:15;;;;;;;;;;;;;;;;;;;;;;;:21;;;;;;;;;;;;58746:37;;;58758:1;58746:37;58739:44;;;;;;57309:1482;;;;:::o;69501:1619::-;69590:4;69596:7;69637:1;69624:10;:14;69616:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;69698:23;:21;:23::i;:::-;69684:10;:37;;69676:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;70894:13;70910:40;70939:10;70910:9;:13;;:28;;:40;;;;:::i;:::-;70894:56;;70976:9;:13;;:20;;;;70967:5;:29;70963:150;;;71021:5;71028:1;71013:17;;;;;;;70963:150;71071:4;71077:9;:16;;71094:5;71077:23;;;;;;;;;;;;;;;;;;;;;;;;71063:38;;;;;69501:1619;;;;;;:::o;61096:388::-;61181:23;61207:20;61217:9;61207;:20::i;:::-;61181:46;;61238:24;61265:20;61275:9;61265;:20::i;:::-;61238:47;;61320:9;61296:10;:21;61307:9;61296:21;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;61391:9;61347:54;;61374:15;61347:54;;61363:9;61347:54;;;;;;;;;;;;61414:62;61431:15;61448:9;61459:16;61414;:62::i;:::-;61096:388;;;;:::o;34322:191::-;34396:16;34415:6;;;;;;;;;;;34396:25;;34441:8;34432:6;;:17;;;;;;;;;;;;;;;;;;34496:8;34465:40;;34486:8;34465:40;;;;;;;;;;;;34322:191;;:::o;67522:223::-;67569:7;67589:30;:18;:28;:30::i;:::-;67632:17;67652:23;:21;:23::i;:::-;67632:43;;67691:19;67700:9;67691:19;;;;;;:::i;:::-;;;;;;;;67728:9;67721:16;;;67522:223;:::o;24237:167::-;24314:7;24341:55;24363:20;:18;:20::i;:::-;24385:10;24341:21;:55::i;:::-;24334:62;;24237:167;;;:::o;17886:279::-;18014:7;18035:17;18054:18;18076:25;18087:4;18093:1;18096;18099;18076:10;:25::i;:::-;18034:67;;;;18112:18;18124:5;18112:11;:18::i;:::-;18148:9;18141:16;;;;17886:279;;;;;;:::o;52928:207::-;52988:15;53016:30;53049:7;:14;53057:5;53049:14;;;;;;;;;;;;;;;53016:47;;53084:15;:5;:13;:15::i;:::-;53074:25;;53110:17;:5;:15;:17::i;:::-;52928:207;;;;:::o;59753:105::-;59806:7;59833:17;59826:24;;59753:105;:::o;62143:645::-;62317:17;62336;62366:11;62380:5;:12;;;;62366:26;;62422:1;62415:3;:8;:35;;62430:5;62442:1;62436:3;:7;;;;:::i;:::-;62430:14;;;;;;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;62415:35;;;62426:1;62415:35;62403:47;;;;62473:20;62476:9;62487:5;62473:2;:20;;:::i;:::-;62461:32;;62516:1;62510:3;:7;:51;;;;;62549:12;62521:5;62533:1;62527:3;:7;;;;:::i;:::-;62521:14;;;;;;;;;;;;;;;;;;;;;;;:24;;;;;;;;;;;;:40;;;62510:51;62506:275;;;62601:29;62620:9;62601:18;:29::i;:::-;62578:5;62590:1;62584:3;:7;;;;:::i;:::-;62578:14;;;;;;;;;;;;;;;;;;;;;;;:20;;;:52;;;;;;;;;;;;;;;;;;62506:275;;;62663:5;62674:94;;;;;;;;62697:31;62715:12;62697:17;:31::i;:::-;62674:94;;;;;;62737:29;62756:9;62737:18;:29::i;:::-;62674:94;;;;;62663:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62506:275;62143:645;;;;;;;:::o;72420:198::-;72566:44;72593:4;72599:2;72603:6;72566:26;:44::i;:::-;72420:198;;;:::o;72626:193::-;72768:43;72794:4;72800:2;72804:6;72768:25;:43::i;:::-;72626:193;;;:::o;71128:146::-;71196:70;71212:24;:33;71237:7;71212:33;;;;;;;;;;;;;;;71247:18;71257:7;71247:9;:18::i;:::-;71196:15;:70::i;:::-;71128:146;:::o;71282:118::-;71339:53;71355:21;71378:13;:11;:13::i;:::-;71339:15;:53::i;:::-;71282:118::o;61492:643::-;61624:3;61617:10;;:3;:10;;;;:24;;;;;61640:1;61631:6;:10;61617:24;61613:515;;;61677:1;61662:17;;:3;:17;;;61658:224;;61701:17;61720;61741:54;61758:12;:17;61771:3;61758:17;;;;;;;;;;;;;;;61777:9;61788:6;61741:16;:54::i;:::-;61700:95;;;;61840:3;61819:47;;;61845:9;61856;61819:47;;;;;;;:::i;:::-;;;;;;;;61658:224;;;61917:1;61902:17;;:3;:17;;;61898:219;;61941:17;61960;61981:49;61998:12;:17;62011:3;61998:17;;;;;;;;;;;;;;;62017:4;62023:6;61981:16;:49::i;:::-;61940:90;;;;62075:3;62054:47;;;62080:9;62091;62054:47;;;;;;;:::i;:::-;;;;;;;;61898:219;;;61613:515;61492:643;;;:::o;23332:263::-;23476:7;23524:8;23534;23544:11;23557:13;23580:4;23513:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;23503:84;;;;;;23496:91;;23332:263;;;;;:::o;28956:156::-;29018:7;29103:1;29098;29094;:5;29093:11;;;;:::i;:::-;29088:1;29084;:5;29083:21;;;;:::i;:::-;29076:28;;28956:156;;;;:::o;67811:127::-;67875:7;67902:28;:18;:26;:28::i;:::-;67895:35;;67811:127;:::o;30172:918::-;30261:7;30301:1;30285:5;:12;;;;:17;30281:58;;;30326:1;30319:8;;;;30281:58;30351:11;30377:12;30392:5;:12;;;;30377:27;;30417:424;30430:4;30424:3;:10;30417:424;;;30451:11;30465:23;30478:3;30483:4;30465:12;:23::i;:::-;30451:37;;30722:7;30709:5;30715:3;30709:10;;;;;;;;;;;;;;;;;;;;;;;;:20;30705:125;;;30757:3;30750:10;;30705:125;;;30813:1;30807:3;:7;;;;:::i;:::-;30801:13;;30705:125;30417:424;;;;30967:1;30961:3;:7;:36;;;;;30990:7;30972:5;30984:1;30978:3;:7;;;;:::i;:::-;30972:14;;;;;;;;;;;;;;;;;;;;;;;;:25;30961:36;30957:126;;;31027:1;31021:3;:7;;;;:::i;:::-;31014:14;;;;;;30957:126;31068:3;31061:10;;;;30172:918;;;;;:::o;27770:127::-;27877:1;27859:7;:14;;;:19;;;;;;;;;;;27770:127;:::o;19577:196::-;19670:7;19736:15;19753:10;19707:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;19697:68;;;;;;19690:75;;19577:196;;;;:::o;16115:1632::-;16246:7;16255:12;17180:66;17175:1;17167:10;;:79;17163:163;;;17279:1;17283:30;17263:51;;;;;;17163:163;17345:2;17340:1;:7;;;;:18;;;;;17356:2;17351:1;:7;;;;17340:18;17336:102;;;17391:1;17395:30;17375:51;;;;;;17336:102;17535:14;17552:24;17562:4;17568:1;17571;17574;17552:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17535:41;;17609:1;17591:20;;:6;:20;;;17587:103;;;17644:1;17648:29;17628:50;;;;;;;17587:103;17710:6;17718:20;17702:37;;;;;16115:1632;;;;;;;;:::o;10777:643::-;10855:20;10846:29;;;;;;;;;;;;;;;;:5;:29;;;;;;;;;;;;;;;;;10842:571;;;10892:7;;10842:571;10953:29;10944:38;;;;;;;;;;;;;;;;:5;:38;;;;;;;;;;;;;;;;;10940:473;;;10999:34;;;;;;;;;;:::i;:::-;;;;;;;;10940:473;11064:35;11055:44;;;;;;;;;;;;;;;;:5;:44;;;;;;;;;;;;;;;;;11051:362;;;11116:41;;;;;;;;;;:::i;:::-;;;;;;;;11051:362;11188:30;11179:39;;;;;;;;;;;;;;;;:5;:39;;;;;;;;;;;;;;;;;11175:238;;;11235:44;;;;;;;;;;:::i;:::-;;;;;;;;11175:238;11310:30;11301:39;;;;;;;;;;;;;;;;:5;:39;;;;;;;;;;;;;;;;;11297:116;;;11357:44;;;;;;;;;;:::i;:::-;;;;;;;;11297:116;10777:643;;:::o;71408:310::-;71503:17;71523:23;:21;:23::i;:::-;71503:43;;71594:9;71561:30;71577:9;:13;;71561:15;:30::i;:::-;:42;71557:154;;;71620:9;:13;;71639:9;71620:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71664:9;:16;;71686:12;71664:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71557:154;71408:310;;;:::o;71726:212::-;71796:7;71834:1;71820:3;:10;;;;:15;71816:115;;;71859:1;71852:8;;;;71816:115;71900:3;71917:1;71904:3;:10;;;;:14;;;;:::i;:::-;71900:19;;;;;;;;;;;;;;;;;;;;;;;;71893:26;;71726:212;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;:::o;7:139:1:-;;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:139::-;;236:6;223:20;214:29;;252:33;279:5;252:33;:::i;:::-;204:87;;;;:::o;297:139::-;;381:6;368:20;359:29;;397:33;424:5;397:33;:::i;:::-;349:87;;;;:::o;442:137::-;;525:6;512:20;503:29;;541:32;567:5;541:32;:::i;:::-;493:86;;;;:::o;585:135::-;;667:6;654:20;645:29;;683:31;708:5;683:31;:::i;:::-;635:85;;;;:::o;726:262::-;;834:2;822:9;813:7;809:23;805:32;802:2;;;850:1;847;840:12;802:2;893:1;918:53;963:7;954:6;943:9;939:22;918:53;:::i;:::-;908:63;;864:117;792:196;;;;:::o;994:407::-;;;1119:2;1107:9;1098:7;1094:23;1090:32;1087:2;;;1135:1;1132;1125:12;1087:2;1178:1;1203:53;1248:7;1239:6;1228:9;1224:22;1203:53;:::i;:::-;1193:63;;1149:117;1305:2;1331:53;1376:7;1367:6;1356:9;1352:22;1331:53;:::i;:::-;1321:63;;1276:118;1077:324;;;;;:::o;1407:552::-;;;;1549:2;1537:9;1528:7;1524:23;1520:32;1517:2;;;1565:1;1562;1555:12;1517:2;1608:1;1633:53;1678:7;1669:6;1658:9;1654:22;1633:53;:::i;:::-;1623:63;;1579:117;1735:2;1761:53;1806:7;1797:6;1786:9;1782:22;1761:53;:::i;:::-;1751:63;;1706:118;1863:2;1889:53;1934:7;1925:6;1914:9;1910:22;1889:53;:::i;:::-;1879:63;;1834:118;1507:452;;;;;:::o;1965:1132::-;;;;;;;;2173:3;2161:9;2152:7;2148:23;2144:33;2141:2;;;2190:1;2187;2180:12;2141:2;2233:1;2258:53;2303:7;2294:6;2283:9;2279:22;2258:53;:::i;:::-;2248:63;;2204:117;2360:2;2386:53;2431:7;2422:6;2411:9;2407:22;2386:53;:::i;:::-;2376:63;;2331:118;2488:2;2514:53;2559:7;2550:6;2539:9;2535:22;2514:53;:::i;:::-;2504:63;;2459:118;2616:2;2642:53;2687:7;2678:6;2667:9;2663:22;2642:53;:::i;:::-;2632:63;;2587:118;2744:3;2771:51;2814:7;2805:6;2794:9;2790:22;2771:51;:::i;:::-;2761:61;;2715:117;2871:3;2898:53;2943:7;2934:6;2923:9;2919:22;2898:53;:::i;:::-;2888:63;;2842:119;3000:3;3027:53;3072:7;3063:6;3052:9;3048:22;3027:53;:::i;:::-;3017:63;;2971:119;2131:966;;;;;;;;;;:::o;3103:407::-;;;3228:2;3216:9;3207:7;3203:23;3199:32;3196:2;;;3244:1;3241;3234:12;3196:2;3287:1;3312:53;3357:7;3348:6;3337:9;3333:22;3312:53;:::i;:::-;3302:63;;3258:117;3414:2;3440:53;3485:7;3476:6;3465:9;3461:22;3440:53;:::i;:::-;3430:63;;3385:118;3186:324;;;;;:::o;3516:986::-;;;;;;;3707:3;3695:9;3686:7;3682:23;3678:33;3675:2;;;3724:1;3721;3714:12;3675:2;3767:1;3792:53;3837:7;3828:6;3817:9;3813:22;3792:53;:::i;:::-;3782:63;;3738:117;3894:2;3920:53;3965:7;3956:6;3945:9;3941:22;3920:53;:::i;:::-;3910:63;;3865:118;4022:2;4048:53;4093:7;4084:6;4073:9;4069:22;4048:53;:::i;:::-;4038:63;;3993:118;4150:2;4176:51;4219:7;4210:6;4199:9;4195:22;4176:51;:::i;:::-;4166:61;;4121:116;4276:3;4303:53;4348:7;4339:6;4328:9;4324:22;4303:53;:::i;:::-;4293:63;;4247:119;4405:3;4432:53;4477:7;4468:6;4457:9;4453:22;4432:53;:::i;:::-;4422:63;;4376:119;3665:837;;;;;;;;:::o;4508:405::-;;;4632:2;4620:9;4611:7;4607:23;4603:32;4600:2;;;4648:1;4645;4638:12;4600:2;4691:1;4716:53;4761:7;4752:6;4741:9;4737:22;4716:53;:::i;:::-;4706:63;;4662:117;4818:2;4844:52;4888:7;4879:6;4868:9;4864:22;4844:52;:::i;:::-;4834:62;;4789:117;4590:323;;;;;:::o;4919:262::-;;5027:2;5015:9;5006:7;5002:23;4998:32;4995:2;;;5043:1;5040;5033:12;4995:2;5086:1;5111:53;5156:7;5147:6;5136:9;5132:22;5111:53;:::i;:::-;5101:63;;5057:117;4985:196;;;;:::o;5187:118::-;5274:24;5292:5;5274:24;:::i;:::-;5269:3;5262:37;5252:53;;:::o;5311:109::-;5392:21;5407:5;5392:21;:::i;:::-;5387:3;5380:34;5370:50;;:::o;5426:118::-;5513:24;5531:5;5513:24;:::i;:::-;5508:3;5501:37;5491:53;;:::o;5550:157::-;5655:45;5675:24;5693:5;5675:24;:::i;:::-;5655:45;:::i;:::-;5650:3;5643:58;5633:74;;:::o;5713:364::-;;5829:39;5862:5;5829:39;:::i;:::-;5884:71;5948:6;5943:3;5884:71;:::i;:::-;5877:78;;5964:52;6009:6;6004:3;5997:4;5990:5;5986:16;5964:52;:::i;:::-;6041:29;6063:6;6041:29;:::i;:::-;6036:3;6032:39;6025:46;;5805:272;;;;;:::o;6083:366::-;;6246:67;6310:2;6305:3;6246:67;:::i;:::-;6239:74;;6322:93;6411:3;6322:93;:::i;:::-;6440:2;6435:3;6431:12;6424:19;;6229:220;;;:::o;6455:366::-;;6618:67;6682:2;6677:3;6618:67;:::i;:::-;6611:74;;6694:93;6783:3;6694:93;:::i;:::-;6812:2;6807:3;6803:12;6796:19;;6601:220;;;:::o;6827:366::-;;6990:67;7054:2;7049:3;6990:67;:::i;:::-;6983:74;;7066:93;7155:3;7066:93;:::i;:::-;7184:2;7179:3;7175:12;7168:19;;6973:220;;;:::o;7199:366::-;;7362:67;7426:2;7421:3;7362:67;:::i;:::-;7355:74;;7438:93;7527:3;7438:93;:::i;:::-;7556:2;7551:3;7547:12;7540:19;;7345:220;;;:::o;7571:366::-;;7734:67;7798:2;7793:3;7734:67;:::i;:::-;7727:74;;7810:93;7899:3;7810:93;:::i;:::-;7928:2;7923:3;7919:12;7912:19;;7717:220;;;:::o;7943:366::-;;8106:67;8170:2;8165:3;8106:67;:::i;:::-;8099:74;;8182:93;8271:3;8182:93;:::i;:::-;8300:2;8295:3;8291:12;8284:19;;8089:220;;;:::o;8315:366::-;;8478:67;8542:2;8537:3;8478:67;:::i;:::-;8471:74;;8554:93;8643:3;8554:93;:::i;:::-;8672:2;8667:3;8663:12;8656:19;;8461:220;;;:::o;8687:366::-;;8850:67;8914:2;8909:3;8850:67;:::i;:::-;8843:74;;8926:93;9015:3;8926:93;:::i;:::-;9044:2;9039:3;9035:12;9028:19;;8833:220;;;:::o;9059:366::-;;9222:67;9286:2;9281:3;9222:67;:::i;:::-;9215:74;;9298:93;9387:3;9298:93;:::i;:::-;9416:2;9411:3;9407:12;9400:19;;9205:220;;;:::o;9431:400::-;;9612:84;9694:1;9689:3;9612:84;:::i;:::-;9605:91;;9705:93;9794:3;9705:93;:::i;:::-;9823:1;9818:3;9814:11;9807:18;;9595:236;;;:::o;9837:366::-;;10000:67;10064:2;10059:3;10000:67;:::i;:::-;9993:74;;10076:93;10165:3;10076:93;:::i;:::-;10194:2;10189:3;10185:12;10178:19;;9983:220;;;:::o;10209:366::-;;10372:67;10436:2;10431:3;10372:67;:::i;:::-;10365:74;;10448:93;10537:3;10448:93;:::i;:::-;10566:2;10561:3;10557:12;10550:19;;10355:220;;;:::o;10581:366::-;;10744:67;10808:2;10803:3;10744:67;:::i;:::-;10737:74;;10820:93;10909:3;10820:93;:::i;:::-;10938:2;10933:3;10929:12;10922:19;;10727:220;;;:::o;10953:366::-;;11116:67;11180:2;11175:3;11116:67;:::i;:::-;11109:74;;11192:93;11281:3;11192:93;:::i;:::-;11310:2;11305:3;11301:12;11294:19;;11099:220;;;:::o;11325:366::-;;11488:67;11552:2;11547:3;11488:67;:::i;:::-;11481:74;;11564:93;11653:3;11564:93;:::i;:::-;11682:2;11677:3;11673:12;11666:19;;11471:220;;;:::o;11697:366::-;;11860:67;11924:2;11919:3;11860:67;:::i;:::-;11853:74;;11936:93;12025:3;11936:93;:::i;:::-;12054:2;12049:3;12045:12;12038:19;;11843:220;;;:::o;12069:366::-;;12232:67;12296:2;12291:3;12232:67;:::i;:::-;12225:74;;12308:93;12397:3;12308:93;:::i;:::-;12426:2;12421:3;12417:12;12410:19;;12215:220;;;:::o;12441:366::-;;12604:67;12668:2;12663:3;12604:67;:::i;:::-;12597:74;;12680:93;12769:3;12680:93;:::i;:::-;12798:2;12793:3;12789:12;12782:19;;12587:220;;;:::o;12813:366::-;;12976:67;13040:2;13035:3;12976:67;:::i;:::-;12969:74;;13052:93;13141:3;13052:93;:::i;:::-;13170:2;13165:3;13161:12;13154:19;;12959:220;;;:::o;13185:366::-;;13348:67;13412:2;13407:3;13348:67;:::i;:::-;13341:74;;13424:93;13513:3;13424:93;:::i;:::-;13542:2;13537:3;13533:12;13526:19;;13331:220;;;:::o;13557:366::-;;13720:67;13784:2;13779:3;13720:67;:::i;:::-;13713:74;;13796:93;13885:3;13796:93;:::i;:::-;13914:2;13909:3;13905:12;13898:19;;13703:220;;;:::o;13929:366::-;;14092:67;14156:2;14151:3;14092:67;:::i;:::-;14085:74;;14168:93;14257:3;14168:93;:::i;:::-;14286:2;14281:3;14277:12;14270:19;;14075:220;;;:::o;14301:366::-;;14464:67;14528:2;14523:3;14464:67;:::i;:::-;14457:74;;14540:93;14629:3;14540:93;:::i;:::-;14658:2;14653:3;14649:12;14642:19;;14447:220;;;:::o;14673:366::-;;14836:67;14900:2;14895:3;14836:67;:::i;:::-;14829:74;;14912:93;15001:3;14912:93;:::i;:::-;15030:2;15025:3;15021:12;15014:19;;14819:220;;;:::o;15045:366::-;;15208:67;15272:2;15267:3;15208:67;:::i;:::-;15201:74;;15284:93;15373:3;15284:93;:::i;:::-;15402:2;15397:3;15393:12;15386:19;;15191:220;;;:::o;15485:517::-;15638:4;15633:3;15629:14;15730:4;15723:5;15719:16;15713:23;15749:61;15804:4;15799:3;15795:14;15781:12;15749:61;:::i;:::-;15653:167;15903:4;15896:5;15892:16;15886:23;15922:63;15979:4;15974:3;15970:14;15956:12;15922:63;:::i;:::-;15830:165;15607:395;;;:::o;16008:108::-;16085:24;16103:5;16085:24;:::i;:::-;16080:3;16073:37;16063:53;;:::o;16122:118::-;16209:24;16227:5;16209:24;:::i;:::-;16204:3;16197:37;16187:53;;:::o;16246:105::-;16321:23;16338:5;16321:23;:::i;:::-;16316:3;16309:36;16299:52;;:::o;16357:115::-;16442:23;16459:5;16442:23;:::i;:::-;16437:3;16430:36;16420:52;;:::o;16478:112::-;16561:22;16577:5;16561:22;:::i;:::-;16556:3;16549:35;16539:51;;:::o;16596:663::-;;16859:148;17003:3;16859:148;:::i;:::-;16852:155;;17017:75;17088:3;17079:6;17017:75;:::i;:::-;17117:2;17112:3;17108:12;17101:19;;17130:75;17201:3;17192:6;17130:75;:::i;:::-;17230:2;17225:3;17221:12;17214:19;;17250:3;17243:10;;16841:418;;;;;:::o;17265:222::-;;17396:2;17385:9;17381:18;17373:26;;17409:71;17477:1;17466:9;17462:17;17453:6;17409:71;:::i;:::-;17363:124;;;;:::o;17493:210::-;;17618:2;17607:9;17603:18;17595:26;;17631:65;17693:1;17682:9;17678:17;17669:6;17631:65;:::i;:::-;17585:118;;;;:::o;17709:222::-;;17840:2;17829:9;17825:18;17817:26;;17853:71;17921:1;17910:9;17906:17;17897:6;17853:71;:::i;:::-;17807:124;;;;:::o;17937:775::-;;18208:3;18197:9;18193:19;18185:27;;18222:71;18290:1;18279:9;18275:17;18266:6;18222:71;:::i;:::-;18303:72;18371:2;18360:9;18356:18;18347:6;18303:72;:::i;:::-;18385;18453:2;18442:9;18438:18;18429:6;18385:72;:::i;:::-;18467;18535:2;18524:9;18520:18;18511:6;18467:72;:::i;:::-;18549:73;18617:3;18606:9;18602:19;18593:6;18549:73;:::i;:::-;18632;18700:3;18689:9;18685:19;18676:6;18632:73;:::i;:::-;18175:537;;;;;;;;;:::o;18718:553::-;;18933:3;18922:9;18918:19;18910:27;;18947:71;19015:1;19004:9;19000:17;18991:6;18947:71;:::i;:::-;19028:72;19096:2;19085:9;19081:18;19072:6;19028:72;:::i;:::-;19110;19178:2;19167:9;19163:18;19154:6;19110:72;:::i;:::-;19192;19260:2;19249:9;19245:18;19236:6;19192:72;:::i;:::-;18900:371;;;;;;;:::o;19277:664::-;;19520:3;19509:9;19505:19;19497:27;;19534:71;19602:1;19591:9;19587:17;19578:6;19534:71;:::i;:::-;19615:72;19683:2;19672:9;19668:18;19659:6;19615:72;:::i;:::-;19697;19765:2;19754:9;19750:18;19741:6;19697:72;:::i;:::-;19779;19847:2;19836:9;19832:18;19823:6;19779:72;:::i;:::-;19861:73;19929:3;19918:9;19914:19;19905:6;19861:73;:::i;:::-;19487:454;;;;;;;;:::o;19947:545::-;;20158:3;20147:9;20143:19;20135:27;;20172:71;20240:1;20229:9;20225:17;20216:6;20172:71;:::i;:::-;20253:68;20317:2;20306:9;20302:18;20293:6;20253:68;:::i;:::-;20331:72;20399:2;20388:9;20384:18;20375:6;20331:72;:::i;:::-;20413;20481:2;20470:9;20466:18;20457:6;20413:72;:::i;:::-;20125:367;;;;;;;:::o;20498:313::-;;20649:2;20638:9;20634:18;20626:26;;20698:9;20692:4;20688:20;20684:1;20673:9;20669:17;20662:47;20726:78;20799:4;20790:6;20726:78;:::i;:::-;20718:86;;20616:195;;;;:::o;20817:419::-;;21021:2;21010:9;21006:18;20998:26;;21070:9;21064:4;21060:20;21056:1;21045:9;21041:17;21034:47;21098:131;21224:4;21098:131;:::i;:::-;21090:139;;20988:248;;;:::o;21242:419::-;;21446:2;21435:9;21431:18;21423:26;;21495:9;21489:4;21485:20;21481:1;21470:9;21466:17;21459:47;21523:131;21649:4;21523:131;:::i;:::-;21515:139;;21413:248;;;:::o;21667:419::-;;21871:2;21860:9;21856:18;21848:26;;21920:9;21914:4;21910:20;21906:1;21895:9;21891:17;21884:47;21948:131;22074:4;21948:131;:::i;:::-;21940:139;;21838:248;;;:::o;22092:419::-;;22296:2;22285:9;22281:18;22273:26;;22345:9;22339:4;22335:20;22331:1;22320:9;22316:17;22309:47;22373:131;22499:4;22373:131;:::i;:::-;22365:139;;22263:248;;;:::o;22517:419::-;;22721:2;22710:9;22706:18;22698:26;;22770:9;22764:4;22760:20;22756:1;22745:9;22741:17;22734:47;22798:131;22924:4;22798:131;:::i;:::-;22790:139;;22688:248;;;:::o;22942:419::-;;23146:2;23135:9;23131:18;23123:26;;23195:9;23189:4;23185:20;23181:1;23170:9;23166:17;23159:47;23223:131;23349:4;23223:131;:::i;:::-;23215:139;;23113:248;;;:::o;23367:419::-;;23571:2;23560:9;23556:18;23548:26;;23620:9;23614:4;23610:20;23606:1;23595:9;23591:17;23584:47;23648:131;23774:4;23648:131;:::i;:::-;23640:139;;23538:248;;;:::o;23792:419::-;;23996:2;23985:9;23981:18;23973:26;;24045:9;24039:4;24035:20;24031:1;24020:9;24016:17;24009:47;24073:131;24199:4;24073:131;:::i;:::-;24065:139;;23963:248;;;:::o;24217:419::-;;24421:2;24410:9;24406:18;24398:26;;24470:9;24464:4;24460:20;24456:1;24445:9;24441:17;24434:47;24498:131;24624:4;24498:131;:::i;:::-;24490:139;;24388:248;;;:::o;24642:419::-;;24846:2;24835:9;24831:18;24823:26;;24895:9;24889:4;24885:20;24881:1;24870:9;24866:17;24859:47;24923:131;25049:4;24923:131;:::i;:::-;24915:139;;24813:248;;;:::o;25067:419::-;;25271:2;25260:9;25256:18;25248:26;;25320:9;25314:4;25310:20;25306:1;25295:9;25291:17;25284:47;25348:131;25474:4;25348:131;:::i;:::-;25340:139;;25238:248;;;:::o;25492:419::-;;25696:2;25685:9;25681:18;25673:26;;25745:9;25739:4;25735:20;25731:1;25720:9;25716:17;25709:47;25773:131;25899:4;25773:131;:::i;:::-;25765:139;;25663:248;;;:::o;25917:419::-;;26121:2;26110:9;26106:18;26098:26;;26170:9;26164:4;26160:20;26156:1;26145:9;26141:17;26134:47;26198:131;26324:4;26198:131;:::i;:::-;26190:139;;26088:248;;;:::o;26342:419::-;;26546:2;26535:9;26531:18;26523:26;;26595:9;26589:4;26585:20;26581:1;26570:9;26566:17;26559:47;26623:131;26749:4;26623:131;:::i;:::-;26615:139;;26513:248;;;:::o;26767:419::-;;26971:2;26960:9;26956:18;26948:26;;27020:9;27014:4;27010:20;27006:1;26995:9;26991:17;26984:47;27048:131;27174:4;27048:131;:::i;:::-;27040:139;;26938:248;;;:::o;27192:419::-;;27396:2;27385:9;27381:18;27373:26;;27445:9;27439:4;27435:20;27431:1;27420:9;27416:17;27409:47;27473:131;27599:4;27473:131;:::i;:::-;27465:139;;27363:248;;;:::o;27617:419::-;;27821:2;27810:9;27806:18;27798:26;;27870:9;27864:4;27860:20;27856:1;27845:9;27841:17;27834:47;27898:131;28024:4;27898:131;:::i;:::-;27890:139;;27788:248;;;:::o;28042:419::-;;28246:2;28235:9;28231:18;28223:26;;28295:9;28289:4;28285:20;28281:1;28270:9;28266:17;28259:47;28323:131;28449:4;28323:131;:::i;:::-;28315:139;;28213:248;;;:::o;28467:419::-;;28671:2;28660:9;28656:18;28648:26;;28720:9;28714:4;28710:20;28706:1;28695:9;28691:17;28684:47;28748:131;28874:4;28748:131;:::i;:::-;28740:139;;28638:248;;;:::o;28892:419::-;;29096:2;29085:9;29081:18;29073:26;;29145:9;29139:4;29135:20;29131:1;29120:9;29116:17;29109:47;29173:131;29299:4;29173:131;:::i;:::-;29165:139;;29063:248;;;:::o;29317:419::-;;29521:2;29510:9;29506:18;29498:26;;29570:9;29564:4;29560:20;29556:1;29545:9;29541:17;29534:47;29598:131;29724:4;29598:131;:::i;:::-;29590:139;;29488:248;;;:::o;29742:419::-;;29946:2;29935:9;29931:18;29923:26;;29995:9;29989:4;29985:20;29981:1;29970:9;29966:17;29959:47;30023:131;30149:4;30023:131;:::i;:::-;30015:139;;29913:248;;;:::o;30167:419::-;;30371:2;30360:9;30356:18;30348:26;;30420:9;30414:4;30410:20;30406:1;30395:9;30391:17;30384:47;30448:131;30574:4;30448:131;:::i;:::-;30440:139;;30338:248;;;:::o;30592:419::-;;30796:2;30785:9;30781:18;30773:26;;30845:9;30839:4;30835:20;30831:1;30820:9;30816:17;30809:47;30873:131;30999:4;30873:131;:::i;:::-;30865:139;;30763:248;;;:::o;31017:334::-;;31204:2;31193:9;31189:18;31181:26;;31217:127;31341:1;31330:9;31326:17;31317:6;31217:127;:::i;:::-;31171:180;;;;:::o;31357:222::-;;31488:2;31477:9;31473:18;31465:26;;31501:71;31569:1;31558:9;31554:17;31545:6;31501:71;:::i;:::-;31455:124;;;;:::o;31585:332::-;;31744:2;31733:9;31729:18;31721:26;;31757:71;31825:1;31814:9;31810:17;31801:6;31757:71;:::i;:::-;31838:72;31906:2;31895:9;31891:18;31882:6;31838:72;:::i;:::-;31711:206;;;;;:::o;31923:218::-;;32052:2;32041:9;32037:18;32029:26;;32065:69;32131:1;32120:9;32116:17;32107:6;32065:69;:::i;:::-;32019:122;;;;:::o;32147:214::-;;32274:2;32263:9;32259:18;32251:26;;32287:67;32351:1;32340:9;32336:17;32327:6;32287:67;:::i;:::-;32241:120;;;;:::o;32367:99::-;;32453:5;32447:12;32437:22;;32426:40;;;:::o;32472:169::-;;32590:6;32585:3;32578:19;32630:4;32625:3;32621:14;32606:29;;32568:73;;;;:::o;32647:148::-;;32786:3;32771:18;;32761:34;;;;:::o;32801:305::-;;32860:20;32878:1;32860:20;:::i;:::-;32855:25;;32894:20;32912:1;32894:20;:::i;:::-;32889:25;;33048:1;32980:66;32976:74;32973:1;32970:81;32967:2;;;33054:18;;:::i;:::-;32967:2;33098:1;33095;33091:9;33084:16;;32845:261;;;;:::o;33112:185::-;;33169:20;33187:1;33169:20;:::i;:::-;33164:25;;33203:20;33221:1;33203:20;:::i;:::-;33198:25;;33242:1;33232:2;;33247:18;;:::i;:::-;33232:2;33289:1;33286;33282:9;33277:14;;33154:143;;;;:::o;33303:191::-;;33363:20;33381:1;33363:20;:::i;:::-;33358:25;;33397:20;33415:1;33397:20;:::i;:::-;33392:25;;33436:1;33433;33430:8;33427:2;;;33441:18;;:::i;:::-;33427:2;33486:1;33483;33479:9;33471:17;;33348:146;;;;:::o;33500:96::-;;33566:24;33584:5;33566:24;:::i;:::-;33555:35;;33545:51;;;:::o;33602:90::-;;33679:5;33672:13;33665:21;33654:32;;33644:48;;;:::o;33698:77::-;;33764:5;33753:16;;33743:32;;;:::o;33781:126::-;;33858:42;33851:5;33847:54;33836:65;;33826:81;;;:::o;33913:142::-;;33990:58;33983:5;33979:70;33968:81;;33958:97;;;:::o;34061:77::-;;34127:5;34116:16;;34106:32;;;:::o;34144:93::-;;34220:10;34213:5;34209:22;34198:33;;34188:49;;;:::o;34243:86::-;;34318:4;34311:5;34307:16;34296:27;;34286:43;;;:::o;34335:307::-;34403:1;34413:113;34427:6;34424:1;34421:13;34413:113;;;34512:1;34507:3;34503:11;34497:18;34493:1;34488:3;34484:11;34477:39;34449:2;34446:1;34442:10;34437:15;;34413:113;;;34544:6;34541:1;34538:13;34535:2;;;34624:1;34615:6;34610:3;34606:16;34599:27;34535:2;34384:258;;;;:::o;34648:320::-;;34729:1;34723:4;34719:12;34709:22;;34776:1;34770:4;34766:12;34797:18;34787:2;;34853:4;34845:6;34841:17;34831:27;;34787:2;34915;34907:6;34904:14;34884:18;34881:38;34878:2;;;34934:18;;:::i;:::-;34878:2;34699:269;;;;:::o;34974:79::-;;35042:5;35031:16;;35021:32;;;:::o;35059:180::-;35107:77;35104:1;35097:88;35204:4;35201:1;35194:15;35228:4;35225:1;35218:15;35245:180;35293:77;35290:1;35283:88;35390:4;35387:1;35380:15;35414:4;35411:1;35404:15;35431:180;35479:77;35476:1;35469:88;35576:4;35573:1;35566:15;35600:4;35597:1;35590:15;35617:102;;35709:2;35705:7;35700:2;35693:5;35689:14;35685:28;35675:38;;35665:54;;;:::o;35725:174::-;35865:26;35861:1;35853:6;35849:14;35842:50;35831:68;:::o;35905:179::-;36045:31;36041:1;36033:6;36029:14;36022:55;36011:73;:::o;36090:222::-;36230:34;36226:1;36218:6;36214:14;36207:58;36299:5;36294:2;36286:6;36282:15;36275:30;36196:116;:::o;36318:181::-;36458:33;36454:1;36446:6;36442:14;36435:57;36424:75;:::o;36505:179::-;36645:31;36641:1;36633:6;36629:14;36622:55;36611:73;:::o;36690:181::-;36830:33;36826:1;36818:6;36814:14;36807:57;36796:75;:::o;36877:175::-;37017:27;37013:1;37005:6;37001:14;36994:51;36983:69;:::o;37058:225::-;37198:34;37194:1;37186:6;37182:14;37175:58;37267:8;37262:2;37254:6;37250:15;37243:33;37164:119;:::o;37289:221::-;37429:34;37425:1;37417:6;37413:14;37406:58;37498:4;37493:2;37485:6;37481:15;37474:29;37395:115;:::o;37516:214::-;37656:66;37652:1;37644:6;37640:14;37633:90;37622:108;:::o;37736:179::-;37876:31;37872:1;37864:6;37860:14;37853:55;37842:73;:::o;37921:225::-;38061:34;38057:1;38049:6;38045:14;38038:58;38130:8;38125:2;38117:6;38113:15;38106:33;38027:119;:::o;38152:221::-;38292:34;38288:1;38280:6;38276:14;38269:58;38361:4;38356:2;38348:6;38344:15;38337:29;38258:115;:::o;38379:221::-;38519:34;38515:1;38507:6;38503:14;38496:58;38588:4;38583:2;38575:6;38571:15;38564:29;38485:115;:::o;38606:180::-;38746:32;38742:1;38734:6;38730:14;38723:56;38712:74;:::o;38792:227::-;38932:34;38928:1;38920:6;38916:14;38909:58;39001:10;38996:2;38988:6;38984:15;38977:35;38898:121;:::o;39025:235::-;39165:34;39161:1;39153:6;39149:14;39142:58;39234:18;39229:2;39221:6;39217:15;39210:43;39131:129;:::o;39266:182::-;39406:34;39402:1;39394:6;39390:14;39383:58;39372:76;:::o;39454:226::-;39594:34;39590:1;39582:6;39578:14;39571:58;39663:9;39658:2;39650:6;39646:15;39639:34;39560:120;:::o;39686:224::-;39826:34;39822:1;39814:6;39810:14;39803:58;39895:7;39890:2;39882:6;39878:15;39871:32;39792:118;:::o;39916:225::-;40056:34;40052:1;40044:6;40040:14;40033:58;40125:8;40120:2;40112:6;40108:15;40101:33;40022:119;:::o;40147:223::-;40287:34;40283:1;40275:6;40271:14;40264:58;40356:6;40351:2;40343:6;40339:15;40332:31;40253:117;:::o;40376:172::-;40516:24;40512:1;40504:6;40500:14;40493:48;40482:66;:::o;40554:224::-;40694:34;40690:1;40682:6;40678:14;40671:58;40763:7;40758:2;40750:6;40746:15;40739:32;40660:118;:::o;40784:181::-;40924:33;40920:1;40912:6;40908:14;40901:57;40890:75;:::o;40971:122::-;41044:24;41062:5;41044:24;:::i;:::-;41037:5;41034:35;41024:2;;41083:1;41080;41073:12;41024:2;41014:79;:::o;41099:122::-;41172:24;41190:5;41172:24;:::i;:::-;41165:5;41162:35;41152:2;;41211:1;41208;41201:12;41152:2;41142:79;:::o;41227:122::-;41300:24;41318:5;41300:24;:::i;:::-;41293:5;41290:35;41280:2;;41339:1;41336;41329:12;41280:2;41270:79;:::o;41355:120::-;41427:23;41444:5;41427:23;:::i;:::-;41420:5;41417:34;41407:2;;41465:1;41462;41455:12;41407:2;41397:78;:::o;41481:118::-;41552:22;41568:5;41552:22;:::i;:::-;41545:5;41542:33;41532:2;;41589:1;41586;41579:12;41532:2;41522:77;:::o

Swarm Source

ipfs://4377bfaf84ebcb29b406347a2dbd095642c53da27dc690f105c5bc60db79d21e
Loading