ETH Price: $3,257.29 (+2.35%)
Gas: 1 Gwei

Token

HanChain (HAN)
 

Overview

Max Total Supply

1,500,000,000 HAN

Holders

1,216 (0.00%)

Market

Price

$0.01 @ 0.000004 ETH (+2.96%)

Onchain Market Cap

$19,234,341.48

Circulating Supply Market Cap

$1,074,834.27

Other Info

Token Contract (WITH 18 Decimals)

Balance
40,000 HAN

Value
$512.92 ( ~0.157468284530667 Eth) [0.0027%]
0x19400E8ec764C313b5E8a3C9ffE6B5a0AD116040
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Dual cryptocurrency platform with DeFi structure focusing on real-life use. AdKhan: advertising platform, NFT-PLAY: WebDrama and MusicVideo streaming service, MusiKhan: music streaming service. NFT-WebDrama and MusicVideo, token-MusicCopyright, token-HAN stakings are available.

Market

Volume (24H):$4,917,420.05
Market Capitalization:$1,074,834.27
Circulating Supply:83,821,503.00 HAN
Market Data Source: Coinmarketcap

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
HanChain

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 Etherscan.io on 2022-02-05
*/

// SPDX-License-Identifier: MIT

// File: 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: 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: contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: 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: 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: 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: contracts/access/IAccessControl.sol


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

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

// File: 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: 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: 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: 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: contracts/security/Pausable.sol


// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: contracts/access/AccessControl.sol


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

pragma solidity ^0.8.0;





/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: 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: 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: 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: 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: 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: 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/token/ERC20/extensions/ERC20Burnable.sol


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

pragma solidity ^0.8.0;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        unchecked {
            _approve(account, _msgSender(), currentAllowance - amount);
        }
        _burn(account, amount);
    }
}

// File: HanChain.sol


pragma solidity ^0.8.2;








contract HanChain is ERC20, ERC20Burnable, ERC20Snapshot, AccessControl, Pausable, ERC20Permit, ERC20Votes {
    bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    constructor() ERC20("HanChain", "HAN") ERC20Permit("HanChain") {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(SNAPSHOT_ROLE, msg.sender);
        _grantRole(PAUSER_ROLE, msg.sender);
        _mint(msg.sender, 1500000000 * 10 ** decimals());
    }

    function snapshot() public onlyRole(SNAPSHOT_ROLE) {
        _snapshot();
    }

    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

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

    // The following functions are overrides required by Solidity.

    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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SNAPSHOT_ROLE","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":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","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":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610140908152503480156200003a57600080fd5b506040518060400160405280600881526020017f48616e436861696e000000000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600881526020017f48616e436861696e0000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f48414e000000000000000000000000000000000000000000000000000000000081525081600390805190602001906200012c92919062001197565b5080600490805190602001906200014592919062001197565b5050506000600a60006101000a81548160ff02191690831515021790555060008280519060200120905060008280519060200120905060007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90508260e081815250508161010081815250504660a08181525050620001cc818484620002d860201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508061012081815250505050505050506200022e6000801b336200031460201b60201c565b620002607f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f336200031460201b60201c565b620002927f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a336200031460201b60201c565b620002d233620002a76200040660201b60201c565b600a620002b5919062001557565b6359682f00620002c6919062001694565b6200040f60201b60201c565b62001965565b60008383834630604051602001620002f59594939291906200133d565b6040516020818303038152906040528051906020012090509392505050565b6200032682826200042a60201b60201c565b620004025760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620003a76200049560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006012905090565b6200042682826200049d60201b620017a41760201c565b5050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b620004b482826200055b60201b620018311760201c565b620004c4620006d460201b60201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16620004f2620006f860201b60201c565b111562000536576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200052d90620013bc565b60405180910390fd5b62000555600e6200070260201b6200199117836200071a60201b60201c565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620005ce576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005c59062001422565b60405180910390fd5b620005e26000838362000a3760201b60201c565b8060026000828254620005f691906200149f565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546200064d91906200149f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051620006b4919062001444565b60405180910390a3620006d06000838362000aa760201b60201c565b5050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b6000600254905090565b600081836200071291906200149f565b905092915050565b60008060008580549050905060008114620007b357856001826200073f9190620016f5565b8154811062000777577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16620007b6565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250620007e283858760201c565b91506000811180156200085f57504386600183620008019190620016f5565b8154811062000839577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b1562000924576200087b8262000ac460201b620019a71760201c565b866001836200088b9190620016f5565b81548110620008c3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555062000a2e565b856040518060400160405280620009464362000b3260201b62001a121760201c565b63ffffffff168152602001620009678562000ac460201b620019a71760201c565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b62000a4762000b8860201b60201c565b1562000a8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000a81906200139a565b60405180910390fd5b62000aa283838362000b9f60201b62001a651760201c565b505050565b62000abf83838362000c9a60201b62001b1f1760201c565b505050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff801682111562000b2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b2190620013de565b60405180910390fd5b819050919050565b600063ffffffff801682111562000b80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000b779062001400565b60405180910390fd5b819050919050565b6000600a60009054906101000a900460ff16905090565b62000bb783838362000cea60201b62001b4a1760201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141562000c145762000bfe8262000cef60201b60201c565b62000c0e62000d5260201b60201c565b62000c95565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000c715762000c5b8362000cef60201b60201c565b62000c6b62000d5260201b60201c565b62000c94565b62000c828362000cef60201b60201c565b62000c938262000cef60201b60201c565b5b5b505050565b62000cb283838362000d7660201b62001b4f1760201c565b62000ce562000cc78462000d7b60201b60201c565b62000cd88462000d7b60201b60201c565b8362000de460201b60201c565b505050565b505050565b62000d4f600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002062000d43836200100760201b60201c565b6200104f60201b60201c565b50565b62000d74600662000d68620006f860201b60201c565b6200104f60201b60201c565b565b505050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801562000e215750600081115b156200100257600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161462000f145760008062000ebb600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020620010db60201b62001b5417856200071a60201b60201c565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000f0992919062001461565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620010015760008062000fa8600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206200070260201b6200199117856200071a60201b60201c565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724838360405162000ff692919062001461565b60405180910390a250505b5b505050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600062001061620010f360201b60201c565b90508062001078846000016200111160201b60201c565b1015620010d65782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b60008183620010eb9190620016f5565b905092915050565b60006200110c60086200118960201b62001b6a1760201c565b905090565b600080828054905014156200112a576000905062001184565b81600183805490506200113e9190620016f5565b8154811062001176577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490505b919050565b600081600001549050919050565b828054620011a59062001785565b90600052602060002090601f016020900481019282620011c9576000855562001215565b82601f10620011e457805160ff191683800117855562001215565b8280016001018555821562001215579182015b8281111562001214578251825591602001919060010190620011f7565b5b50905062001224919062001228565b5090565b5b808211156200124357600081600090555060010162001229565b5090565b620012528162001730565b82525050565b620012638162001744565b82525050565b6000620012786010836200148e565b9150620012858262001826565b602082019050919050565b60006200129f6030836200148e565b9150620012ac826200184f565b604082019050919050565b6000620012c66027836200148e565b9150620012d3826200189e565b604082019050919050565b6000620012ed6026836200148e565b9150620012fa82620018ed565b604082019050919050565b600062001314601f836200148e565b915062001321826200193c565b602082019050919050565b62001337816200176e565b82525050565b600060a08201905062001354600083018862001258565b62001363602083018762001258565b62001372604083018662001258565b6200138160608301856200132c565b62001390608083018462001247565b9695505050505050565b60006020820190508181036000830152620013b58162001269565b9050919050565b60006020820190508181036000830152620013d78162001290565b9050919050565b60006020820190508181036000830152620013f981620012b7565b9050919050565b600060208201905081810360008301526200141b81620012de565b9050919050565b600060208201905081810360008301526200143d8162001305565b9050919050565b60006020820190506200145b60008301846200132c565b92915050565b60006040820190506200147860008301856200132c565b6200148760208301846200132c565b9392505050565b600082825260208201905092915050565b6000620014ac826200176e565b9150620014b9836200176e565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620014f157620014f0620017bb565b5b828201905092915050565b6000808291508390505b60018511156200154e57808604811115620015265762001525620017bb565b5b6001851615620015365780820291505b8081029050620015468562001819565b945062001506565b94509492505050565b600062001564826200176e565b9150620015718362001778565b9250620015a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484620015a8565b905092915050565b600082620015ba57600190506200168d565b81620015ca57600090506200168d565b8160018114620015e35760028114620015ee5762001624565b60019150506200168d565b60ff841115620016035762001602620017bb565b5b8360020a9150848211156200161d576200161c620017bb565b5b506200168d565b5060208310610133831016604e8410600b84101617156200165e5782820a905083811115620016585762001657620017bb565b5b6200168d565b6200166d8484846001620014fc565b92509050818404811115620016875762001686620017bb565b5b81810290505b9392505050565b6000620016a1826200176e565b9150620016ae836200176e565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615620016ea57620016e9620017bb565b5b828202905092915050565b600062001702826200176e565b91506200170f836200176e565b925082821015620017255762001724620017bb565b5b828203905092915050565b60006200173d826200174e565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600060028204905060018216806200179e57607f821691505b60208210811415620017b557620017b4620017ea565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008160011c9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b60805160a05160c05160601c60e051610100516101205161014051615696620019c3600039600061149f01526000612262015260006122a401526000612283015260006121b80152600061220e0152600061223701526156966000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80637028e2cd1161013b5780639ab24eb0116100b8578063d505accf1161007c578063d505accf14610728578063d547741f14610744578063dd62ed3e14610760578063e63ab1e914610790578063f1127ed8146107ae5761023d565b80639ab24eb01461065e578063a217fddf1461068e578063a457c2d7146106ac578063a9059cbb146106dc578063c3cda5201461070c5761023d565b80638e539e8c116100ff5780638e539e8c146105a657806391d14854146105d657806395d89b41146106065780639711715a14610624578063981b24d01461062e5761023d565b80637028e2cd1461050257806370a082311461052057806379cc6790146105505780637ecebe001461056c5780638456cb591461059c5761023d565b806336568abe116101c95780634ee2cd7e1161018d5780634ee2cd7e14610438578063587cde1e146104685780635c19a95c146104985780635c975abb146104b45780636fcfff45146104d25761023d565b806336568abe1461039657806339509351146103b25780633a46b1a8146103e25780633f4ba83a1461041257806342966c681461041c5761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a5780633644e515146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613eef565b6107de565b6040516102699190614555565b60405180910390f35b61027a610858565b60405161028791906146c9565b60405180910390f35b6102aa60048036038101906102a59190613d89565b6108ea565b6040516102b79190614555565b60405180910390f35b6102c8610908565b6040516102d59190614aa6565b60405180910390f35b6102f860048036038101906102f39190613c9c565b610912565b6040516103059190614555565b60405180910390f35b61032860048036038101906103239190613e8a565b610a0a565b6040516103359190614570565b60405180910390f35b61035860048036038101906103539190613eb3565b610a2a565b005b610362610a53565b60405161036f9190614b05565b60405180910390f35b610380610a5c565b60405161038d9190614570565b60405180910390f35b6103b060048036038101906103ab9190613eb3565b610a6b565b005b6103cc60048036038101906103c79190613d89565b610aee565b6040516103d99190614555565b60405180910390f35b6103fc60048036038101906103f79190613d89565b610b9a565b6040516104099190614aa6565b60405180910390f35b61041a610c2e565b005b61043660048036038101906104319190613f18565b610c6b565b005b610452600480360381019061044d9190613d89565b610c7f565b60405161045f9190614aa6565b60405180910390f35b610482600480360381019061047d9190613c37565b610cef565b60405161048f919061453a565b60405180910390f35b6104b260048036038101906104ad9190613c37565b610d58565b005b6104bc610d6c565b6040516104c99190614555565b60405180910390f35b6104ec60048036038101906104e79190613c37565b610d83565b6040516104f99190614aea565b60405180910390f35b61050a610dd7565b6040516105179190614570565b60405180910390f35b61053a60048036038101906105359190613c37565b610dfb565b6040516105479190614aa6565b60405180910390f35b61056a60048036038101906105659190613d89565b610e43565b005b61058660048036038101906105819190613c37565b610ebe565b6040516105939190614aa6565b60405180910390f35b6105a4610f0e565b005b6105c060048036038101906105bb9190613f18565b610f4b565b6040516105cd9190614aa6565b60405180910390f35b6105f060048036038101906105eb9190613eb3565b610fa1565b6040516105fd9190614555565b60405180910390f35b61060e61100c565b60405161061b91906146c9565b60405180910390f35b61062c61109e565b005b61064860048036038101906106439190613f18565b6110dc565b6040516106559190614aa6565b60405180910390f35b61067860048036038101906106739190613c37565b61110d565b6040516106859190614aa6565b60405180910390f35b610696611244565b6040516106a39190614570565b60405180910390f35b6106c660048036038101906106c19190613d89565b61124b565b6040516106d39190614555565b60405180910390f35b6106f660048036038101906106f19190613d89565b611336565b6040516107039190614555565b60405180910390f35b61072660048036038101906107219190613dc5565b611354565b005b610742600480360381019061073d9190613ceb565b611458565b005b61075e60048036038101906107599190613eb3565b61159a565b005b61077a60048036038101906107759190613c60565b6115c3565b6040516107879190614aa6565b60405180910390f35b61079861164a565b6040516107a59190614570565b60405180910390f35b6107c860048036038101906107c39190613e4e565b61166e565b6040516107d59190614a8b565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610851575061085082611b78565b5b9050919050565b60606003805461086790614d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461089390614d7c565b80156108e05780601f106108b5576101008083540402835291602001916108e0565b820191906000526020600020905b8154815290600101906020018083116108c357829003601f168201915b5050505050905090565b60006108fe6108f7611be2565b8484611bea565b6001905092915050565b6000600254905090565b600061091f848484611db5565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061096a611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19061490b565b60405180910390fd5b6109fe856109f6611be2565b858403611bea565b60019150509392505050565b600060096000838152602001908152602001600020600101549050919050565b610a3382610a0a565b610a4481610a3f611be2565b612036565b610a4e83836120d3565b505050565b60006012905090565b6000610a666121b4565b905090565b610a73611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ae0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad790614a4b565b60405180910390fd5b610aea82826122ce565b5050565b6000610b90610afb611be2565b848460016000610b09611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b8b9190614b47565b611bea565b6001905092915050565b6000438210610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd59061476b565b60405180910390fd5b610c26600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020836123b0565b905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c6081610c5b611be2565b612036565b610c68612508565b50565b610c7c610c76611be2565b826125aa565b50565b6000806000610ccc84600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206125b8565b9150915081610ce357610cde85610dfb565b610ce5565b805b9250505092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d69610d63611be2565b826126d4565b50565b6000600a60009054906101000a900460ff16905090565b6000610dd0600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611a12565b9050919050565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f81565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610e5683610e51611be2565b6115c3565b905081811015610e9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e929061496b565b60405180910390fd5b610eaf83610ea7611be2565b848403611bea565b610eb983836125aa565b505050565b6000610f07600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b6a565b9050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610f4081610f3b611be2565b612036565b610f486127ee565b50565b6000438210610f8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f869061476b565b60405180910390fd5b610f9a600e836123b0565b9050919050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60606004805461101b90614d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461104790614d7c565b80156110945780601f1061106957610100808354040283529160200191611094565b820191906000526020600020905b81548152906001019060200180831161107757829003601f168201915b5050505050905090565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f6110d0816110cb611be2565b612036565b6110d8612891565b5050565b60008060006110ec8460066125b8565b9150915081611102576110fd610908565b611104565b805b92505050919050565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461121b57600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826111a99190614c28565b815481106111e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661121e565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806001600061125a611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130e90614a2b565b60405180910390fd5b61132b611322611be2565b85858403611bea565b600191505092915050565b600061134a611343611be2565b8484611db5565b6001905092915050565b83421115611397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138e906147ab565b60405180910390fd5b60006113f96113f17fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016113d694939291906145ec565b604051602081830303815290604052805190602001206128e7565b858585612901565b90506114048161292c565b8614611445576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143c9061480b565b60405180910390fd5b61144f81886126d4565b50505050505050565b8342111561149b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114929061484b565b60405180910390fd5b60007f00000000000000000000000000000000000000000000000000000000000000008888886114ca8c61292c565b896040516020016114e09695949392919061458b565b6040516020818303038152906040528051906020012090506000611503826128e7565b9050600061151382878787612901565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157a906148eb565b60405180910390fd5b61158e8a8a8a611bea565b50505050505050505050565b6115a382610a0a565b6115b4816115af611be2565b612036565b6115be83836122ce565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b611676613b7b565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106116f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6117ae8282611831565b6117b661298a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166117dc610908565b111561181d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118149061492b565b60405180910390fd5b61182b600e611991836129ae565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189890614a6b565b60405180910390fd5b6118ad60008383612c98565b80600260008282546118bf9190614b47565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119149190614b47565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516119799190614aa6565b60405180910390a361198d60008383612cf0565b5050565b6000818361199f9190614b47565b905092915050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115611a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a019061494b565b60405180910390fd5b819050919050565b600063ffffffff8016821115611a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a54906149cb565b60405180910390fd5b819050919050565b611a70838383611b4a565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611abb57611aae82612d00565b611ab6612d53565b611b1a565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b0657611af983612d00565b611b01612d53565b611b19565b611b0f83612d00565b611b1882612d00565b5b5b505050565b611b2a838383611b4f565b611b45611b3684610cef565b611b3f84610cef565b83612d67565b505050565b505050565b505050565b60008183611b629190614c28565b905092915050565b600081600001549050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c51906149eb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc19061482b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611da89190614aa6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611e25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1c906149ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8c9061474b565b60405180910390fd5b611ea0838383612c98565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611f26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1d9061486b565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fb99190614b47565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161201d9190614aa6565b60405180910390a3612030848484612cf0565b50505050565b6120408282610fa1565b6120cf576120658173ffffffffffffffffffffffffffffffffffffffff166014612f60565b6120738360001c6020612f60565b604051602001612084929190614500565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c691906146c9565b60405180910390fd5b5050565b6120dd8282610fa1565b6121b05760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612155611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561223057507f000000000000000000000000000000000000000000000000000000000000000046145b1561225d577f000000000000000000000000000000000000000000000000000000000000000090506122cb565b6122c87f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061325a565b90505b90565b6122d88282610fa1565b156123ac5760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612351611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b818110156124555760006123d18284613294565b90508486828154811061240d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16111561243f5780925061244f565b60018161244c9190614b47565b91505b506123bd565b600082146124dd578460018361246b9190614c28565b815481106124a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166124e0565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b612510610d6c565b61254f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125469061478b565b60405180910390fd5b6000600a60006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612593611be2565b6040516125a0919061453a565b60405180910390a1565b6125b482826132ba565b5050565b600080600084116125fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f590614a0b565b60405180910390fd5b6126066132d8565b841115612648576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263f9061470b565b60405180910390fd5b600061266085856000016132e990919063ffffffff16565b9050836000018054905081141561267e5760008092509250506126cd565b60018460010182815481106126bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015492509250505b9250929050565b60006126df83610cef565b905060006126ec84610dfb565b905082600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46127e8828483612d67565b50505050565b6127f6610d6c565b15612836576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282d906148ab565b60405180910390fd5b6001600a60006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861287a611be2565b604051612887919061453a565b60405180910390a1565b600061289d600861340f565b60006128a76132d8565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516128d89190614aa6565b60405180910390a18091505090565b60006128fa6128f46121b4565b83613425565b9050919050565b600080600061291287878787613458565b9150915061291f81613565565b8192505050949350505050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061297981611b6a565b91506129848161340f565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008060008580549050905060008114612a4257856001826129d09190614c28565b81548110612a07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612a45565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612a7383858763ffffffff16565b9150600081118015612aec57504386600183612a8f9190614c28565b81548110612ac6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612b9f57612afa826119a7565b86600183612b089190614c28565b81548110612b3f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612c8f565b856040518060400160405280612bb443611a12565b63ffffffff168152602001612bc8856119a7565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b612ca0610d6c565b15612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd7906148ab565b60405180910390fd5b612ceb838383611a65565b505050565b612cfb838383611b1f565b505050565b612d50600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d4b83610dfb565b6138b6565b50565b612d656006612d60610908565b6138b6565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612da35750600081115b15612f5b57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612e8157600080612e2a600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b54856129ae565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e76929190614ac1565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612f5a57600080612f03600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611991856129ae565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612f4f929190614ac1565b60405180910390a250505b5b505050565b606060006002836002612f739190614bce565b612f7d9190614b47565b67ffffffffffffffff811115612fbc577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612fee5781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061304c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106130d6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026131169190614bce565b6131209190614b47565b90505b600181111561320c577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110613188577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b8282815181106131c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061320590614d52565b9050613123565b5060008414613250576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132479061472b565b60405180910390fd5b8091505092915050565b60008383834630604051602001613275959493929190614631565b6040516020818303038152906040528051906020012090509392505050565b600060028284186132a59190614b9d565b8284166132b29190614b47565b905092915050565b6132c48282613931565b6132d2600e611b54836129ae565b50505050565b60006132e46008611b6a565b905090565b600080838054905014156133005760009050613409565b600080848054905090505b8082101561338a57600061331f8383613294565b90508486828154811061335b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154111561337457809150613384565b6001816133819190614b47565b92505b5061330b565b6000821180156133e8575083856001846133a49190614c28565b815481106133db577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154145b15613403576001826133fa9190614c28565b92505050613409565b81925050505b92915050565b6001816000016000828254019250508190555050565b6000828260405160200161343a9291906144c9565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561349357600060039150915061355c565b601b8560ff16141580156134ab5750601c8560ff1614155b156134bd57600060049150915061355c565b6000600187878787604051600081526020016040526040516134e29493929190614684565b6020604051602081039080840390855afa158015613504573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156135535760006001925092505061355c565b80600092509250505b94509492505050565b6000600481111561359f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8160048111156135d8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156135e3576138b3565b6001600481111561361d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115613656577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415613697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368e906146eb565b60405180910390fd5b600260048111156136d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81600481111561370a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561374b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613742906147eb565b60405180910390fd5b60036004811115613785577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8160048111156137be577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156137ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137f69061488b565b60405180910390fd5b600480811115613838577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115613871577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156138b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138a9906148cb565b60405180910390fd5b5b50565b60006138c06132d8565b9050806138cf84600001613b08565b101561392c5782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139989061498b565b60405180910390fd5b6139ad82600083612c98565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015613a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2a906147cb565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160026000828254613a8a9190614c28565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613aef9190614aa6565b60405180910390a3613b0383600084612cf0565b505050565b60008082805490501415613b1f5760009050613b76565b8160018380549050613b319190614c28565b81548110613b68577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490505b919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050613bc8816155d6565b92915050565b600081359050613bdd816155ed565b92915050565b600081359050613bf281615604565b92915050565b600081359050613c078161561b565b92915050565b600081359050613c1c81615632565b92915050565b600081359050613c3181615649565b92915050565b600060208284031215613c4957600080fd5b6000613c5784828501613bb9565b91505092915050565b60008060408385031215613c7357600080fd5b6000613c8185828601613bb9565b9250506020613c9285828601613bb9565b9150509250929050565b600080600060608486031215613cb157600080fd5b6000613cbf86828701613bb9565b9350506020613cd086828701613bb9565b9250506040613ce186828701613bf8565b9150509250925092565b600080600080600080600060e0888a031215613d0657600080fd5b6000613d148a828b01613bb9565b9750506020613d258a828b01613bb9565b9650506040613d368a828b01613bf8565b9550506060613d478a828b01613bf8565b9450506080613d588a828b01613c22565b93505060a0613d698a828b01613bce565b92505060c0613d7a8a828b01613bce565b91505092959891949750929550565b60008060408385031215613d9c57600080fd5b6000613daa85828601613bb9565b9250506020613dbb85828601613bf8565b9150509250929050565b60008060008060008060c08789031215613dde57600080fd5b6000613dec89828a01613bb9565b9650506020613dfd89828a01613bf8565b9550506040613e0e89828a01613bf8565b9450506060613e1f89828a01613c22565b9350506080613e3089828a01613bce565b92505060a0613e4189828a01613bce565b9150509295509295509295565b60008060408385031215613e6157600080fd5b6000613e6f85828601613bb9565b9250506020613e8085828601613c0d565b9150509250929050565b600060208284031215613e9c57600080fd5b6000613eaa84828501613bce565b91505092915050565b60008060408385031215613ec657600080fd5b6000613ed485828601613bce565b9250506020613ee585828601613bb9565b9150509250929050565b600060208284031215613f0157600080fd5b6000613f0f84828501613be3565b91505092915050565b600060208284031215613f2a57600080fd5b6000613f3884828501613bf8565b91505092915050565b613f4a81614c5c565b82525050565b613f5981614c6e565b82525050565b613f6881614c7a565b82525050565b613f7f613f7a82614c7a565b614dae565b82525050565b6000613f9082614b20565b613f9a8185614b2b565b9350613faa818560208601614d1f565b613fb381614e45565b840191505092915050565b6000613fc982614b20565b613fd38185614b3c565b9350613fe3818560208601614d1f565b80840191505092915050565b6000613ffc601883614b2b565b915061400782614e56565b602082019050919050565b600061401f601d83614b2b565b915061402a82614e7f565b602082019050919050565b6000614042602083614b2b565b915061404d82614ea8565b602082019050919050565b6000614065602383614b2b565b915061407082614ed1565b604082019050919050565b6000614088601f83614b2b565b915061409382614f20565b602082019050919050565b60006140ab601483614b2b565b91506140b682614f49565b602082019050919050565b60006140ce601d83614b2b565b91506140d982614f72565b602082019050919050565b60006140f1602283614b2b565b91506140fc82614f9b565b604082019050919050565b6000614114601f83614b2b565b915061411f82614fea565b602082019050919050565b6000614137601983614b2b565b915061414282615013565b602082019050919050565b600061415a602283614b2b565b91506141658261503c565b604082019050919050565b600061417d600283614b3c565b91506141888261508b565b600282019050919050565b60006141a0601d83614b2b565b91506141ab826150b4565b602082019050919050565b60006141c3602683614b2b565b91506141ce826150dd565b604082019050919050565b60006141e6602283614b2b565b91506141f18261512c565b604082019050919050565b6000614209601083614b2b565b91506142148261517b565b602082019050919050565b600061422c602283614b2b565b9150614237826151a4565b604082019050919050565b600061424f601e83614b2b565b915061425a826151f3565b602082019050919050565b6000614272602883614b2b565b915061427d8261521c565b604082019050919050565b6000614295603083614b2b565b91506142a08261526b565b604082019050919050565b60006142b8602783614b2b565b91506142c3826152ba565b604082019050919050565b60006142db602483614b2b565b91506142e682615309565b604082019050919050565b60006142fe602183614b2b565b915061430982615358565b604082019050919050565b6000614321602583614b2b565b915061432c826153a7565b604082019050919050565b6000614344602683614b2b565b915061434f826153f6565b604082019050919050565b6000614367602483614b2b565b915061437282615445565b604082019050919050565b600061438a601683614b2b565b915061439582615494565b602082019050919050565b60006143ad601783614b3c565b91506143b8826154bd565b601782019050919050565b60006143d0602583614b2b565b91506143db826154e6565b604082019050919050565b60006143f3601183614b3c565b91506143fe82615535565b601182019050919050565b6000614416602f83614b2b565b91506144218261555e565b604082019050919050565b6000614439601f83614b2b565b9150614444826155ad565b602082019050919050565b604082016000820151614465600085018261449c565b506020820151614478602085018261447e565b50505050565b61448781614cd0565b82525050565b61449681614cf8565b82525050565b6144a581614d02565b82525050565b6144b481614d02565b82525050565b6144c381614d12565b82525050565b60006144d482614170565b91506144e08285613f6e565b6020820191506144f08284613f6e565b6020820191508190509392505050565b600061450b826143a0565b91506145178285613fbe565b9150614522826143e6565b915061452e8284613fbe565b91508190509392505050565b600060208201905061454f6000830184613f41565b92915050565b600060208201905061456a6000830184613f50565b92915050565b60006020820190506145856000830184613f5f565b92915050565b600060c0820190506145a06000830189613f5f565b6145ad6020830188613f41565b6145ba6040830187613f41565b6145c7606083018661448d565b6145d4608083018561448d565b6145e160a083018461448d565b979650505050505050565b60006080820190506146016000830187613f5f565b61460e6020830186613f41565b61461b604083018561448d565b614628606083018461448d565b95945050505050565b600060a0820190506146466000830188613f5f565b6146536020830187613f5f565b6146606040830186613f5f565b61466d606083018561448d565b61467a6080830184613f41565b9695505050505050565b60006080820190506146996000830187613f5f565b6146a660208301866144ba565b6146b36040830185613f5f565b6146c06060830184613f5f565b95945050505050565b600060208201905081810360008301526146e38184613f85565b905092915050565b6000602082019050818103600083015261470481613fef565b9050919050565b6000602082019050818103600083015261472481614012565b9050919050565b6000602082019050818103600083015261474481614035565b9050919050565b6000602082019050818103600083015261476481614058565b9050919050565b600060208201905081810360008301526147848161407b565b9050919050565b600060208201905081810360008301526147a48161409e565b9050919050565b600060208201905081810360008301526147c4816140c1565b9050919050565b600060208201905081810360008301526147e4816140e4565b9050919050565b6000602082019050818103600083015261480481614107565b9050919050565b600060208201905081810360008301526148248161412a565b9050919050565b600060208201905081810360008301526148448161414d565b9050919050565b6000602082019050818103600083015261486481614193565b9050919050565b60006020820190508181036000830152614884816141b6565b9050919050565b600060208201905081810360008301526148a4816141d9565b9050919050565b600060208201905081810360008301526148c4816141fc565b9050919050565b600060208201905081810360008301526148e48161421f565b9050919050565b6000602082019050818103600083015261490481614242565b9050919050565b6000602082019050818103600083015261492481614265565b9050919050565b6000602082019050818103600083015261494481614288565b9050919050565b60006020820190508181036000830152614964816142ab565b9050919050565b60006020820190508181036000830152614984816142ce565b9050919050565b600060208201905081810360008301526149a4816142f1565b9050919050565b600060208201905081810360008301526149c481614314565b9050919050565b600060208201905081810360008301526149e481614337565b9050919050565b60006020820190508181036000830152614a048161435a565b9050919050565b60006020820190508181036000830152614a248161437d565b9050919050565b60006020820190508181036000830152614a44816143c3565b9050919050565b60006020820190508181036000830152614a6481614409565b9050919050565b60006020820190508181036000830152614a848161442c565b9050919050565b6000604082019050614aa0600083018461444f565b92915050565b6000602082019050614abb600083018461448d565b92915050565b6000604082019050614ad6600083018561448d565b614ae3602083018461448d565b9392505050565b6000602082019050614aff60008301846144ab565b92915050565b6000602082019050614b1a60008301846144ba565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000614b5282614cf8565b9150614b5d83614cf8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614b9257614b91614db8565b5b828201905092915050565b6000614ba882614cf8565b9150614bb383614cf8565b925082614bc357614bc2614de7565b5b828204905092915050565b6000614bd982614cf8565b9150614be483614cf8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614c1d57614c1c614db8565b5b828202905092915050565b6000614c3382614cf8565b9150614c3e83614cf8565b925082821015614c5157614c50614db8565b5b828203905092915050565b6000614c6782614cb0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b60005b83811015614d3d578082015181840152602081019050614d22565b83811115614d4c576000848401525b50505050565b6000614d5d82614cf8565b91506000821415614d7157614d70614db8565b5b600182039050919050565b60006002820490506001821680614d9457607f821691505b60208210811415614da857614da7614e16565b5b50919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000600082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230536e617073686f743a206964206973203000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6155df81614c5c565b81146155ea57600080fd5b50565b6155f681614c7a565b811461560157600080fd5b50565b61560d81614c84565b811461561857600080fd5b50565b61562481614cf8565b811461562f57600080fd5b50565b61563b81614d02565b811461564657600080fd5b50565b61565281614d12565b811461565d57600080fd5b5056fea2646970667358221220eadf1df264f069e0acb0c78903f347238b3b72f8b6f0758d54a3c7c7891b47c064736f6c63430008020033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061023d5760003560e01c80637028e2cd1161013b5780639ab24eb0116100b8578063d505accf1161007c578063d505accf14610728578063d547741f14610744578063dd62ed3e14610760578063e63ab1e914610790578063f1127ed8146107ae5761023d565b80639ab24eb01461065e578063a217fddf1461068e578063a457c2d7146106ac578063a9059cbb146106dc578063c3cda5201461070c5761023d565b80638e539e8c116100ff5780638e539e8c146105a657806391d14854146105d657806395d89b41146106065780639711715a14610624578063981b24d01461062e5761023d565b80637028e2cd1461050257806370a082311461052057806379cc6790146105505780637ecebe001461056c5780638456cb591461059c5761023d565b806336568abe116101c95780634ee2cd7e1161018d5780634ee2cd7e14610438578063587cde1e146104685780635c19a95c146104985780635c975abb146104b45780636fcfff45146104d25761023d565b806336568abe1461039657806339509351146103b25780633a46b1a8146103e25780633f4ba83a1461041257806342966c681461041c5761023d565b806323b872dd1161021057806323b872dd146102de578063248a9ca31461030e5780632f2ff15d1461033e578063313ce5671461035a5780633644e515146103785761023d565b806301ffc9a71461024257806306fdde0314610272578063095ea7b31461029057806318160ddd146102c0575b600080fd5b61025c60048036038101906102579190613eef565b6107de565b6040516102699190614555565b60405180910390f35b61027a610858565b60405161028791906146c9565b60405180910390f35b6102aa60048036038101906102a59190613d89565b6108ea565b6040516102b79190614555565b60405180910390f35b6102c8610908565b6040516102d59190614aa6565b60405180910390f35b6102f860048036038101906102f39190613c9c565b610912565b6040516103059190614555565b60405180910390f35b61032860048036038101906103239190613e8a565b610a0a565b6040516103359190614570565b60405180910390f35b61035860048036038101906103539190613eb3565b610a2a565b005b610362610a53565b60405161036f9190614b05565b60405180910390f35b610380610a5c565b60405161038d9190614570565b60405180910390f35b6103b060048036038101906103ab9190613eb3565b610a6b565b005b6103cc60048036038101906103c79190613d89565b610aee565b6040516103d99190614555565b60405180910390f35b6103fc60048036038101906103f79190613d89565b610b9a565b6040516104099190614aa6565b60405180910390f35b61041a610c2e565b005b61043660048036038101906104319190613f18565b610c6b565b005b610452600480360381019061044d9190613d89565b610c7f565b60405161045f9190614aa6565b60405180910390f35b610482600480360381019061047d9190613c37565b610cef565b60405161048f919061453a565b60405180910390f35b6104b260048036038101906104ad9190613c37565b610d58565b005b6104bc610d6c565b6040516104c99190614555565b60405180910390f35b6104ec60048036038101906104e79190613c37565b610d83565b6040516104f99190614aea565b60405180910390f35b61050a610dd7565b6040516105179190614570565b60405180910390f35b61053a60048036038101906105359190613c37565b610dfb565b6040516105479190614aa6565b60405180910390f35b61056a60048036038101906105659190613d89565b610e43565b005b61058660048036038101906105819190613c37565b610ebe565b6040516105939190614aa6565b60405180910390f35b6105a4610f0e565b005b6105c060048036038101906105bb9190613f18565b610f4b565b6040516105cd9190614aa6565b60405180910390f35b6105f060048036038101906105eb9190613eb3565b610fa1565b6040516105fd9190614555565b60405180910390f35b61060e61100c565b60405161061b91906146c9565b60405180910390f35b61062c61109e565b005b61064860048036038101906106439190613f18565b6110dc565b6040516106559190614aa6565b60405180910390f35b61067860048036038101906106739190613c37565b61110d565b6040516106859190614aa6565b60405180910390f35b610696611244565b6040516106a39190614570565b60405180910390f35b6106c660048036038101906106c19190613d89565b61124b565b6040516106d39190614555565b60405180910390f35b6106f660048036038101906106f19190613d89565b611336565b6040516107039190614555565b60405180910390f35b61072660048036038101906107219190613dc5565b611354565b005b610742600480360381019061073d9190613ceb565b611458565b005b61075e60048036038101906107599190613eb3565b61159a565b005b61077a60048036038101906107759190613c60565b6115c3565b6040516107879190614aa6565b60405180910390f35b61079861164a565b6040516107a59190614570565b60405180910390f35b6107c860048036038101906107c39190613e4e565b61166e565b6040516107d59190614a8b565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610851575061085082611b78565b5b9050919050565b60606003805461086790614d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461089390614d7c565b80156108e05780601f106108b5576101008083540402835291602001916108e0565b820191906000526020600020905b8154815290600101906020018083116108c357829003601f168201915b5050505050905090565b60006108fe6108f7611be2565b8484611bea565b6001905092915050565b6000600254905090565b600061091f848484611db5565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061096a611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050828110156109ea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109e19061490b565b60405180910390fd5b6109fe856109f6611be2565b858403611bea565b60019150509392505050565b600060096000838152602001908152602001600020600101549050919050565b610a3382610a0a565b610a4481610a3f611be2565b612036565b610a4e83836120d3565b505050565b60006012905090565b6000610a666121b4565b905090565b610a73611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ae0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad790614a4b565b60405180910390fd5b610aea82826122ce565b5050565b6000610b90610afb611be2565b848460016000610b09611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b8b9190614b47565b611bea565b6001905092915050565b6000438210610bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd59061476b565b60405180910390fd5b610c26600d60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020836123b0565b905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c6081610c5b611be2565b612036565b610c68612508565b50565b610c7c610c76611be2565b826125aa565b50565b6000806000610ccc84600560008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206125b8565b9150915081610ce357610cde85610dfb565b610ce5565b805b9250505092915050565b6000600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b610d69610d63611be2565b826126d4565b50565b6000600a60009054906101000a900460ff16905090565b6000610dd0600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080549050611a12565b9050919050565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f81565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610e5683610e51611be2565b6115c3565b905081811015610e9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e929061496b565b60405180910390fd5b610eaf83610ea7611be2565b848403611bea565b610eb983836125aa565b505050565b6000610f07600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b6a565b9050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610f4081610f3b611be2565b612036565b610f486127ee565b50565b6000438210610f8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f869061476b565b60405180910390fd5b610f9a600e836123b0565b9050919050565b60006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60606004805461101b90614d7c565b80601f016020809104026020016040519081016040528092919081815260200182805461104790614d7c565b80156110945780601f1061106957610100808354040283529160200191611094565b820191906000526020600020905b81548152906001019060200180831161107757829003601f168201915b5050505050905090565b7f5fdbd35e8da83ee755d5e62a539e5ed7f47126abede0b8b10f9ea43dc6eed07f6110d0816110cb611be2565b612036565b6110d8612891565b5050565b60008060006110ec8460066125b8565b9150915081611102576110fd610908565b611104565b805b92505050919050565b600080600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208054905090506000811461121b57600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001826111a99190614c28565b815481106111e0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661121e565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16915050919050565b6000801b81565b6000806001600061125a611be2565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015611317576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130e90614a2b565b60405180910390fd5b61132b611322611be2565b85858403611bea565b600191505092915050565b600061134a611343611be2565b8484611db5565b6001905092915050565b83421115611397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138e906147ab565b60405180910390fd5b60006113f96113f17fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf8989896040516020016113d694939291906145ec565b604051602081830303815290604052805190602001206128e7565b858585612901565b90506114048161292c565b8614611445576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143c9061480b565b60405180910390fd5b61144f81886126d4565b50505050505050565b8342111561149b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114929061484b565b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886114ca8c61292c565b896040516020016114e09695949392919061458b565b6040516020818303038152906040528051906020012090506000611503826128e7565b9050600061151382878787612901565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611583576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157a906148eb565b60405180910390fd5b61158e8a8a8a611bea565b50505050505050505050565b6115a382610a0a565b6115b4816115af611be2565b612036565b6115be83836122ce565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b611676613b7b565b600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208263ffffffff16815481106116f3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020016040518060400160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525050905092915050565b6117ae8282611831565b6117b661298a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166117dc610908565b111561181d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118149061492b565b60405180910390fd5b61182b600e611991836129ae565b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189890614a6b565b60405180910390fd5b6118ad60008383612c98565b80600260008282546118bf9190614b47565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546119149190614b47565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516119799190614aa6565b60405180910390a361198d60008383612cf0565b5050565b6000818361199f9190614b47565b905092915050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8016821115611a0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a019061494b565b60405180910390fd5b819050919050565b600063ffffffff8016821115611a5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a54906149cb565b60405180910390fd5b819050919050565b611a70838383611b4a565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611abb57611aae82612d00565b611ab6612d53565b611b1a565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611b0657611af983612d00565b611b01612d53565b611b19565b611b0f83612d00565b611b1882612d00565b5b5b505050565b611b2a838383611b4f565b611b45611b3684610cef565b611b3f84610cef565b83612d67565b505050565b505050565b505050565b60008183611b629190614c28565b905092915050565b600081600001549050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611c5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c51906149eb565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cc19061482b565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92583604051611da89190614aa6565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611e25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1c906149ab565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e8c9061474b565b60405180910390fd5b611ea0838383612c98565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611f26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f1d9061486b565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611fb99190614b47565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161201d9190614aa6565b60405180910390a3612030848484612cf0565b50505050565b6120408282610fa1565b6120cf576120658173ffffffffffffffffffffffffffffffffffffffff166014612f60565b6120738360001c6020612f60565b604051602001612084929190614500565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c691906146c9565b60405180910390fd5b5050565b6120dd8282610fa1565b6121b05760016009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612155611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60007f0000000000000000000000000c90c57aaf95a3a87eadda6ec3974c99d786511f73ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561223057507f000000000000000000000000000000000000000000000000000000000000000146145b1561225d577f8ec453966133bcadf779198e1bcbdf6bd8f89ad5cfd85389b89e46361404792090506122cb565b6122c87f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7fcde9603902c6b246c5f58239b930ce4d734b9fb14efc47bd3832a08966ce962b7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc661325a565b90505b90565b6122d88282610fa1565b156123ac5760006009600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612351611be2565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000808380549050905060005b818110156124555760006123d18284613294565b90508486828154811061240d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16111561243f5780925061244f565b60018161244c9190614b47565b91505b506123bd565b600082146124dd578460018361246b9190614c28565b815481106124a2577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166124e0565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250505092915050565b612510610d6c565b61254f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125469061478b565b60405180910390fd5b6000600a60006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa612593611be2565b6040516125a0919061453a565b60405180910390a1565b6125b482826132ba565b5050565b600080600084116125fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125f590614a0b565b60405180910390fd5b6126066132d8565b841115612648576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263f9061470b565b60405180910390fd5b600061266085856000016132e990919063ffffffff16565b9050836000018054905081141561267e5760008092509250506126cd565b60018460010182815481106126bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015492509250505b9250929050565b60006126df83610cef565b905060006126ec84610dfb565b905082600c60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f60405160405180910390a46127e8828483612d67565b50505050565b6127f6610d6c565b15612836576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282d906148ab565b60405180910390fd5b6001600a60006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861287a611be2565b604051612887919061453a565b60405180910390a1565b600061289d600861340f565b60006128a76132d8565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb67816040516128d89190614aa6565b60405180910390a18091505090565b60006128fa6128f46121b4565b83613425565b9050919050565b600080600061291287878787613458565b9150915061291f81613565565b8192505050949350505050565b600080600b60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061297981611b6a565b91506129848161340f565b50919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff905090565b60008060008580549050905060008114612a4257856001826129d09190614c28565b81548110612a07577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160049054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16612a45565b60005b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169250612a7383858763ffffffff16565b9150600081118015612aec57504386600183612a8f9190614c28565b81548110612ac6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160009054906101000a900463ffffffff1663ffffffff16145b15612b9f57612afa826119a7565b86600183612b089190614c28565b81548110612b3f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550612c8f565b856040518060400160405280612bb443611a12565b63ffffffff168152602001612bc8856119a7565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16021790555050505b50935093915050565b612ca0610d6c565b15612ce0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd7906148ab565b60405180910390fd5b612ceb838383611a65565b505050565b612cfb838383611b1f565b505050565b612d50600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d4b83610dfb565b6138b6565b50565b612d656006612d60610908565b6138b6565b565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158015612da35750600081115b15612f5b57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612e8157600080612e2a600d60008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611b54856129ae565b915091508473ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e76929190614ac1565b60405180910390a250505b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612f5a57600080612f03600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611991856129ae565b915091508373ffffffffffffffffffffffffffffffffffffffff167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612f4f929190614ac1565b60405180910390a250505b5b505050565b606060006002836002612f739190614bce565b612f7d9190614b47565b67ffffffffffffffff811115612fbc577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612fee5781602001600182028036833780820191505090505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061304c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106130d6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026131169190614bce565b6131209190614b47565b90505b600181111561320c577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110613188577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b8282815181106131c5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c94508061320590614d52565b9050613123565b5060008414613250576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132479061472b565b60405180910390fd5b8091505092915050565b60008383834630604051602001613275959493929190614631565b6040516020818303038152906040528051906020012090509392505050565b600060028284186132a59190614b9d565b8284166132b29190614b47565b905092915050565b6132c48282613931565b6132d2600e611b54836129ae565b50505050565b60006132e46008611b6a565b905090565b600080838054905014156133005760009050613409565b600080848054905090505b8082101561338a57600061331f8383613294565b90508486828154811061335b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154111561337457809150613384565b6001816133819190614b47565b92505b5061330b565b6000821180156133e8575083856001846133a49190614c28565b815481106133db577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154145b15613403576001826133fa9190614c28565b92505050613409565b81925050505b92915050565b6001816000016000828254019250508190555050565b6000828260405160200161343a9291906144c9565b60405160208183030381529060405280519060200120905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c111561349357600060039150915061355c565b601b8560ff16141580156134ab5750601c8560ff1614155b156134bd57600060049150915061355c565b6000600187878787604051600081526020016040526040516134e29493929190614684565b6020604051602081039080840390855afa158015613504573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156135535760006001925092505061355c565b80600092509250505b94509492505050565b6000600481111561359f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8160048111156135d8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156135e3576138b3565b6001600481111561361d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115613656577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b1415613697576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161368e906146eb565b60405180910390fd5b600260048111156136d1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81600481111561370a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b141561374b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613742906147eb565b60405180910390fd5b60036004811115613785577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8160048111156137be577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156137ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137f69061488b565b60405180910390fd5b600480811115613838577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b816004811115613871577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b14156138b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138a9906148cb565b60405180910390fd5b5b50565b60006138c06132d8565b9050806138cf84600001613b08565b101561392c5782600001819080600181540180825580915050600190039060005260206000200160009091909190915055826001018290806001815401808255809150506001900390600052602060002001600090919091909150555b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139989061498b565b60405180910390fd5b6139ad82600083612c98565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015613a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a2a906147cb565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160026000828254613a8a9190614c28565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051613aef9190614aa6565b60405180910390a3613b0383600084612cf0565b505050565b60008082805490501415613b1f5760009050613b76565b8160018380549050613b319190614c28565b81548110613b68577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020015490505b919050565b6040518060400160405280600063ffffffff16815260200160007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681525090565b600081359050613bc8816155d6565b92915050565b600081359050613bdd816155ed565b92915050565b600081359050613bf281615604565b92915050565b600081359050613c078161561b565b92915050565b600081359050613c1c81615632565b92915050565b600081359050613c3181615649565b92915050565b600060208284031215613c4957600080fd5b6000613c5784828501613bb9565b91505092915050565b60008060408385031215613c7357600080fd5b6000613c8185828601613bb9565b9250506020613c9285828601613bb9565b9150509250929050565b600080600060608486031215613cb157600080fd5b6000613cbf86828701613bb9565b9350506020613cd086828701613bb9565b9250506040613ce186828701613bf8565b9150509250925092565b600080600080600080600060e0888a031215613d0657600080fd5b6000613d148a828b01613bb9565b9750506020613d258a828b01613bb9565b9650506040613d368a828b01613bf8565b9550506060613d478a828b01613bf8565b9450506080613d588a828b01613c22565b93505060a0613d698a828b01613bce565b92505060c0613d7a8a828b01613bce565b91505092959891949750929550565b60008060408385031215613d9c57600080fd5b6000613daa85828601613bb9565b9250506020613dbb85828601613bf8565b9150509250929050565b60008060008060008060c08789031215613dde57600080fd5b6000613dec89828a01613bb9565b9650506020613dfd89828a01613bf8565b9550506040613e0e89828a01613bf8565b9450506060613e1f89828a01613c22565b9350506080613e3089828a01613bce565b92505060a0613e4189828a01613bce565b9150509295509295509295565b60008060408385031215613e6157600080fd5b6000613e6f85828601613bb9565b9250506020613e8085828601613c0d565b9150509250929050565b600060208284031215613e9c57600080fd5b6000613eaa84828501613bce565b91505092915050565b60008060408385031215613ec657600080fd5b6000613ed485828601613bce565b9250506020613ee585828601613bb9565b9150509250929050565b600060208284031215613f0157600080fd5b6000613f0f84828501613be3565b91505092915050565b600060208284031215613f2a57600080fd5b6000613f3884828501613bf8565b91505092915050565b613f4a81614c5c565b82525050565b613f5981614c6e565b82525050565b613f6881614c7a565b82525050565b613f7f613f7a82614c7a565b614dae565b82525050565b6000613f9082614b20565b613f9a8185614b2b565b9350613faa818560208601614d1f565b613fb381614e45565b840191505092915050565b6000613fc982614b20565b613fd38185614b3c565b9350613fe3818560208601614d1f565b80840191505092915050565b6000613ffc601883614b2b565b915061400782614e56565b602082019050919050565b600061401f601d83614b2b565b915061402a82614e7f565b602082019050919050565b6000614042602083614b2b565b915061404d82614ea8565b602082019050919050565b6000614065602383614b2b565b915061407082614ed1565b604082019050919050565b6000614088601f83614b2b565b915061409382614f20565b602082019050919050565b60006140ab601483614b2b565b91506140b682614f49565b602082019050919050565b60006140ce601d83614b2b565b91506140d982614f72565b602082019050919050565b60006140f1602283614b2b565b91506140fc82614f9b565b604082019050919050565b6000614114601f83614b2b565b915061411f82614fea565b602082019050919050565b6000614137601983614b2b565b915061414282615013565b602082019050919050565b600061415a602283614b2b565b91506141658261503c565b604082019050919050565b600061417d600283614b3c565b91506141888261508b565b600282019050919050565b60006141a0601d83614b2b565b91506141ab826150b4565b602082019050919050565b60006141c3602683614b2b565b91506141ce826150dd565b604082019050919050565b60006141e6602283614b2b565b91506141f18261512c565b604082019050919050565b6000614209601083614b2b565b91506142148261517b565b602082019050919050565b600061422c602283614b2b565b9150614237826151a4565b604082019050919050565b600061424f601e83614b2b565b915061425a826151f3565b602082019050919050565b6000614272602883614b2b565b915061427d8261521c565b604082019050919050565b6000614295603083614b2b565b91506142a08261526b565b604082019050919050565b60006142b8602783614b2b565b91506142c3826152ba565b604082019050919050565b60006142db602483614b2b565b91506142e682615309565b604082019050919050565b60006142fe602183614b2b565b915061430982615358565b604082019050919050565b6000614321602583614b2b565b915061432c826153a7565b604082019050919050565b6000614344602683614b2b565b915061434f826153f6565b604082019050919050565b6000614367602483614b2b565b915061437282615445565b604082019050919050565b600061438a601683614b2b565b915061439582615494565b602082019050919050565b60006143ad601783614b3c565b91506143b8826154bd565b601782019050919050565b60006143d0602583614b2b565b91506143db826154e6565b604082019050919050565b60006143f3601183614b3c565b91506143fe82615535565b601182019050919050565b6000614416602f83614b2b565b91506144218261555e565b604082019050919050565b6000614439601f83614b2b565b9150614444826155ad565b602082019050919050565b604082016000820151614465600085018261449c565b506020820151614478602085018261447e565b50505050565b61448781614cd0565b82525050565b61449681614cf8565b82525050565b6144a581614d02565b82525050565b6144b481614d02565b82525050565b6144c381614d12565b82525050565b60006144d482614170565b91506144e08285613f6e565b6020820191506144f08284613f6e565b6020820191508190509392505050565b600061450b826143a0565b91506145178285613fbe565b9150614522826143e6565b915061452e8284613fbe565b91508190509392505050565b600060208201905061454f6000830184613f41565b92915050565b600060208201905061456a6000830184613f50565b92915050565b60006020820190506145856000830184613f5f565b92915050565b600060c0820190506145a06000830189613f5f565b6145ad6020830188613f41565b6145ba6040830187613f41565b6145c7606083018661448d565b6145d4608083018561448d565b6145e160a083018461448d565b979650505050505050565b60006080820190506146016000830187613f5f565b61460e6020830186613f41565b61461b604083018561448d565b614628606083018461448d565b95945050505050565b600060a0820190506146466000830188613f5f565b6146536020830187613f5f565b6146606040830186613f5f565b61466d606083018561448d565b61467a6080830184613f41565b9695505050505050565b60006080820190506146996000830187613f5f565b6146a660208301866144ba565b6146b36040830185613f5f565b6146c06060830184613f5f565b95945050505050565b600060208201905081810360008301526146e38184613f85565b905092915050565b6000602082019050818103600083015261470481613fef565b9050919050565b6000602082019050818103600083015261472481614012565b9050919050565b6000602082019050818103600083015261474481614035565b9050919050565b6000602082019050818103600083015261476481614058565b9050919050565b600060208201905081810360008301526147848161407b565b9050919050565b600060208201905081810360008301526147a48161409e565b9050919050565b600060208201905081810360008301526147c4816140c1565b9050919050565b600060208201905081810360008301526147e4816140e4565b9050919050565b6000602082019050818103600083015261480481614107565b9050919050565b600060208201905081810360008301526148248161412a565b9050919050565b600060208201905081810360008301526148448161414d565b9050919050565b6000602082019050818103600083015261486481614193565b9050919050565b60006020820190508181036000830152614884816141b6565b9050919050565b600060208201905081810360008301526148a4816141d9565b9050919050565b600060208201905081810360008301526148c4816141fc565b9050919050565b600060208201905081810360008301526148e48161421f565b9050919050565b6000602082019050818103600083015261490481614242565b9050919050565b6000602082019050818103600083015261492481614265565b9050919050565b6000602082019050818103600083015261494481614288565b9050919050565b60006020820190508181036000830152614964816142ab565b9050919050565b60006020820190508181036000830152614984816142ce565b9050919050565b600060208201905081810360008301526149a4816142f1565b9050919050565b600060208201905081810360008301526149c481614314565b9050919050565b600060208201905081810360008301526149e481614337565b9050919050565b60006020820190508181036000830152614a048161435a565b9050919050565b60006020820190508181036000830152614a248161437d565b9050919050565b60006020820190508181036000830152614a44816143c3565b9050919050565b60006020820190508181036000830152614a6481614409565b9050919050565b60006020820190508181036000830152614a848161442c565b9050919050565b6000604082019050614aa0600083018461444f565b92915050565b6000602082019050614abb600083018461448d565b92915050565b6000604082019050614ad6600083018561448d565b614ae3602083018461448d565b9392505050565b6000602082019050614aff60008301846144ab565b92915050565b6000602082019050614b1a60008301846144ba565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000614b5282614cf8565b9150614b5d83614cf8565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614b9257614b91614db8565b5b828201905092915050565b6000614ba882614cf8565b9150614bb383614cf8565b925082614bc357614bc2614de7565b5b828204905092915050565b6000614bd982614cf8565b9150614be483614cf8565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614c1d57614c1c614db8565b5b828202905092915050565b6000614c3382614cf8565b9150614c3e83614cf8565b925082821015614c5157614c50614db8565b5b828203905092915050565b6000614c6782614cb0565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b60005b83811015614d3d578082015181840152602081019050614d22565b83811115614d4c576000848401525b50505050565b6000614d5d82614cf8565b91506000821415614d7157614d70614db8565b5b600182039050919050565b60006002820490506001821680614d9457607f821691505b60208210811415614da857614da7614e16565b5b50919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f4552433230536e617073686f743a206e6f6e6578697374656e74206964000000600082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e656400600082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f4552433230566f7465733a207369676e61747572652065787069726564000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f4552433230566f7465733a20696e76616c6964206e6f6e636500000000000000600082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f45524332305065726d69743a206578706972656420646561646c696e65000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f45434453413a20696e76616c6964207369676e6174757265202776272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305065726d69743a20696e76616c6964207369676e61747572650000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206160008201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000602082015250565b7f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60008201527f766572666c6f77696e6720766f74657300000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203260008201527f3234206269747300000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f7760008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f53616665436173743a2076616c756520646f65736e27742066697420696e203360008201527f3220626974730000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433230536e617073686f743a206964206973203000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b6155df81614c5c565b81146155ea57600080fd5b50565b6155f681614c7a565b811461560157600080fd5b50565b61560d81614c84565b811461561857600080fd5b50565b61562481614cf8565b811461562f57600080fd5b50565b61563b81614d02565b811461564657600080fd5b50565b61565281614d12565b811461565d57600080fd5b5056fea2646970667358221220eadf1df264f069e0acb0c78903f347238b3b72f8b6f0758d54a3c7c7891b47c064736f6c63430008020033

Deployed Bytecode Sourcemap

85419:1609:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41710:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52391:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54558:169;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53511:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55209:492;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43121:123;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43506:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53353:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64770:115;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44554:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56110:215;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68519:251;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86132:77;;;:::i;:::-;;84566:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80117:266;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67919:119;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70958:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37962:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67675:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85533:66;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53682:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84976:368;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64512:128;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86051:73;;;:::i;:::-;;69059:242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42006:139;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52610:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85962:81;;;:::i;:::-;;80487:234;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68122:195;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41097:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56828:413;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54022:175;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71145:582;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63801:645;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43898:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54260:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85606:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67445:150;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41710:204;41795:4;41834:32;41819:47;;;:11;:47;;;;:87;;;;41870:36;41894:11;41870:23;:36::i;:::-;41819:87;41812:94;;41710:204;;;:::o;52391:100::-;52445:13;52478:5;52471:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52391:100;:::o;54558:169::-;54641:4;54658:39;54667:12;:10;:12::i;:::-;54681:7;54690:6;54658:8;:39::i;:::-;54715:4;54708:11;;54558:169;;;;:::o;53511:108::-;53572:7;53599:12;;53592:19;;53511:108;:::o;55209:492::-;55349:4;55366:36;55376:6;55384:9;55395:6;55366:9;:36::i;:::-;55415:24;55442:11;:19;55454:6;55442:19;;;;;;;;;;;;;;;:33;55462:12;:10;:12::i;:::-;55442:33;;;;;;;;;;;;;;;;55415:60;;55514:6;55494:16;:26;;55486:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;55601:57;55610:6;55618:12;:10;:12::i;:::-;55651:6;55632:16;:25;55601:8;:57::i;:::-;55689:4;55682:11;;;55209:492;;;;;:::o;43121:123::-;43187:7;43214:6;:12;43221:4;43214:12;;;;;;;;;;;:22;;;43207:29;;43121:123;;;:::o;43506:147::-;43589:18;43602:4;43589:12;:18::i;:::-;41588:30;41599:4;41605:12;:10;:12::i;:::-;41588:10;:30::i;:::-;43620:25:::1;43631:4;43637:7;43620:10;:25::i;:::-;43506:147:::0;;;:::o;53353:93::-;53411:5;53436:2;53429:9;;53353:93;:::o;64770:115::-;64830:7;64857:20;:18;:20::i;:::-;64850:27;;64770:115;:::o;44554:218::-;44661:12;:10;:12::i;:::-;44650:23;;:7;:23;;;44642:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;44738:26;44750:4;44756:7;44738:11;:26::i;:::-;44554:218;;:::o;56110:215::-;56198:4;56215:80;56224:12;:10;:12::i;:::-;56238:7;56284:10;56247:11;:25;56259:12;:10;:12::i;:::-;56247:25;;;;;;;;;;;;;;;:34;56273:7;56247:34;;;;;;;;;;;;;;;;:47;;;;:::i;:::-;56215:8;:80::i;:::-;56313:4;56306:11;;56110:215;;;;:::o;68519:251::-;68600:7;68642:12;68628:11;:26;68620:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;68708:54;68727:12;:21;68740:7;68727:21;;;;;;;;;;;;;;;68750:11;68708:18;:54::i;:::-;68701:61;;68519:251;;;;:::o;86132:77::-;85644:24;41588:30;41599:4;41605:12;:10;:12::i;:::-;41588:10;:30::i;:::-;86191:10:::1;:8;:10::i;:::-;86132:77:::0;:::o;84566:91::-;84622:27;84628:12;:10;:12::i;:::-;84642:6;84622:5;:27::i;:::-;84566:91;:::o;80117:266::-;80204:7;80225:16;80243:13;80260:55;80269:10;80281:24;:33;80306:7;80281:33;;;;;;;;;;;;;;;80260:8;:55::i;:::-;80224:91;;;;80335:11;:40;;80357:18;80367:7;80357:9;:18::i;:::-;80335:40;;;80349:5;80335:40;80328:47;;;;80117:266;;;;:::o;67919:119::-;67984:7;68011:10;:19;68022:7;68011:19;;;;;;;;;;;;;;;;;;;;;;;;;68004:26;;67919:119;;;:::o;70958:105::-;71021:34;71031:12;:10;:12::i;:::-;71045:9;71021;:34::i;:::-;70958:105;:::o;37962:86::-;38009:4;38033:7;;;;;;;;;;;38026:14;;37962:86;:::o;67675:151::-;67745:6;67771:47;67789:12;:21;67802:7;67789:21;;;;;;;;;;;;;;;:28;;;;67771:17;:47::i;:::-;67764:54;;67675:151;;;:::o;85533:66::-;85573:26;85533:66;:::o;53682:127::-;53756:7;53783:9;:18;53793:7;53783:18;;;;;;;;;;;;;;;;53776:25;;53682:127;;;:::o;84976:368::-;85053:24;85080:32;85090:7;85099:12;:10;:12::i;:::-;85080:9;:32::i;:::-;85053:59;;85151:6;85131:16;:26;;85123:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;85234:58;85243:7;85252:12;:10;:12::i;:::-;85285:6;85266:16;:25;85234:8;:58::i;:::-;85314:22;85320:7;85329:6;85314:5;:22::i;:::-;84976:368;;;:::o;64512:128::-;64581:7;64608:24;:7;:14;64616:5;64608:14;;;;;;;;;;;;;;;:22;:24::i;:::-;64601:31;;64512:128;;;:::o;86051:73::-;85644:24;41588:30;41599:4;41605:12;:10;:12::i;:::-;41588:10;:30::i;:::-;86108:8:::1;:6;:8::i;:::-;86051:73:::0;:::o;69059:242::-;69129:7;69171:12;69157:11;:26;69149:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;69237:56;69256:23;69281:11;69237:18;:56::i;:::-;69230:63;;69059:242;;;:::o;42006:139::-;42084:4;42108:6;:12;42115:4;42108:12;;;;;;;;;;;:20;;:29;42129:7;42108:29;;;;;;;;;;;;;;;;;;;;;;;;;42101:36;;42006:139;;;;:::o;52610:104::-;52666:13;52699:7;52692:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52610:104;:::o;85962:81::-;85573:26;41588:30;41599:4;41605:12;:10;:12::i;:::-;41588:10;:30::i;:::-;86024:11:::1;:9;:11::i;:::-;;85962:81:::0;:::o;80487:234::-;80559:7;80580:16;80598:13;80615:43;80624:10;80636:21;80615:8;:43::i;:::-;80579:79;;;;80678:11;:35;;80700:13;:11;:13::i;:::-;80678:35;;;80692:5;80678:35;80671:42;;;;80487:234;;;:::o;68122:195::-;68178:7;68198:11;68212:12;:21;68225:7;68212:21;;;;;;;;;;;;;;;:28;;;;68198:42;;68265:1;68258:3;:8;:51;;68273:12;:21;68286:7;68273:21;;;;;;;;;;;;;;;68301:1;68295:3;:7;;;;:::i;:::-;68273:30;;;;;;;;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;68258:51;;;68269:1;68258:51;68251:58;;;;;68122:195;;;:::o;41097:49::-;41142:4;41097:49;;;:::o;56828:413::-;56921:4;56938:24;56965:11;:25;56977:12;:10;:12::i;:::-;56965:25;;;;;;;;;;;;;;;:34;56991:7;56965:34;;;;;;;;;;;;;;;;56938:61;;57038:15;57018:16;:35;;57010:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;57131:67;57140:12;:10;:12::i;:::-;57154:7;57182:15;57163:16;:34;57131:8;:67::i;:::-;57229:4;57222:11;;;56828:413;;;;:::o;54022:175::-;54108:4;54125:42;54135:12;:10;:12::i;:::-;54149:9;54160:6;54125:9;:42::i;:::-;54185:4;54178:11;;54022:175;;;;:::o;71145:582::-;71363:6;71344:15;:25;;71336:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;71414:14;71431:174;71459:87;66696:71;71519:9;71530:5;71537:6;71486:58;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;71476:69;;;;;;71459:16;:87::i;:::-;71561:1;71577;71593;71431:13;:174::i;:::-;71414:191;;71633:17;71643:6;71633:9;:17::i;:::-;71624:5;:26;71616:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;71691:28;71701:6;71709:9;71691;:28::i;:::-;71145:582;;;;;;;:::o;63801:645::-;64045:8;64026:15;:27;;64018:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;64100:18;64142:16;64160:5;64167:7;64176:5;64183:16;64193:5;64183:9;:16::i;:::-;64201:8;64131:79;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64121:90;;;;;;64100:111;;64224:12;64239:28;64256:10;64239:16;:28::i;:::-;64224:43;;64280:14;64297:28;64311:4;64317:1;64320;64323;64297:13;:28::i;:::-;64280:45;;64354:5;64344:15;;:6;:15;;;64336:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;64407:31;64416:5;64423:7;64432:5;64407:8;:31::i;:::-;63801:645;;;;;;;;;;:::o;43898:149::-;43982:18;43995:4;43982:12;:18::i;:::-;41588:30;41599:4;41605:12;:10;:12::i;:::-;41588:10;:30::i;:::-;44013:26:::1;44025:4;44031:7;44013:11;:26::i;:::-;43898:149:::0;;;:::o;54260:151::-;54349:7;54376:11;:18;54388:5;54376:18;;;;;;;;;;;;;;;:27;54395:7;54376:27;;;;;;;;;;;;;;;;54369:34;;54260:151;;;;:::o;85606:62::-;85644:24;85606:62;:::o;67445:150::-;67524:17;;:::i;:::-;67561:12;:21;67574:7;67561:21;;;;;;;;;;;;;;;67583:3;67561:26;;;;;;;;;;;;;;;;;;;;;;;;;67554:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67445:150;;;;:::o;72033:290::-;72118:28;72130:7;72139:6;72118:11;:28::i;:::-;72182:12;:10;:12::i;:::-;72165:29;;:13;:11;:13::i;:::-;:29;;72157:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;72260:55;72277:23;72302:4;72308:6;72260:16;:55::i;:::-;;;72033:290;;:::o;58751:399::-;58854:1;58835:21;;:7;:21;;;;58827:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;58905:49;58934:1;58938:7;58947:6;58905:20;:49::i;:::-;58983:6;58967:12;;:22;;;;;;;:::i;:::-;;;;;;;;59022:6;59000:9;:18;59010:7;59000:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;59065:7;59044:37;;59061:1;59044:37;;;59074:6;59044:37;;;;;;:::i;:::-;;;;;;;;59094:48;59122:1;59126:7;59135:6;59094:19;:48::i;:::-;58751:399;;:::o;74877:98::-;74935:7;74966:1;74962;:5;;;;:::i;:::-;74955:12;;74877:98;;;;:::o;1216:195::-;1273:7;1310:17;1301:26;;:5;:26;;1293:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;1397:5;1382:21;;1216:195;;;:::o;3186:190::-;3242:6;3278:16;3269:25;;:5;:25;;3261:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;3362:5;3348:20;;3186:190;;;:::o;80938:622::-;81081:44;81108:4;81114:2;81118:6;81081:26;:44::i;:::-;81158:1;81142:18;;:4;:18;;;81138:415;;;81198:26;81221:2;81198:22;:26::i;:::-;81239:28;:26;:28::i;:::-;81138:415;;;81303:1;81289:16;;:2;:16;;;81285:268;;;81343:28;81366:4;81343:22;:28::i;:::-;81386;:26;:28::i;:::-;81285:268;;;81472:28;81495:4;81472:22;:28::i;:::-;81515:26;81538:2;81515:22;:26::i;:::-;81285:268;81138:415;80938:622;;;:::o;72751:262::-;72893:43;72919:4;72925:2;72929:6;72893:25;:43::i;:::-;72949:56;72966:15;72976:4;72966:9;:15::i;:::-;72983:13;72993:2;72983:9;:13::i;:::-;72998:6;72949:16;:56::i;:::-;72751:262;;;:::o;61492:125::-;;;;:::o;62221:124::-;;;;:::o;74983:103::-;75046:7;75077:1;75073;:5;;;;:::i;:::-;75066:12;;74983:103;;;;:::o;32544:114::-;32609:7;32636;:14;;;32629:21;;32544:114;;;:::o;12216:157::-;12301:4;12340:25;12325:40;;;:11;:40;;;;12318:47;;12216:157;;;:::o;36630:98::-;36683:7;36710:10;36703:17;;36630:98;:::o;60512:380::-;60665:1;60648:19;;:5;:19;;;;60640:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;60746:1;60727:21;;:7;:21;;;;60719:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;60830:6;60800:11;:18;60812:5;60800:18;;;;;;;;;;;;;;;:27;60819:7;60800:27;;;;;;;;;;;;;;;:36;;;;60868:7;60852:32;;60861:5;60852:32;;;60877:6;60852:32;;;;;;:::i;:::-;;;;;;;;60512:380;;;:::o;57731:733::-;57889:1;57871:20;;:6;:20;;;;57863:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;57973:1;57952:23;;:9;:23;;;;57944:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;58028:47;58049:6;58057:9;58068:6;58028:20;:47::i;:::-;58088:21;58112:9;:17;58122:6;58112:17;;;;;;;;;;;;;;;;58088:41;;58165:6;58148:13;:23;;58140:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;58286:6;58270:13;:22;58250:9;:17;58260:6;58250:17;;;;;;;;;;;;;;;:42;;;;58338:6;58314:9;:20;58324:9;58314:20;;;;;;;;;;;;;;;;:30;;;;;;;:::i;:::-;;;;;;;;58379:9;58362:35;;58371:6;58362:35;;;58390:6;58362:35;;;;;;:::i;:::-;;;;;;;;58410:46;58430:6;58438:9;58449:6;58410:19;:46::i;:::-;57731:733;;;;:::o;42435:497::-;42516:22;42524:4;42530:7;42516;:22::i;:::-;42511:414;;42704:41;42732:7;42704:41;;42742:2;42704:19;:41::i;:::-;42818:38;42846:4;42838:13;;42853:2;42818:19;:38::i;:::-;42609:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42555:358;;;;;;;;;;;:::i;:::-;;;;;;;;42511:414;42435:497;;:::o;46055:238::-;46139:22;46147:4;46153:7;46139;:22::i;:::-;46134:152;;46210:4;46178:6;:12;46185:4;46178:12;;;;;;;;;;;:20;;:29;46199:7;46178:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;46261:12;:10;:12::i;:::-;46234:40;;46252:7;46234:40;;46246:4;46234:40;;;;;;;;;;46134:152;46055:238;;:::o;27258:314::-;27311:7;27352:12;27335:29;;27343:4;27335:29;;;:66;;;;;27385:16;27368:13;:33;27335:66;27331:234;;;27425:24;27418:31;;;;27331:234;27489:64;27511:10;27523:12;27537:15;27489:21;:64::i;:::-;27482:71;;27258:314;;:::o;46425:239::-;46509:22;46517:4;46523:7;46509;:22::i;:::-;46505:152;;;46580:5;46548:6;:12;46555:4;46548:12;;;;;;;;;;;:20;;:29;46569:7;46548:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;46632:12;:10;:12::i;:::-;46605:40;;46623:7;46605:40;;46617:4;46605:40;;;;;;;;;;46505:152;46425:239;;:::o;69390:1482::-;69489:7;70508:12;70523:5;:12;;;;70508:27;;70546:11;70572:236;70585:4;70579:3;:10;70572:236;;;70606:11;70620:23;70633:3;70638:4;70620:12;:23::i;:::-;70606:37;;70685:11;70662:5;70668:3;70662:10;;;;;;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;:34;;;70658:139;;;70724:3;70717:10;;70658:139;;;70780:1;70774:3;:7;;;;:::i;:::-;70768:13;;70658:139;70572:236;;;;70835:1;70827:4;:9;:37;;70843:5;70856:1;70849:4;:8;;;;:::i;:::-;70843:15;;;;;;;;;;;;;;;;;;;;;;;:21;;;;;;;;;;;;70827:37;;;70839:1;70827:37;70820:44;;;;;;69390:1482;;;;:::o;39021:120::-;38565:8;:6;:8::i;:::-;38557:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;39090:5:::1;39080:7;;:15;;;;;;;;;;;;;;;;;;39111:22;39120:12;:10;:12::i;:::-;39111:22;;;;;;:::i;:::-;;;;;;;;39021:120::o:0;86870:155::-;86989:28;87001:7;87010:6;86989:11;:28::i;:::-;86870:155;;:::o;81568:1619::-;81657:4;81663:7;81704:1;81691:10;:14;81683:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;81765:23;:21;:23::i;:::-;81751:10;:37;;81743:79;;;;;;;;;;;;:::i;:::-;;;;;;;;;82961:13;82977:40;83006:10;82977:9;:13;;:28;;:40;;;;:::i;:::-;82961:56;;83043:9;:13;;:20;;;;83034:5;:29;83030:150;;;83088:5;83095:1;83080:17;;;;;;;83030:150;83138:4;83144:9;:16;;83161:5;83144:23;;;;;;;;;;;;;;;;;;;;;;;;83130:38;;;;;81568:1619;;;;;;:::o;73177:388::-;73262:23;73288:20;73298:9;73288;:20::i;:::-;73262:46;;73319:24;73346:20;73356:9;73346;:20::i;:::-;73319:47;;73401:9;73377:10;:21;73388:9;73377:21;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;73472:9;73428:54;;73455:15;73428:54;;73444:9;73428:54;;;;;;;;;;;;73495:62;73512:15;73529:9;73540:16;73495;:62::i;:::-;73177:388;;;;:::o;38762:118::-;38288:8;:6;:8::i;:::-;38287:9;38279:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;38832:4:::1;38822:7;;:14;;;;;;;;;;;;;;;;;;38852:20;38859:12;:10;:12::i;:::-;38852:20;;;;;;:::i;:::-;;;;;;;;38762:118::o:0;79589:223::-;79636:7;79656:30;:18;:28;:30::i;:::-;79699:17;79719:23;:21;:23::i;:::-;79699:43;;79758:19;79767:9;79758:19;;;;;;:::i;:::-;;;;;;;;79795:9;79788:16;;;79589:223;:::o;28485:167::-;28562:7;28589:55;28611:20;:18;:20::i;:::-;28633:10;28589:21;:55::i;:::-;28582:62;;28485:167;;;:::o;22148:279::-;22276:7;22297:17;22316:18;22338:25;22349:4;22355:1;22358;22361;22338:10;:25::i;:::-;22296:67;;;;22374:18;22386:5;22374:11;:18::i;:::-;22410:9;22403:16;;;;22148:279;;;;;;:::o;65023:207::-;65083:15;65111:30;65144:7;:14;65152:5;65144:14;;;;;;;;;;;;;;;65111:47;;65179:15;:5;:13;:15::i;:::-;65169:25;;65205:17;:5;:15;:17::i;:::-;65023:207;;;;:::o;71834:105::-;71887:7;71914:17;71907:24;;71834:105;:::o;74224:645::-;74398:17;74417;74447:11;74461:5;:12;;;;74447:26;;74503:1;74496:3;:8;:35;;74511:5;74523:1;74517:3;:7;;;;:::i;:::-;74511:14;;;;;;;;;;;;;;;;;;;;;;;:20;;;;;;;;;;;;74496:35;;;74507:1;74496:35;74484:47;;;;74554:20;74557:9;74568:5;74554:2;:20;;:::i;:::-;74542:32;;74597:1;74591:3;:7;:51;;;;;74630:12;74602:5;74614:1;74608:3;:7;;;;:::i;:::-;74602:14;;;;;;;;;;;;;;;;;;;;;;;:24;;;;;;;;;;;;:40;;;74591:51;74587:275;;;74682:29;74701:9;74682:18;:29::i;:::-;74659:5;74671:1;74665:3;:7;;;;:::i;:::-;74659:14;;;;;;;;;;;;;;;;;;;;;;;:20;;;:52;;;;;;;;;;;;;;;;;;74587:275;;;74744:5;74755:94;;;;;;;;74778:31;74796:12;74778:17;:31::i;:::-;74755:94;;;;;;74818:29;74837:9;74818:18;:29::i;:::-;74755:94;;;;;74744:106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74587:275;74224:645;;;;;;;:::o;86217:221::-;38288:8;:6;:8::i;:::-;38287:9;38279:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;86386:44:::1;86413:4;86419:2;86423:6;86386:26;:44::i;:::-;86217:221:::0;;;:::o;86516:193::-;86658:43;86684:4;86690:2;86694:6;86658:25;:43::i;:::-;86516:193;;;:::o;83195:146::-;83263:70;83279:24;:33;83304:7;83279:33;;;;;;;;;;;;;;;83314:18;83324:7;83314:9;:18::i;:::-;83263:15;:70::i;:::-;83195:146;:::o;83349:118::-;83406:53;83422:21;83445:13;:11;:13::i;:::-;83406:15;:53::i;:::-;83349:118::o;73573:643::-;73705:3;73698:10;;:3;:10;;;;:24;;;;;73721:1;73712:6;:10;73698:24;73694:515;;;73758:1;73743:17;;:3;:17;;;73739:224;;73782:17;73801;73822:54;73839:12;:17;73852:3;73839:17;;;;;;;;;;;;;;;73858:9;73869:6;73822:16;:54::i;:::-;73781:95;;;;73921:3;73900:47;;;73926:9;73937;73900:47;;;;;;;:::i;:::-;;;;;;;;73739:224;;;73998:1;73983:17;;:3;:17;;;73979:219;;74022:17;74041;74062:49;74079:12;:17;74092:3;74079:17;;;;;;;;;;;;;;;74098:4;74104:6;74062:16;:49::i;:::-;74021:90;;;;74156:3;74135:47;;;74161:9;74172;74135:47;;;;;;;:::i;:::-;;;;;;;;73979:219;;;73694:515;73573:643;;;:::o;14032:451::-;14107:13;14133:19;14178:1;14169:6;14165:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;14155:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14133:47;;14191:15;:6;14198:1;14191:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;14217;:6;14224:1;14217:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;14248:9;14273:1;14264:6;14260:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;14248:26;;14243:135;14280:1;14276;:5;14243:135;;;14315:12;14336:3;14328:5;:11;14315:25;;;;;;;;;;;;;;;;;;14303:6;14310:1;14303:9;;;;;;;;;;;;;;;;;;;:37;;;;;;;;;;;14365:1;14355:11;;;;;14283:3;;;;:::i;:::-;;;14243:135;;;;14405:1;14396:5;:10;14388:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;14468:6;14454:21;;;14032:451;;;;:::o;27580:263::-;27724:7;27772:8;27782;27792:11;27805:13;27828:4;27761:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;27751:84;;;;;;27744:91;;27580:263;;;;;:::o;33838:156::-;33900:7;33985:1;33980;33976;:5;33975:11;;;;:::i;:::-;33970:1;33966;:5;33965:21;;;;:::i;:::-;33958:28;;33838:156;;;;:::o;72417:194::-;72502:28;72514:7;72523:6;72502:11;:28::i;:::-;72543:60;72560:23;72585:9;72596:6;72543:16;:60::i;:::-;;;72417:194;;:::o;79878:127::-;79942:7;79969:28;:18;:26;:28::i;:::-;79962:35;;79878:127;:::o;35040:918::-;35129:7;35169:1;35153:5;:12;;;;:17;35149:58;;;35194:1;35187:8;;;;35149:58;35219:11;35245:12;35260:5;:12;;;;35245:27;;35285:424;35298:4;35292:3;:10;35285:424;;;35319:11;35333:23;35346:3;35351:4;35333:12;:23::i;:::-;35319:37;;35590:7;35577:5;35583:3;35577:10;;;;;;;;;;;;;;;;;;;;;;;;:20;35573:125;;;35625:3;35618:10;;35573:125;;;35681:1;35675:3;:7;;;;:::i;:::-;35669:13;;35573:125;35285:424;;;;35835:1;35829:3;:7;:36;;;;;35858:7;35840:5;35852:1;35846:3;:7;;;;:::i;:::-;35840:14;;;;;;;;;;;;;;;;;;;;;;;;:25;35829:36;35825:126;;;35895:1;35889:3;:7;;;;:::i;:::-;35882:14;;;;;;35825:126;35936:3;35929:10;;;;35040:918;;;;;:::o;32666:127::-;32773:1;32755:7;:14;;;:19;;;;;;;;;;;32666:127;:::o;23839:196::-;23932:7;23998:15;24015:10;23969:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;23959:68;;;;;;23952:75;;23839:196;;;;:::o;20377:1632::-;20508:7;20517:12;21442:66;21437:1;21429:10;;:79;21425:163;;;21541:1;21545:30;21525:51;;;;;;21425:163;21607:2;21602:1;:7;;;;:18;;;;;21618:2;21613:1;:7;;;;21602:18;21598:102;;;21653:1;21657:30;21637:51;;;;;;21598:102;21797:14;21814:24;21824:4;21830:1;21833;21836;21814:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21797:41;;21871:1;21853:20;;:6;:20;;;21849:103;;;21906:1;21910:29;21890:50;;;;;;;21849:103;21972:6;21980:20;21964:37;;;;;20377:1632;;;;;;;;:::o;15039:643::-;15117:20;15108:29;;;;;;;;;;;;;;;;:5;:29;;;;;;;;;;;;;;;;;15104:571;;;15154:7;;15104:571;15215:29;15206:38;;;;;;;;;;;;;;;;:5;:38;;;;;;;;;;;;;;;;;15202:473;;;15261:34;;;;;;;;;;:::i;:::-;;;;;;;;15202:473;15326:35;15317:44;;;;;;;;;;;;;;;;:5;:44;;;;;;;;;;;;;;;;;15313:362;;;15378:41;;;;;;;;;;:::i;:::-;;;;;;;;15313:362;15450:30;15441:39;;;;;;;;;;;;;;;;:5;:39;;;;;;;;;;;;;;;;;15437:238;;;15497:44;;;;;;;;;;:::i;:::-;;;;;;;;15437:238;15572:30;15563:39;;;;;;;;;;;;;;;;:5;:39;;;;;;;;;;;;;;;;;15559:116;;;15619:44;;;;;;;;;;:::i;:::-;;;;;;;;15559:116;15039:643;;:::o;83475:310::-;83570:17;83590:23;:21;:23::i;:::-;83570:43;;83661:9;83628:30;83644:9;:13;;83628:15;:30::i;:::-;:42;83624:154;;;83687:9;:13;;83706:9;83687:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83731:9;:16;;83753:12;83731:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83624:154;83475:310;;;:::o;59483:591::-;59586:1;59567:21;;:7;:21;;;;59559:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;59639:49;59660:7;59677:1;59681:6;59639:20;:49::i;:::-;59701:22;59726:9;:18;59736:7;59726:18;;;;;;;;;;;;;;;;59701:43;;59781:6;59763:14;:24;;59755:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;59900:6;59883:14;:23;59862:9;:18;59872:7;59862:18;;;;;;;;;;;;;;;:44;;;;59944:6;59928:12;;:22;;;;;;;:::i;:::-;;;;;;;;59994:1;59968:37;;59977:7;59968:37;;;59998:6;59968:37;;;;;;:::i;:::-;;;;;;;;60018:48;60038:7;60055:1;60059:6;60018:19;:48::i;:::-;59483:591;;;:::o;83793:212::-;83863:7;83901:1;83887:3;:10;;;;:15;83883:115;;;83926:1;83919:8;;;;83883:115;83967:3;83984:1;83971:3;:10;;;;:14;;;;:::i;:::-;83967:19;;;;;;;;;;;;;;;;;;;;;;;;83960:26;;83793: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:137::-;;380:6;367:20;358:29;;396:32;422:5;396:32;:::i;:::-;348:86;;;;:::o;440:139::-;;524:6;511:20;502:29;;540:33;567:5;540:33;:::i;:::-;492:87;;;;:::o;585:137::-;;668:6;655:20;646:29;;684:32;710:5;684:32;:::i;:::-;636:86;;;;:::o;728:135::-;;810:6;797:20;788:29;;826:31;851:5;826:31;:::i;:::-;778:85;;;;:::o;869:262::-;;977:2;965:9;956:7;952:23;948:32;945:2;;;993:1;990;983:12;945:2;1036:1;1061:53;1106:7;1097:6;1086:9;1082:22;1061:53;:::i;:::-;1051:63;;1007:117;935:196;;;;:::o;1137:407::-;;;1262:2;1250:9;1241:7;1237:23;1233:32;1230:2;;;1278:1;1275;1268:12;1230:2;1321:1;1346:53;1391:7;1382:6;1371:9;1367:22;1346:53;:::i;:::-;1336:63;;1292:117;1448:2;1474:53;1519:7;1510:6;1499:9;1495:22;1474:53;:::i;:::-;1464:63;;1419:118;1220:324;;;;;:::o;1550:552::-;;;;1692:2;1680:9;1671:7;1667:23;1663:32;1660:2;;;1708:1;1705;1698:12;1660:2;1751:1;1776:53;1821:7;1812:6;1801:9;1797:22;1776:53;:::i;:::-;1766:63;;1722:117;1878:2;1904:53;1949:7;1940:6;1929:9;1925:22;1904:53;:::i;:::-;1894:63;;1849:118;2006:2;2032:53;2077:7;2068:6;2057:9;2053:22;2032:53;:::i;:::-;2022:63;;1977:118;1650:452;;;;;:::o;2108:1132::-;;;;;;;;2316:3;2304:9;2295:7;2291:23;2287:33;2284:2;;;2333:1;2330;2323:12;2284:2;2376:1;2401:53;2446:7;2437:6;2426:9;2422:22;2401:53;:::i;:::-;2391:63;;2347:117;2503:2;2529:53;2574:7;2565:6;2554:9;2550:22;2529:53;:::i;:::-;2519:63;;2474:118;2631:2;2657:53;2702:7;2693:6;2682:9;2678:22;2657:53;:::i;:::-;2647:63;;2602:118;2759:2;2785:53;2830:7;2821:6;2810:9;2806:22;2785:53;:::i;:::-;2775:63;;2730:118;2887:3;2914:51;2957:7;2948:6;2937:9;2933:22;2914:51;:::i;:::-;2904:61;;2858:117;3014:3;3041:53;3086:7;3077:6;3066:9;3062:22;3041:53;:::i;:::-;3031:63;;2985:119;3143:3;3170:53;3215:7;3206:6;3195:9;3191:22;3170:53;:::i;:::-;3160:63;;3114:119;2274:966;;;;;;;;;;:::o;3246:407::-;;;3371:2;3359:9;3350:7;3346:23;3342:32;3339:2;;;3387:1;3384;3377:12;3339:2;3430:1;3455:53;3500:7;3491:6;3480:9;3476:22;3455:53;:::i;:::-;3445:63;;3401:117;3557:2;3583:53;3628:7;3619:6;3608:9;3604:22;3583:53;:::i;:::-;3573:63;;3528:118;3329:324;;;;;:::o;3659:986::-;;;;;;;3850:3;3838:9;3829:7;3825:23;3821:33;3818:2;;;3867:1;3864;3857:12;3818:2;3910:1;3935:53;3980:7;3971:6;3960:9;3956:22;3935:53;:::i;:::-;3925:63;;3881:117;4037:2;4063:53;4108:7;4099:6;4088:9;4084:22;4063:53;:::i;:::-;4053:63;;4008:118;4165:2;4191:53;4236:7;4227:6;4216:9;4212:22;4191:53;:::i;:::-;4181:63;;4136:118;4293:2;4319:51;4362:7;4353:6;4342:9;4338:22;4319:51;:::i;:::-;4309:61;;4264:116;4419:3;4446:53;4491:7;4482:6;4471:9;4467:22;4446:53;:::i;:::-;4436:63;;4390:119;4548:3;4575:53;4620:7;4611:6;4600:9;4596:22;4575:53;:::i;:::-;4565:63;;4519:119;3808:837;;;;;;;;:::o;4651:405::-;;;4775:2;4763:9;4754:7;4750:23;4746:32;4743:2;;;4791:1;4788;4781:12;4743:2;4834:1;4859:53;4904:7;4895:6;4884:9;4880:22;4859:53;:::i;:::-;4849:63;;4805:117;4961:2;4987:52;5031:7;5022:6;5011:9;5007:22;4987:52;:::i;:::-;4977:62;;4932:117;4733:323;;;;;:::o;5062:262::-;;5170:2;5158:9;5149:7;5145:23;5141:32;5138:2;;;5186:1;5183;5176:12;5138:2;5229:1;5254:53;5299:7;5290:6;5279:9;5275:22;5254:53;:::i;:::-;5244:63;;5200:117;5128:196;;;;:::o;5330:407::-;;;5455:2;5443:9;5434:7;5430:23;5426:32;5423:2;;;5471:1;5468;5461:12;5423:2;5514:1;5539:53;5584:7;5575:6;5564:9;5560:22;5539:53;:::i;:::-;5529:63;;5485:117;5641:2;5667:53;5712:7;5703:6;5692:9;5688:22;5667:53;:::i;:::-;5657:63;;5612:118;5413:324;;;;;:::o;5743:260::-;;5850:2;5838:9;5829:7;5825:23;5821:32;5818:2;;;5866:1;5863;5856:12;5818:2;5909:1;5934:52;5978:7;5969:6;5958:9;5954:22;5934:52;:::i;:::-;5924:62;;5880:116;5808:195;;;;:::o;6009:262::-;;6117:2;6105:9;6096:7;6092:23;6088:32;6085:2;;;6133:1;6130;6123:12;6085:2;6176:1;6201:53;6246:7;6237:6;6226:9;6222:22;6201:53;:::i;:::-;6191:63;;6147:117;6075:196;;;;:::o;6277:118::-;6364:24;6382:5;6364:24;:::i;:::-;6359:3;6352:37;6342:53;;:::o;6401:109::-;6482:21;6497:5;6482:21;:::i;:::-;6477:3;6470:34;6460:50;;:::o;6516:118::-;6603:24;6621:5;6603:24;:::i;:::-;6598:3;6591:37;6581:53;;:::o;6640:157::-;6745:45;6765:24;6783:5;6765:24;:::i;:::-;6745:45;:::i;:::-;6740:3;6733:58;6723:74;;:::o;6803:364::-;;6919:39;6952:5;6919:39;:::i;:::-;6974:71;7038:6;7033:3;6974:71;:::i;:::-;6967:78;;7054:52;7099:6;7094:3;7087:4;7080:5;7076:16;7054:52;:::i;:::-;7131:29;7153:6;7131:29;:::i;:::-;7126:3;7122:39;7115:46;;6895:272;;;;;:::o;7173:377::-;;7307:39;7340:5;7307:39;:::i;:::-;7362:89;7444:6;7439:3;7362:89;:::i;:::-;7355:96;;7460:52;7505:6;7500:3;7493:4;7486:5;7482:16;7460:52;:::i;:::-;7537:6;7532:3;7528:16;7521:23;;7283:267;;;;;:::o;7556:366::-;;7719:67;7783:2;7778:3;7719:67;:::i;:::-;7712:74;;7795:93;7884:3;7795:93;:::i;:::-;7913:2;7908:3;7904:12;7897:19;;7702:220;;;:::o;7928:366::-;;8091:67;8155:2;8150:3;8091:67;:::i;:::-;8084:74;;8167:93;8256:3;8167:93;:::i;:::-;8285:2;8280:3;8276:12;8269:19;;8074:220;;;:::o;8300:366::-;;8463:67;8527:2;8522:3;8463:67;:::i;:::-;8456:74;;8539:93;8628:3;8539:93;:::i;:::-;8657:2;8652:3;8648:12;8641:19;;8446:220;;;:::o;8672:366::-;;8835:67;8899:2;8894:3;8835:67;:::i;:::-;8828:74;;8911:93;9000:3;8911:93;:::i;:::-;9029:2;9024:3;9020:12;9013:19;;8818:220;;;:::o;9044:366::-;;9207:67;9271:2;9266:3;9207:67;:::i;:::-;9200:74;;9283:93;9372:3;9283:93;:::i;:::-;9401:2;9396:3;9392:12;9385:19;;9190:220;;;:::o;9416:366::-;;9579:67;9643:2;9638:3;9579:67;:::i;:::-;9572:74;;9655:93;9744:3;9655:93;:::i;:::-;9773:2;9768:3;9764:12;9757:19;;9562:220;;;:::o;9788:366::-;;9951:67;10015:2;10010:3;9951:67;:::i;:::-;9944:74;;10027:93;10116:3;10027:93;:::i;:::-;10145:2;10140:3;10136:12;10129:19;;9934:220;;;:::o;10160:366::-;;10323:67;10387:2;10382:3;10323:67;:::i;:::-;10316:74;;10399:93;10488:3;10399:93;:::i;:::-;10517:2;10512:3;10508:12;10501:19;;10306:220;;;:::o;10532:366::-;;10695:67;10759:2;10754:3;10695:67;:::i;:::-;10688:74;;10771:93;10860:3;10771:93;:::i;:::-;10889:2;10884:3;10880:12;10873:19;;10678:220;;;:::o;10904:366::-;;11067:67;11131:2;11126:3;11067:67;:::i;:::-;11060:74;;11143:93;11232:3;11143:93;:::i;:::-;11261:2;11256:3;11252:12;11245:19;;11050:220;;;:::o;11276:366::-;;11439:67;11503:2;11498:3;11439:67;:::i;:::-;11432:74;;11515:93;11604:3;11515:93;:::i;:::-;11633:2;11628:3;11624:12;11617:19;;11422:220;;;:::o;11648:400::-;;11829:84;11911:1;11906:3;11829:84;:::i;:::-;11822:91;;11922:93;12011:3;11922:93;:::i;:::-;12040:1;12035:3;12031:11;12024:18;;11812:236;;;:::o;12054:366::-;;12217:67;12281:2;12276:3;12217:67;:::i;:::-;12210:74;;12293:93;12382:3;12293:93;:::i;:::-;12411:2;12406:3;12402:12;12395:19;;12200:220;;;:::o;12426:366::-;;12589:67;12653:2;12648:3;12589:67;:::i;:::-;12582:74;;12665:93;12754:3;12665:93;:::i;:::-;12783:2;12778:3;12774:12;12767:19;;12572:220;;;:::o;12798:366::-;;12961:67;13025:2;13020:3;12961:67;:::i;:::-;12954:74;;13037:93;13126:3;13037:93;:::i;:::-;13155:2;13150:3;13146:12;13139:19;;12944:220;;;:::o;13170:366::-;;13333:67;13397:2;13392:3;13333:67;:::i;:::-;13326:74;;13409:93;13498:3;13409:93;:::i;:::-;13527:2;13522:3;13518:12;13511:19;;13316:220;;;:::o;13542:366::-;;13705:67;13769:2;13764:3;13705:67;:::i;:::-;13698:74;;13781:93;13870:3;13781:93;:::i;:::-;13899:2;13894:3;13890:12;13883:19;;13688:220;;;:::o;13914:366::-;;14077:67;14141:2;14136:3;14077:67;:::i;:::-;14070:74;;14153:93;14242:3;14153:93;:::i;:::-;14271:2;14266:3;14262:12;14255:19;;14060:220;;;:::o;14286:366::-;;14449:67;14513:2;14508:3;14449:67;:::i;:::-;14442:74;;14525:93;14614:3;14525:93;:::i;:::-;14643:2;14638:3;14634:12;14627:19;;14432:220;;;:::o;14658:366::-;;14821:67;14885:2;14880:3;14821:67;:::i;:::-;14814:74;;14897:93;14986:3;14897:93;:::i;:::-;15015:2;15010:3;15006:12;14999:19;;14804:220;;;:::o;15030:366::-;;15193:67;15257:2;15252:3;15193:67;:::i;:::-;15186:74;;15269:93;15358:3;15269:93;:::i;:::-;15387:2;15382:3;15378:12;15371:19;;15176:220;;;:::o;15402:366::-;;15565:67;15629:2;15624:3;15565:67;:::i;:::-;15558:74;;15641:93;15730:3;15641:93;:::i;:::-;15759:2;15754:3;15750:12;15743:19;;15548:220;;;:::o;15774:366::-;;15937:67;16001:2;15996:3;15937:67;:::i;:::-;15930:74;;16013:93;16102:3;16013:93;:::i;:::-;16131:2;16126:3;16122:12;16115:19;;15920:220;;;:::o;16146:366::-;;16309:67;16373:2;16368:3;16309:67;:::i;:::-;16302:74;;16385:93;16474:3;16385:93;:::i;:::-;16503:2;16498:3;16494:12;16487:19;;16292:220;;;:::o;16518:366::-;;16681:67;16745:2;16740:3;16681:67;:::i;:::-;16674:74;;16757:93;16846:3;16757:93;:::i;:::-;16875:2;16870:3;16866:12;16859:19;;16664:220;;;:::o;16890:366::-;;17053:67;17117:2;17112:3;17053:67;:::i;:::-;17046:74;;17129:93;17218:3;17129:93;:::i;:::-;17247:2;17242:3;17238:12;17231:19;;17036:220;;;:::o;17262:366::-;;17425:67;17489:2;17484:3;17425:67;:::i;:::-;17418:74;;17501:93;17590:3;17501:93;:::i;:::-;17619:2;17614:3;17610:12;17603:19;;17408:220;;;:::o;17634:402::-;;17815:85;17897:2;17892:3;17815:85;:::i;:::-;17808:92;;17909:93;17998:3;17909:93;:::i;:::-;18027:2;18022:3;18018:12;18011:19;;17798:238;;;:::o;18042:366::-;;18205:67;18269:2;18264:3;18205:67;:::i;:::-;18198:74;;18281:93;18370:3;18281:93;:::i;:::-;18399:2;18394:3;18390:12;18383:19;;18188:220;;;:::o;18414:402::-;;18595:85;18677:2;18672:3;18595:85;:::i;:::-;18588:92;;18689:93;18778:3;18689:93;:::i;:::-;18807:2;18802:3;18798:12;18791:19;;18578:238;;;:::o;18822:366::-;;18985:67;19049:2;19044:3;18985:67;:::i;:::-;18978:74;;19061:93;19150:3;19061:93;:::i;:::-;19179:2;19174:3;19170:12;19163:19;;18968:220;;;:::o;19194:366::-;;19357:67;19421:2;19416:3;19357:67;:::i;:::-;19350:74;;19433:93;19522:3;19433:93;:::i;:::-;19551:2;19546:3;19542:12;19535:19;;19340:220;;;:::o;19634:517::-;19787:4;19782:3;19778:14;19879:4;19872:5;19868:16;19862:23;19898:61;19953:4;19948:3;19944:14;19930:12;19898:61;:::i;:::-;19802:167;20052:4;20045:5;20041:16;20035:23;20071:63;20128:4;20123:3;20119:14;20105:12;20071:63;:::i;:::-;19979:165;19756:395;;;:::o;20157:108::-;20234:24;20252:5;20234:24;:::i;:::-;20229:3;20222:37;20212:53;;:::o;20271:118::-;20358:24;20376:5;20358:24;:::i;:::-;20353:3;20346:37;20336:53;;:::o;20395:105::-;20470:23;20487:5;20470:23;:::i;:::-;20465:3;20458:36;20448:52;;:::o;20506:115::-;20591:23;20608:5;20591:23;:::i;:::-;20586:3;20579:36;20569:52;;:::o;20627:112::-;20710:22;20726:5;20710:22;:::i;:::-;20705:3;20698:35;20688:51;;:::o;20745:663::-;;21008:148;21152:3;21008:148;:::i;:::-;21001:155;;21166:75;21237:3;21228:6;21166:75;:::i;:::-;21266:2;21261:3;21257:12;21250:19;;21279:75;21350:3;21341:6;21279:75;:::i;:::-;21379:2;21374:3;21370:12;21363:19;;21399:3;21392:10;;20990:418;;;;;:::o;21414:967::-;;21818:148;21962:3;21818:148;:::i;:::-;21811:155;;21983:95;22074:3;22065:6;21983:95;:::i;:::-;21976:102;;22095:148;22239:3;22095:148;:::i;:::-;22088:155;;22260:95;22351:3;22342:6;22260:95;:::i;:::-;22253:102;;22372:3;22365:10;;21800:581;;;;;:::o;22387:222::-;;22518:2;22507:9;22503:18;22495:26;;22531:71;22599:1;22588:9;22584:17;22575:6;22531:71;:::i;:::-;22485:124;;;;:::o;22615:210::-;;22740:2;22729:9;22725:18;22717:26;;22753:65;22815:1;22804:9;22800:17;22791:6;22753:65;:::i;:::-;22707:118;;;;:::o;22831:222::-;;22962:2;22951:9;22947:18;22939:26;;22975:71;23043:1;23032:9;23028:17;23019:6;22975:71;:::i;:::-;22929:124;;;;:::o;23059:775::-;;23330:3;23319:9;23315:19;23307:27;;23344:71;23412:1;23401:9;23397:17;23388:6;23344:71;:::i;:::-;23425:72;23493:2;23482:9;23478:18;23469:6;23425:72;:::i;:::-;23507;23575:2;23564:9;23560:18;23551:6;23507:72;:::i;:::-;23589;23657:2;23646:9;23642:18;23633:6;23589:72;:::i;:::-;23671:73;23739:3;23728:9;23724:19;23715:6;23671:73;:::i;:::-;23754;23822:3;23811:9;23807:19;23798:6;23754:73;:::i;:::-;23297:537;;;;;;;;;:::o;23840:553::-;;24055:3;24044:9;24040:19;24032:27;;24069:71;24137:1;24126:9;24122:17;24113:6;24069:71;:::i;:::-;24150:72;24218:2;24207:9;24203:18;24194:6;24150:72;:::i;:::-;24232;24300:2;24289:9;24285:18;24276:6;24232:72;:::i;:::-;24314;24382:2;24371:9;24367:18;24358:6;24314:72;:::i;:::-;24022:371;;;;;;;:::o;24399:664::-;;24642:3;24631:9;24627:19;24619:27;;24656:71;24724:1;24713:9;24709:17;24700:6;24656:71;:::i;:::-;24737:72;24805:2;24794:9;24790:18;24781:6;24737:72;:::i;:::-;24819;24887:2;24876:9;24872:18;24863:6;24819:72;:::i;:::-;24901;24969:2;24958:9;24954:18;24945:6;24901:72;:::i;:::-;24983:73;25051:3;25040:9;25036:19;25027:6;24983:73;:::i;:::-;24609:454;;;;;;;;:::o;25069:545::-;;25280:3;25269:9;25265:19;25257:27;;25294:71;25362:1;25351:9;25347:17;25338:6;25294:71;:::i;:::-;25375:68;25439:2;25428:9;25424:18;25415:6;25375:68;:::i;:::-;25453:72;25521:2;25510:9;25506:18;25497:6;25453:72;:::i;:::-;25535;25603:2;25592:9;25588:18;25579:6;25535:72;:::i;:::-;25247:367;;;;;;;:::o;25620:313::-;;25771:2;25760:9;25756:18;25748:26;;25820:9;25814:4;25810:20;25806:1;25795:9;25791:17;25784:47;25848:78;25921:4;25912:6;25848:78;:::i;:::-;25840:86;;25738:195;;;;:::o;25939:419::-;;26143:2;26132:9;26128:18;26120:26;;26192:9;26186:4;26182:20;26178:1;26167:9;26163:17;26156:47;26220:131;26346:4;26220:131;:::i;:::-;26212:139;;26110:248;;;:::o;26364:419::-;;26568:2;26557:9;26553:18;26545:26;;26617:9;26611:4;26607:20;26603:1;26592:9;26588:17;26581:47;26645:131;26771:4;26645:131;:::i;:::-;26637:139;;26535:248;;;:::o;26789:419::-;;26993:2;26982:9;26978:18;26970:26;;27042:9;27036:4;27032:20;27028:1;27017:9;27013:17;27006:47;27070:131;27196:4;27070:131;:::i;:::-;27062:139;;26960:248;;;:::o;27214:419::-;;27418:2;27407:9;27403:18;27395:26;;27467:9;27461:4;27457:20;27453:1;27442:9;27438:17;27431:47;27495:131;27621:4;27495:131;:::i;:::-;27487:139;;27385:248;;;:::o;27639:419::-;;27843:2;27832:9;27828:18;27820:26;;27892:9;27886:4;27882:20;27878:1;27867:9;27863:17;27856:47;27920:131;28046:4;27920:131;:::i;:::-;27912:139;;27810:248;;;:::o;28064:419::-;;28268:2;28257:9;28253:18;28245:26;;28317:9;28311:4;28307:20;28303:1;28292:9;28288:17;28281:47;28345:131;28471:4;28345:131;:::i;:::-;28337:139;;28235:248;;;:::o;28489:419::-;;28693:2;28682:9;28678:18;28670:26;;28742:9;28736:4;28732:20;28728:1;28717:9;28713:17;28706:47;28770:131;28896:4;28770:131;:::i;:::-;28762:139;;28660:248;;;:::o;28914:419::-;;29118:2;29107:9;29103:18;29095:26;;29167:9;29161:4;29157:20;29153:1;29142:9;29138:17;29131:47;29195:131;29321:4;29195:131;:::i;:::-;29187:139;;29085:248;;;:::o;29339:419::-;;29543:2;29532:9;29528:18;29520:26;;29592:9;29586:4;29582:20;29578:1;29567:9;29563:17;29556:47;29620:131;29746:4;29620:131;:::i;:::-;29612:139;;29510:248;;;:::o;29764:419::-;;29968:2;29957:9;29953:18;29945:26;;30017:9;30011:4;30007:20;30003:1;29992:9;29988:17;29981:47;30045:131;30171:4;30045:131;:::i;:::-;30037:139;;29935:248;;;:::o;30189:419::-;;30393:2;30382:9;30378:18;30370:26;;30442:9;30436:4;30432:20;30428:1;30417:9;30413:17;30406:47;30470:131;30596:4;30470:131;:::i;:::-;30462:139;;30360:248;;;:::o;30614:419::-;;30818:2;30807:9;30803:18;30795:26;;30867:9;30861:4;30857:20;30853:1;30842:9;30838:17;30831:47;30895:131;31021:4;30895:131;:::i;:::-;30887:139;;30785:248;;;:::o;31039:419::-;;31243:2;31232:9;31228:18;31220:26;;31292:9;31286:4;31282:20;31278:1;31267:9;31263:17;31256:47;31320:131;31446:4;31320:131;:::i;:::-;31312:139;;31210:248;;;:::o;31464:419::-;;31668:2;31657:9;31653:18;31645:26;;31717:9;31711:4;31707:20;31703:1;31692:9;31688:17;31681:47;31745:131;31871:4;31745:131;:::i;:::-;31737:139;;31635:248;;;:::o;31889:419::-;;32093:2;32082:9;32078:18;32070:26;;32142:9;32136:4;32132:20;32128:1;32117:9;32113:17;32106:47;32170:131;32296:4;32170:131;:::i;:::-;32162:139;;32060:248;;;:::o;32314:419::-;;32518:2;32507:9;32503:18;32495:26;;32567:9;32561:4;32557:20;32553:1;32542:9;32538:17;32531:47;32595:131;32721:4;32595:131;:::i;:::-;32587:139;;32485:248;;;:::o;32739:419::-;;32943:2;32932:9;32928:18;32920:26;;32992:9;32986:4;32982:20;32978:1;32967:9;32963:17;32956:47;33020:131;33146:4;33020:131;:::i;:::-;33012:139;;32910:248;;;:::o;33164:419::-;;33368:2;33357:9;33353:18;33345:26;;33417:9;33411:4;33407:20;33403:1;33392:9;33388:17;33381:47;33445:131;33571:4;33445:131;:::i;:::-;33437:139;;33335:248;;;:::o;33589:419::-;;33793:2;33782:9;33778:18;33770:26;;33842:9;33836:4;33832:20;33828:1;33817:9;33813:17;33806:47;33870:131;33996:4;33870:131;:::i;:::-;33862:139;;33760:248;;;:::o;34014:419::-;;34218:2;34207:9;34203:18;34195:26;;34267:9;34261:4;34257:20;34253:1;34242:9;34238:17;34231:47;34295:131;34421:4;34295:131;:::i;:::-;34287:139;;34185:248;;;:::o;34439:419::-;;34643:2;34632:9;34628:18;34620:26;;34692:9;34686:4;34682:20;34678:1;34667:9;34663:17;34656:47;34720:131;34846:4;34720:131;:::i;:::-;34712:139;;34610:248;;;:::o;34864:419::-;;35068:2;35057:9;35053:18;35045:26;;35117:9;35111:4;35107:20;35103:1;35092:9;35088:17;35081:47;35145:131;35271:4;35145:131;:::i;:::-;35137:139;;35035:248;;;:::o;35289:419::-;;35493:2;35482:9;35478:18;35470:26;;35542:9;35536:4;35532:20;35528:1;35517:9;35513:17;35506:47;35570:131;35696:4;35570:131;:::i;:::-;35562:139;;35460:248;;;:::o;35714:419::-;;35918:2;35907:9;35903:18;35895:26;;35967:9;35961:4;35957:20;35953:1;35942:9;35938:17;35931:47;35995:131;36121:4;35995:131;:::i;:::-;35987:139;;35885:248;;;:::o;36139:419::-;;36343:2;36332:9;36328:18;36320:26;;36392:9;36386:4;36382:20;36378:1;36367:9;36363:17;36356:47;36420:131;36546:4;36420:131;:::i;:::-;36412:139;;36310:248;;;:::o;36564:419::-;;36768:2;36757:9;36753:18;36745:26;;36817:9;36811:4;36807:20;36803:1;36792:9;36788:17;36781:47;36845:131;36971:4;36845:131;:::i;:::-;36837:139;;36735:248;;;:::o;36989:419::-;;37193:2;37182:9;37178:18;37170:26;;37242:9;37236:4;37232:20;37228:1;37217:9;37213:17;37206:47;37270:131;37396:4;37270:131;:::i;:::-;37262:139;;37160:248;;;:::o;37414:419::-;;37618:2;37607:9;37603:18;37595:26;;37667:9;37661:4;37657:20;37653:1;37642:9;37638:17;37631:47;37695:131;37821:4;37695:131;:::i;:::-;37687:139;;37585:248;;;:::o;37839:419::-;;38043:2;38032:9;38028:18;38020:26;;38092:9;38086:4;38082:20;38078:1;38067:9;38063:17;38056:47;38120:131;38246:4;38120:131;:::i;:::-;38112:139;;38010:248;;;:::o;38264:334::-;;38451:2;38440:9;38436:18;38428:26;;38464:127;38588:1;38577:9;38573:17;38564:6;38464:127;:::i;:::-;38418:180;;;;:::o;38604:222::-;;38735:2;38724:9;38720:18;38712:26;;38748:71;38816:1;38805:9;38801:17;38792:6;38748:71;:::i;:::-;38702:124;;;;:::o;38832:332::-;;38991:2;38980:9;38976:18;38968:26;;39004:71;39072:1;39061:9;39057:17;39048:6;39004:71;:::i;:::-;39085:72;39153:2;39142:9;39138:18;39129:6;39085:72;:::i;:::-;38958:206;;;;;:::o;39170:218::-;;39299:2;39288:9;39284:18;39276:26;;39312:69;39378:1;39367:9;39363:17;39354:6;39312:69;:::i;:::-;39266:122;;;;:::o;39394:214::-;;39521:2;39510:9;39506:18;39498:26;;39534:67;39598:1;39587:9;39583:17;39574:6;39534:67;:::i;:::-;39488:120;;;;:::o;39614:99::-;;39700:5;39694:12;39684:22;;39673:40;;;:::o;39719:169::-;;39837:6;39832:3;39825:19;39877:4;39872:3;39868:14;39853:29;;39815:73;;;;:::o;39894:148::-;;40033:3;40018:18;;40008:34;;;;:::o;40048:305::-;;40107:20;40125:1;40107:20;:::i;:::-;40102:25;;40141:20;40159:1;40141:20;:::i;:::-;40136:25;;40295:1;40227:66;40223:74;40220:1;40217:81;40214:2;;;40301:18;;:::i;:::-;40214:2;40345:1;40342;40338:9;40331:16;;40092:261;;;;:::o;40359:185::-;;40416:20;40434:1;40416:20;:::i;:::-;40411:25;;40450:20;40468:1;40450:20;:::i;:::-;40445:25;;40489:1;40479:2;;40494:18;;:::i;:::-;40479:2;40536:1;40533;40529:9;40524:14;;40401:143;;;;:::o;40550:348::-;;40613:20;40631:1;40613:20;:::i;:::-;40608:25;;40647:20;40665:1;40647:20;:::i;:::-;40642:25;;40835:1;40767:66;40763:74;40760:1;40757:81;40752:1;40745:9;40738:17;40734:105;40731:2;;;40842:18;;:::i;:::-;40731:2;40890:1;40887;40883:9;40872:20;;40598:300;;;;:::o;40904:191::-;;40964:20;40982:1;40964:20;:::i;:::-;40959:25;;40998:20;41016:1;40998:20;:::i;:::-;40993:25;;41037:1;41034;41031:8;41028:2;;;41042:18;;:::i;:::-;41028:2;41087:1;41084;41080:9;41072:17;;40949:146;;;;:::o;41101:96::-;;41167:24;41185:5;41167:24;:::i;:::-;41156:35;;41146:51;;;:::o;41203:90::-;;41280:5;41273:13;41266:21;41255:32;;41245:48;;;:::o;41299:77::-;;41365:5;41354:16;;41344:32;;;:::o;41382:149::-;;41458:66;41451:5;41447:78;41436:89;;41426:105;;;:::o;41537:126::-;;41614:42;41607:5;41603:54;41592:65;;41582:81;;;:::o;41669:142::-;;41746:58;41739:5;41735:70;41724:81;;41714:97;;;:::o;41817:77::-;;41883:5;41872:16;;41862:32;;;:::o;41900:93::-;;41976:10;41969:5;41965:22;41954:33;;41944:49;;;:::o;41999:86::-;;42074:4;42067:5;42063:16;42052:27;;42042:43;;;:::o;42091:307::-;42159:1;42169:113;42183:6;42180:1;42177:13;42169:113;;;42268:1;42263:3;42259:11;42253:18;42249:1;42244:3;42240:11;42233:39;42205:2;42202:1;42198:10;42193:15;;42169:113;;;42300:6;42297:1;42294:13;42291:2;;;42380:1;42371:6;42366:3;42362:16;42355:27;42291:2;42140:258;;;;:::o;42404:171::-;;42466:24;42484:5;42466:24;:::i;:::-;42457:33;;42512:4;42505:5;42502:15;42499:2;;;42520:18;;:::i;:::-;42499:2;42567:1;42560:5;42556:13;42549:20;;42447:128;;;:::o;42581:320::-;;42662:1;42656:4;42652:12;42642:22;;42709:1;42703:4;42699:12;42730:18;42720:2;;42786:4;42778:6;42774:17;42764:27;;42720:2;42848;42840:6;42837:14;42817:18;42814:38;42811:2;;;42867:18;;:::i;:::-;42811:2;42632:269;;;;:::o;42907:79::-;;42975:5;42964:16;;42954:32;;;:::o;42992:180::-;43040:77;43037:1;43030:88;43137:4;43134:1;43127:15;43161:4;43158:1;43151:15;43178:180;43226:77;43223:1;43216:88;43323:4;43320:1;43313:15;43347:4;43344:1;43337:15;43364:180;43412:77;43409:1;43402:88;43509:4;43506:1;43499:15;43533:4;43530:1;43523:15;43550:102;;43642:2;43638:7;43633:2;43626:5;43622:14;43618:28;43608:38;;43598:54;;;:::o;43658:174::-;43798:26;43794:1;43786:6;43782:14;43775:50;43764:68;:::o;43838:179::-;43978:31;43974:1;43966:6;43962:14;43955:55;43944:73;:::o;44023:182::-;44163:34;44159:1;44151:6;44147:14;44140:58;44129:76;:::o;44211:222::-;44351:34;44347:1;44339:6;44335:14;44328:58;44420:5;44415:2;44407:6;44403:15;44396:30;44317:116;:::o;44439:181::-;44579:33;44575:1;44567:6;44563:14;44556:57;44545:75;:::o;44626:170::-;44766:22;44762:1;44754:6;44750:14;44743:46;44732:64;:::o;44802:179::-;44942:31;44938:1;44930:6;44926:14;44919:55;44908:73;:::o;44987:221::-;45127:34;45123:1;45115:6;45111:14;45104:58;45196:4;45191:2;45183:6;45179:15;45172:29;45093:115;:::o;45214:181::-;45354:33;45350:1;45342:6;45338:14;45331:57;45320:75;:::o;45401:175::-;45541:27;45537:1;45529:6;45525:14;45518:51;45507:69;:::o;45582:221::-;45722:34;45718:1;45710:6;45706:14;45699:58;45791:4;45786:2;45778:6;45774:15;45767:29;45688:115;:::o;45809:214::-;45949:66;45945:1;45937:6;45933:14;45926:90;45915:108;:::o;46029:179::-;46169:31;46165:1;46157:6;46153:14;46146:55;46135:73;:::o;46214:225::-;46354:34;46350:1;46342:6;46338:14;46331:58;46423:8;46418:2;46410:6;46406:15;46399:33;46320:119;:::o;46445:221::-;46585:34;46581:1;46573:6;46569:14;46562:58;46654:4;46649:2;46641:6;46637:15;46630:29;46551:115;:::o;46672:166::-;46812:18;46808:1;46800:6;46796:14;46789:42;46778:60;:::o;46844:221::-;46984:34;46980:1;46972:6;46968:14;46961:58;47053:4;47048:2;47040:6;47036:15;47029:29;46950:115;:::o;47071:180::-;47211:32;47207:1;47199:6;47195:14;47188:56;47177:74;:::o;47257:227::-;47397:34;47393:1;47385:6;47381:14;47374:58;47466:10;47461:2;47453:6;47449:15;47442:35;47363:121;:::o;47490:235::-;47630:34;47626:1;47618:6;47614:14;47607:58;47699:18;47694:2;47686:6;47682:15;47675:43;47596:129;:::o;47731:226::-;47871:34;47867:1;47859:6;47855:14;47848:58;47940:9;47935:2;47927:6;47923:15;47916:34;47837:120;:::o;47963:223::-;48103:34;48099:1;48091:6;48087:14;48080:58;48172:6;48167:2;48159:6;48155:15;48148:31;48069:117;:::o;48192:220::-;48332:34;48328:1;48320:6;48316:14;48309:58;48401:3;48396:2;48388:6;48384:15;48377:28;48298:114;:::o;48418:224::-;48558:34;48554:1;48546:6;48542:14;48535:58;48627:7;48622:2;48614:6;48610:15;48603:32;48524:118;:::o;48648:225::-;48788:34;48784:1;48776:6;48772:14;48765:58;48857:8;48852:2;48844:6;48840:15;48833:33;48754:119;:::o;48879:223::-;49019:34;49015:1;49007:6;49003:14;48996:58;49088:6;49083:2;49075:6;49071:15;49064:31;48985:117;:::o;49108:172::-;49248:24;49244:1;49236:6;49232:14;49225:48;49214:66;:::o;49286:173::-;49426:25;49422:1;49414:6;49410:14;49403:49;49392:67;:::o;49465:224::-;49605:34;49601:1;49593:6;49589:14;49582:58;49674:7;49669:2;49661:6;49657:15;49650:32;49571:118;:::o;49695:167::-;49835:19;49831:1;49823:6;49819:14;49812:43;49801:61;:::o;49868:234::-;50008:34;50004:1;49996:6;49992:14;49985:58;50077:17;50072:2;50064:6;50060:15;50053:42;49974:128;:::o;50108:181::-;50248:33;50244:1;50236:6;50232:14;50225:57;50214:75;:::o;50295:122::-;50368:24;50386:5;50368:24;:::i;:::-;50361:5;50358:35;50348:2;;50407:1;50404;50397:12;50348:2;50338:79;:::o;50423:122::-;50496:24;50514:5;50496:24;:::i;:::-;50489:5;50486:35;50476:2;;50535:1;50532;50525:12;50476:2;50466:79;:::o;50551:120::-;50623:23;50640:5;50623:23;:::i;:::-;50616:5;50613:34;50603:2;;50661:1;50658;50651:12;50603:2;50593:78;:::o;50677:122::-;50750:24;50768:5;50750:24;:::i;:::-;50743:5;50740:35;50730:2;;50789:1;50786;50779:12;50730:2;50720:79;:::o;50805:120::-;50877:23;50894:5;50877:23;:::i;:::-;50870:5;50867:34;50857:2;;50915:1;50912;50905:12;50857:2;50847:78;:::o;50931:118::-;51002:22;51018:5;51002:22;:::i;:::-;50995:5;50992:33;50982:2;;51039:1;51036;51029:12;50982:2;50972:77;:::o

Swarm Source

ipfs://eadf1df264f069e0acb0c78903f347238b3b72f8b6f0758d54a3c7c7891b47c0
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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