ETH Price: $2,706.72 (+1.10%)

Token

SoRekt (SRT)
 

Overview

Max Total Supply

800 SRT

Holders

4

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
200 SRT

Value
$0.00
0x96b37d861aedadb91f2949fbb9304127cc18ecd4
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
SoRektToken

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-02-23
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/math/SafeMath.sol


// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// File: @openzeppelin/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: @openzeppelin/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: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @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 == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/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: @openzeppelin/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.8.0) (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);
        _;
    }

    /**
     * @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 virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @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 virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(account),
                        " 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 virtual 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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    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`.
     *
     * May emit a {RoleRevoked} event.
     */
    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.
     *
     * May emit a {RoleGranted} event.
     *
     * [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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (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 Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        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: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

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


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

pragma solidity ^0.8.0;


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

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

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

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


// OpenZeppelin Contracts (last updated v4.8.0) (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.openzeppelin.com/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:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, 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}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, 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}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, 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) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, 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) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * 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:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, 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;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _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;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _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 Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

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

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (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 {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

// File: contracts/SoRektToken.sol


pragma solidity >=0.7.0 <0.9.0;






//
/**
 * @title IndexxExchange token
 * @notice BEP20 Token with pausable, mintable and burn features
 */
contract SoRektToken is ERC20, ERC20Burnable, Pausable, AccessControl {
    using SafeMath for uint256;

    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    address public feeAdmin;
    bool public feeActive = false;
 
    /**
     * @dev Constructor assigning Token name, symbol and minter, pauser and admin role to msg.sender
     */
    constructor() ERC20("SoRekt", "SRT") {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(PAUSER_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
        feeAdmin = msg.sender;
    }

    /**
     * @dev Function to change Fee admin address
     * @param _newFeeAdmin The address of new fee admin
     */
    function changeFeeAdmin(address _newFeeAdmin) external onlyRole(MINTER_ROLE){
        feeAdmin = _newFeeAdmin;
    }

    /**
     * @dev Function to change Fee active status
     * @param status new status for fee charging
     */
    function changeFeeStatus(bool status) external onlyRole(MINTER_ROLE){
        feeActive = status;
    }

    /**
     * @dev Function to pause token transfer
     */
    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    /**
     * @dev Function to unpause token transfer
     */
    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    /**
     * @dev Function to mint tokens
     * @param to The address that will receive the minted tokens.
     * @param amount The amount of tokens to mint.
     */
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
        _mint(to, amount);
    }

    /**
     * @dev Function to halt token transfers in case of extreme events and emergencies
     * @param to The address that will send the tokens.
     * @param from The address that will receive the tokens.
     * @param amount The amount of tokens to mint.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal override whenNotPaused {
        super._beforeTokenTransfer(from, to, amount);
    }

    function transfer(address to, uint256 amount)
        public
        override
        returns (bool)
    {
        address owner = _msgSender();

        if ( feeActive == true && amount > 20000 * 10**18) {
            uint256 fee;
            if (amount > 40000 * 10**18) {
                if (amount > 80000 * 10**18) {
                    fee = amount.mul(15).div(1000);
                } else {
                    fee = amount.div(100);
                }
            } else {
                fee = amount.mul(5).div(1000);
            }
            _transfer(owner, feeAdmin, fee);
            amount = amount.sub(fee);
        }

        _transfer(owner, to, amount);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);

        if (feeActive == true && amount > 20000 * 10**18) {
            uint256 fee;
            if (amount > 40000 * 10**18) {
                if (amount > 80000 * 10**18) {
                    fee = amount.mul(15).div(1000);
                } else {
                    fee = amount.div(100);
                }
            } else {
                fee = amount.mul(5).div(1000);
            }
            _transfer(from, feeAdmin, fee);
            amount = amount.sub(fee);
        }
        _transfer(from, to, amount);

        return true;
    }


}

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":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":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":"MINTER_ROLE","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":[{"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":"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":"_newFeeAdmin","type":"address"}],"name":"changeFeeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"status","type":"bool"}],"name":"changeFeeStatus","outputs":[],"stateMutability":"nonpayable","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":[],"name":"feeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"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":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"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":[{"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":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","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"}]

60806040526000600760146101000a81548160ff0219169083151502179055503480156200002c57600080fd5b506040518060400160405280600681526020017f536f52656b7400000000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f53525400000000000000000000000000000000000000000000000000000000008152508160039080519060200190620000b19291906200030d565b508060049080519060200190620000ca9291906200030d565b5050506000600560006101000a81548160ff021916908315150217905550620000fd6000801b33620001a860201b60201c565b6200012f7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33620001a860201b60201c565b620001617f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a633620001a860201b60201c565b33600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000422565b620001ba82826200029a60201b60201c565b620002965760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506200023b6200030560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600033905090565b8280546200031b90620003bd565b90600052602060002090601f0160209004810192826200033f57600085556200038b565b82601f106200035a57805160ff19168380011785556200038b565b828001600101855582156200038b579182015b828111156200038a5782518255916020019190600101906200036d565b5b5090506200039a91906200039e565b5090565b5b80821115620003b95760008160009055506001016200039f565b5090565b60006002820490506001821680620003d657607f821691505b60208210811415620003ed57620003ec620003f3565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b612e0b80620004326000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c806370a0823111610104578063a457c2d7116100a2578063d547741f11610071578063d547741f14610557578063dd62ed3e14610573578063e39e165a146105a3578063e63ab1e9146105c1576101da565b8063a457c2d7146104bd578063a9059cbb146104ed578063af1171ca1461051d578063d539139314610539576101da565b806391d14854116100de57806391d148541461043557806395d89b41146104655780639e7bd52514610483578063a217fddf1461049f576101da565b806370a08231146103df57806379cc67901461040f5780638456cb591461042b576101da565b806330a402c01161017c5780633f4ba83a1161014b5780633f4ba83a1461037f57806340c10f191461038957806342966c68146103a55780635c975abb146103c1576101da565b806330a402c0146102f7578063313ce5671461031557806336568abe14610333578063395093511461034f576101da565b806318160ddd116101b857806318160ddd1461025d57806323b872dd1461027b578063248a9ca3146102ab5780632f2ff15d146102db576101da565b806301ffc9a7146101df57806306fdde031461020f578063095ea7b31461022d575b600080fd5b6101f960048036038101906101f491906120ae565b6105df565b604051610206919061243a565b60405180910390f35b610217610659565b6040516102249190612470565b60405180910390f35b61024760048036038101906102429190611fe4565b6106eb565b604051610254919061243a565b60405180910390f35b61026561070e565b6040516102729190612652565b60405180910390f35b61029560048036038101906102909190611f95565b610718565b6040516102a2919061243a565b60405180910390f35b6102c560048036038101906102c09190612049565b610858565b6040516102d29190612455565b60405180910390f35b6102f560048036038101906102f09190612072565b610878565b005b6102ff610899565b60405161030c919061241f565b60405180910390f35b61031d6108bf565b60405161032a919061266d565b60405180910390f35b61034d60048036038101906103489190612072565b6108c8565b005b61036960048036038101906103649190611fe4565b61094b565b604051610376919061243a565b60405180910390f35b610387610982565b005b6103a3600480360381019061039e9190611fe4565b6109b7565b005b6103bf60048036038101906103ba91906120d7565b6109f0565b005b6103c9610a04565b6040516103d6919061243a565b60405180910390f35b6103f960048036038101906103f49190611f30565b610a1b565b6040516104069190612652565b60405180910390f35b61042960048036038101906104249190611fe4565b610a63565b005b610433610a83565b005b61044f600480360381019061044a9190612072565b610ab8565b60405161045c919061243a565b60405180910390f35b61046d610b23565b60405161047a9190612470565b60405180910390f35b61049d60048036038101906104989190612020565b610bb5565b005b6104a7610bfd565b6040516104b49190612455565b60405180910390f35b6104d760048036038101906104d29190611fe4565b610c04565b6040516104e4919061243a565b60405180910390f35b61050760048036038101906105029190611fe4565b610c7b565b604051610514919061243a565b60405180910390f35b61053760048036038101906105329190611f30565b610daf565b005b610541610e1e565b60405161054e9190612455565b60405180910390f35b610571600480360381019061056c9190612072565b610e42565b005b61058d60048036038101906105889190611f59565b610e63565b60405161059a9190612652565b60405180910390f35b6105ab610eea565b6040516105b8919061243a565b60405180910390f35b6105c9610efd565b6040516105d69190612455565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610652575061065182610f21565b5b9050919050565b606060038054610668906128ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610694906128ac565b80156106e15780601f106106b6576101008083540402835291602001916106e1565b820191906000526020600020905b8154815290600101906020018083116106c457829003601f168201915b5050505050905090565b6000806106f6610f8b565b9050610703818585610f93565b600191505092915050565b6000600254905090565b600080610723610f8b565b905061073085828561115e565b60011515600760149054906101000a900460ff16151514801561075c575069043c33c193756480000083115b15610841576000690878678326eac90000008411156107d2576910f0cf064dd5920000008411156107b6576107af6103e86107a1600f876111ea90919063ffffffff16565b61120090919063ffffffff16565b90506107cd565b6107ca60648561120090919063ffffffff16565b90505b6107fd565b6107fa6103e86107ec6005876111ea90919063ffffffff16565b61120090919063ffffffff16565b90505b61082a86600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611216565b61083d818561148e90919063ffffffff16565b9350505b61084c858585611216565b60019150509392505050565b600060066000838152602001908152602001600020600101549050919050565b61088182610858565b61088a816114a4565b61089483836114b8565b505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006012905090565b6108d0610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461093d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093490612612565b60405180910390fd5b6109478282611599565b5050565b600080610956610f8b565b90506109778185856109688589610e63565b61097291906126af565b610f93565b600191505092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6109ac816114a4565b6109b461167b565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109e1816114a4565b6109eb83836116de565b505050565b610a016109fb610f8b565b82611835565b50565b6000600560009054906101000a900460ff16905090565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610a7582610a6f610f8b565b8361115e565b610a7f8282611835565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610aad816114a4565b610ab5611a03565b50565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610b32906128ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5e906128ac565b8015610bab5780601f10610b8057610100808354040283529160200191610bab565b820191906000526020600020905b815481529060010190602001808311610b8e57829003601f168201915b5050505050905090565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610bdf816114a4565b81600760146101000a81548160ff0219169083151502179055505050565b6000801b81565b600080610c0f610f8b565b90506000610c1d8286610e63565b905083811015610c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c59906125f2565b60405180910390fd5b610c6f8286868403610f93565b60019250505092915050565b600080610c86610f8b565b905060011515600760149054906101000a900460ff161515148015610cb4575069043c33c193756480000083115b15610d99576000690878678326eac9000000841115610d2a576910f0cf064dd592000000841115610d0e57610d076103e8610cf9600f876111ea90919063ffffffff16565b61120090919063ffffffff16565b9050610d25565b610d2260648561120090919063ffffffff16565b90505b610d55565b610d526103e8610d446005876111ea90919063ffffffff16565b61120090919063ffffffff16565b90505b610d8282600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611216565b610d95818561148e90919063ffffffff16565b9350505b610da4818585611216565b600191505092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610dd9816114a4565b81600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b610e4b82610858565b610e54816114a4565b610e5e8383611599565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600760149054906101000a900460ff1681565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611003576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffa906125d2565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a90612512565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516111519190612652565b60405180910390a3505050565b600061116a8484610e63565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146111e457818110156111d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cd90612532565b60405180910390fd5b6111e38484848403610f93565b5b50505050565b600081836111f89190612736565b905092915050565b6000818361120e9190612705565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127d906125b2565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ed906124b2565b60405180910390fd5b611301838383611a66565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611387576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137e90612552565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114759190612652565b60405180910390a3611488848484611a7e565b50505050565b6000818361149c9190612790565b905092915050565b6114b5816114b0610f8b565b611a83565b50565b6114c28282610ab8565b6115955760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061153a610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6115a38282610ab8565b156116775760006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061161c610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b611683611b08565b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6116c7610f8b565b6040516116d4919061241f565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561174e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174590612632565b60405180910390fd5b61175a60008383611a66565b806002600082825461176c91906126af565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161181d9190612652565b60405180910390a361183160008383611a7e565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189c90612592565b60405180910390fd5b6118b182600083611a66565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e906124f2565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119ea9190612652565b60405180910390a36119fe83600084611a7e565b505050565b611a0b611b51565b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a4f610f8b565b604051611a5c919061241f565b60405180910390a1565b611a6e611b51565b611a79838383611b9b565b505050565b505050565b611a8d8282610ab8565b611b0457611a9a81611ba0565b611aa88360001c6020611bcd565b604051602001611ab99291906123e5565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afb9190612470565b60405180910390fd5b5050565b611b10610a04565b611b4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b46906124d2565b60405180910390fd5b565b611b59610a04565b15611b99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9090612572565b60405180910390fd5b565b505050565b6060611bc68273ffffffffffffffffffffffffffffffffffffffff16601460ff16611bcd565b9050919050565b606060006002836002611be09190612736565b611bea91906126af565b67ffffffffffffffff811115611c29577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611c5b5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611cb9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611d43577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611d839190612736565b611d8d91906126af565b90505b6001811115611e79577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611df5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110611e32577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080611e7290612882565b9050611d90565b5060008414611ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb490612492565b60405180910390fd5b8091505092915050565b600081359050611ed681612d62565b92915050565b600081359050611eeb81612d79565b92915050565b600081359050611f0081612d90565b92915050565b600081359050611f1581612da7565b92915050565b600081359050611f2a81612dbe565b92915050565b600060208284031215611f4257600080fd5b6000611f5084828501611ec7565b91505092915050565b60008060408385031215611f6c57600080fd5b6000611f7a85828601611ec7565b9250506020611f8b85828601611ec7565b9150509250929050565b600080600060608486031215611faa57600080fd5b6000611fb886828701611ec7565b9350506020611fc986828701611ec7565b9250506040611fda86828701611f1b565b9150509250925092565b60008060408385031215611ff757600080fd5b600061200585828601611ec7565b925050602061201685828601611f1b565b9150509250929050565b60006020828403121561203257600080fd5b600061204084828501611edc565b91505092915050565b60006020828403121561205b57600080fd5b600061206984828501611ef1565b91505092915050565b6000806040838503121561208557600080fd5b600061209385828601611ef1565b92505060206120a485828601611ec7565b9150509250929050565b6000602082840312156120c057600080fd5b60006120ce84828501611f06565b91505092915050565b6000602082840312156120e957600080fd5b60006120f784828501611f1b565b91505092915050565b612109816127c4565b82525050565b612118816127d6565b82525050565b612127816127e2565b82525050565b600061213882612688565b6121428185612693565b935061215281856020860161284f565b61215b8161296b565b840191505092915050565b600061217182612688565b61217b81856126a4565b935061218b81856020860161284f565b80840191505092915050565b60006121a4602083612693565b91506121af8261297c565b602082019050919050565b60006121c7602383612693565b91506121d2826129a5565b604082019050919050565b60006121ea601483612693565b91506121f5826129f4565b602082019050919050565b600061220d602283612693565b915061221882612a1d565b604082019050919050565b6000612230602283612693565b915061223b82612a6c565b604082019050919050565b6000612253601d83612693565b915061225e82612abb565b602082019050919050565b6000612276602683612693565b915061228182612ae4565b604082019050919050565b6000612299601083612693565b91506122a482612b33565b602082019050919050565b60006122bc602183612693565b91506122c782612b5c565b604082019050919050565b60006122df602583612693565b91506122ea82612bab565b604082019050919050565b6000612302602483612693565b915061230d82612bfa565b604082019050919050565b60006123256017836126a4565b915061233082612c49565b601782019050919050565b6000612348602583612693565b915061235382612c72565b604082019050919050565b600061236b6011836126a4565b915061237682612cc1565b601182019050919050565b600061238e602f83612693565b915061239982612cea565b604082019050919050565b60006123b1601f83612693565b91506123bc82612d39565b602082019050919050565b6123d081612838565b82525050565b6123df81612842565b82525050565b60006123f082612318565b91506123fc8285612166565b91506124078261235e565b91506124138284612166565b91508190509392505050565b60006020820190506124346000830184612100565b92915050565b600060208201905061244f600083018461210f565b92915050565b600060208201905061246a600083018461211e565b92915050565b6000602082019050818103600083015261248a818461212d565b905092915050565b600060208201905081810360008301526124ab81612197565b9050919050565b600060208201905081810360008301526124cb816121ba565b9050919050565b600060208201905081810360008301526124eb816121dd565b9050919050565b6000602082019050818103600083015261250b81612200565b9050919050565b6000602082019050818103600083015261252b81612223565b9050919050565b6000602082019050818103600083015261254b81612246565b9050919050565b6000602082019050818103600083015261256b81612269565b9050919050565b6000602082019050818103600083015261258b8161228c565b9050919050565b600060208201905081810360008301526125ab816122af565b9050919050565b600060208201905081810360008301526125cb816122d2565b9050919050565b600060208201905081810360008301526125eb816122f5565b9050919050565b6000602082019050818103600083015261260b8161233b565b9050919050565b6000602082019050818103600083015261262b81612381565b9050919050565b6000602082019050818103600083015261264b816123a4565b9050919050565b600060208201905061266760008301846123c7565b92915050565b600060208201905061268260008301846123d6565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b60006126ba82612838565b91506126c583612838565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126fa576126f96128de565b5b828201905092915050565b600061271082612838565b915061271b83612838565b92508261272b5761272a61290d565b5b828204905092915050565b600061274182612838565b915061274c83612838565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612785576127846128de565b5b828202905092915050565b600061279b82612838565b91506127a683612838565b9250828210156127b9576127b86128de565b5b828203905092915050565b60006127cf82612818565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561286d578082015181840152602081019050612852565b8381111561287c576000848401525b50505050565b600061288d82612838565b915060008214156128a1576128a06128de565b5b600182039050919050565b600060028204905060018216806128c457607f821691505b602082108114156128d8576128d761293c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b612d6b816127c4565b8114612d7657600080fd5b50565b612d82816127d6565b8114612d8d57600080fd5b50565b612d99816127e2565b8114612da457600080fd5b50565b612db0816127ec565b8114612dbb57600080fd5b50565b612dc781612838565b8114612dd257600080fd5b5056fea264697066735822122073b1fc8a4350a58f83e65b751f3d71512c113624ada906b1fcdd14e7e66a66d064736f6c63430008040033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101da5760003560e01c806370a0823111610104578063a457c2d7116100a2578063d547741f11610071578063d547741f14610557578063dd62ed3e14610573578063e39e165a146105a3578063e63ab1e9146105c1576101da565b8063a457c2d7146104bd578063a9059cbb146104ed578063af1171ca1461051d578063d539139314610539576101da565b806391d14854116100de57806391d148541461043557806395d89b41146104655780639e7bd52514610483578063a217fddf1461049f576101da565b806370a08231146103df57806379cc67901461040f5780638456cb591461042b576101da565b806330a402c01161017c5780633f4ba83a1161014b5780633f4ba83a1461037f57806340c10f191461038957806342966c68146103a55780635c975abb146103c1576101da565b806330a402c0146102f7578063313ce5671461031557806336568abe14610333578063395093511461034f576101da565b806318160ddd116101b857806318160ddd1461025d57806323b872dd1461027b578063248a9ca3146102ab5780632f2ff15d146102db576101da565b806301ffc9a7146101df57806306fdde031461020f578063095ea7b31461022d575b600080fd5b6101f960048036038101906101f491906120ae565b6105df565b604051610206919061243a565b60405180910390f35b610217610659565b6040516102249190612470565b60405180910390f35b61024760048036038101906102429190611fe4565b6106eb565b604051610254919061243a565b60405180910390f35b61026561070e565b6040516102729190612652565b60405180910390f35b61029560048036038101906102909190611f95565b610718565b6040516102a2919061243a565b60405180910390f35b6102c560048036038101906102c09190612049565b610858565b6040516102d29190612455565b60405180910390f35b6102f560048036038101906102f09190612072565b610878565b005b6102ff610899565b60405161030c919061241f565b60405180910390f35b61031d6108bf565b60405161032a919061266d565b60405180910390f35b61034d60048036038101906103489190612072565b6108c8565b005b61036960048036038101906103649190611fe4565b61094b565b604051610376919061243a565b60405180910390f35b610387610982565b005b6103a3600480360381019061039e9190611fe4565b6109b7565b005b6103bf60048036038101906103ba91906120d7565b6109f0565b005b6103c9610a04565b6040516103d6919061243a565b60405180910390f35b6103f960048036038101906103f49190611f30565b610a1b565b6040516104069190612652565b60405180910390f35b61042960048036038101906104249190611fe4565b610a63565b005b610433610a83565b005b61044f600480360381019061044a9190612072565b610ab8565b60405161045c919061243a565b60405180910390f35b61046d610b23565b60405161047a9190612470565b60405180910390f35b61049d60048036038101906104989190612020565b610bb5565b005b6104a7610bfd565b6040516104b49190612455565b60405180910390f35b6104d760048036038101906104d29190611fe4565b610c04565b6040516104e4919061243a565b60405180910390f35b61050760048036038101906105029190611fe4565b610c7b565b604051610514919061243a565b60405180910390f35b61053760048036038101906105329190611f30565b610daf565b005b610541610e1e565b60405161054e9190612455565b60405180910390f35b610571600480360381019061056c9190612072565b610e42565b005b61058d60048036038101906105889190611f59565b610e63565b60405161059a9190612652565b60405180910390f35b6105ab610eea565b6040516105b8919061243a565b60405180910390f35b6105c9610efd565b6040516105d69190612455565b60405180910390f35b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610652575061065182610f21565b5b9050919050565b606060038054610668906128ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610694906128ac565b80156106e15780601f106106b6576101008083540402835291602001916106e1565b820191906000526020600020905b8154815290600101906020018083116106c457829003601f168201915b5050505050905090565b6000806106f6610f8b565b9050610703818585610f93565b600191505092915050565b6000600254905090565b600080610723610f8b565b905061073085828561115e565b60011515600760149054906101000a900460ff16151514801561075c575069043c33c193756480000083115b15610841576000690878678326eac90000008411156107d2576910f0cf064dd5920000008411156107b6576107af6103e86107a1600f876111ea90919063ffffffff16565b61120090919063ffffffff16565b90506107cd565b6107ca60648561120090919063ffffffff16565b90505b6107fd565b6107fa6103e86107ec6005876111ea90919063ffffffff16565b61120090919063ffffffff16565b90505b61082a86600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611216565b61083d818561148e90919063ffffffff16565b9350505b61084c858585611216565b60019150509392505050565b600060066000838152602001908152602001600020600101549050919050565b61088182610858565b61088a816114a4565b61089483836114b8565b505050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006012905090565b6108d0610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461093d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161093490612612565b60405180910390fd5b6109478282611599565b5050565b600080610956610f8b565b90506109778185856109688589610e63565b61097291906126af565b610f93565b600191505092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6109ac816114a4565b6109b461167b565b50565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109e1816114a4565b6109eb83836116de565b505050565b610a016109fb610f8b565b82611835565b50565b6000600560009054906101000a900460ff16905090565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b610a7582610a6f610f8b565b8361115e565b610a7f8282611835565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610aad816114a4565b610ab5611a03565b50565b60006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060048054610b32906128ac565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5e906128ac565b8015610bab5780601f10610b8057610100808354040283529160200191610bab565b820191906000526020600020905b815481529060010190602001808311610b8e57829003601f168201915b5050505050905090565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610bdf816114a4565b81600760146101000a81548160ff0219169083151502179055505050565b6000801b81565b600080610c0f610f8b565b90506000610c1d8286610e63565b905083811015610c62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c59906125f2565b60405180910390fd5b610c6f8286868403610f93565b60019250505092915050565b600080610c86610f8b565b905060011515600760149054906101000a900460ff161515148015610cb4575069043c33c193756480000083115b15610d99576000690878678326eac9000000841115610d2a576910f0cf064dd592000000841115610d0e57610d076103e8610cf9600f876111ea90919063ffffffff16565b61120090919063ffffffff16565b9050610d25565b610d2260648561120090919063ffffffff16565b90505b610d55565b610d526103e8610d446005876111ea90919063ffffffff16565b61120090919063ffffffff16565b90505b610d8282600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683611216565b610d95818561148e90919063ffffffff16565b9350505b610da4818585611216565b600191505092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6610dd9816114a4565b81600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b610e4b82610858565b610e54816114a4565b610e5e8383611599565b505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600760149054906101000a900460ff1681565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611003576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ffa906125d2565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611073576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161106a90612512565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516111519190612652565b60405180910390a3505050565b600061116a8484610e63565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146111e457818110156111d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111cd90612532565b60405180910390fd5b6111e38484848403610f93565b5b50505050565b600081836111f89190612736565b905092915050565b6000818361120e9190612705565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611286576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161127d906125b2565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156112f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ed906124b2565b60405180910390fd5b611301838383611a66565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611387576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161137e90612552565b60405180910390fd5b8181036000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114759190612652565b60405180910390a3611488848484611a7e565b50505050565b6000818361149c9190612790565b905092915050565b6114b5816114b0610f8b565b611a83565b50565b6114c28282610ab8565b6115955760016006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061153a610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6115a38282610ab8565b156116775760006006600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555061161c610f8b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b611683611b08565b6000600560006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6116c7610f8b565b6040516116d4919061241f565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561174e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161174590612632565b60405180910390fd5b61175a60008383611a66565b806002600082825461176c91906126af565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161181d9190612652565b60405180910390a361183160008383611a7e565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189c90612592565b60405180910390fd5b6118b182600083611a66565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611937576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192e906124f2565b60405180910390fd5b8181036000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516119ea9190612652565b60405180910390a36119fe83600084611a7e565b505050565b611a0b611b51565b6001600560006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a4f610f8b565b604051611a5c919061241f565b60405180910390a1565b611a6e611b51565b611a79838383611b9b565b505050565b505050565b611a8d8282610ab8565b611b0457611a9a81611ba0565b611aa88360001c6020611bcd565b604051602001611ab99291906123e5565b6040516020818303038152906040526040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611afb9190612470565b60405180910390fd5b5050565b611b10610a04565b611b4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b46906124d2565b60405180910390fd5b565b611b59610a04565b15611b99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9090612572565b60405180910390fd5b565b505050565b6060611bc68273ffffffffffffffffffffffffffffffffffffffff16601460ff16611bcd565b9050919050565b606060006002836002611be09190612736565b611bea91906126af565b67ffffffffffffffff811115611c29577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611c5b5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611cb9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611d43577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002611d839190612736565b611d8d91906126af565b90505b6001811115611e79577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611df5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b1a60f81b828281518110611e32577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080611e7290612882565b9050611d90565b5060008414611ebd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eb490612492565b60405180910390fd5b8091505092915050565b600081359050611ed681612d62565b92915050565b600081359050611eeb81612d79565b92915050565b600081359050611f0081612d90565b92915050565b600081359050611f1581612da7565b92915050565b600081359050611f2a81612dbe565b92915050565b600060208284031215611f4257600080fd5b6000611f5084828501611ec7565b91505092915050565b60008060408385031215611f6c57600080fd5b6000611f7a85828601611ec7565b9250506020611f8b85828601611ec7565b9150509250929050565b600080600060608486031215611faa57600080fd5b6000611fb886828701611ec7565b9350506020611fc986828701611ec7565b9250506040611fda86828701611f1b565b9150509250925092565b60008060408385031215611ff757600080fd5b600061200585828601611ec7565b925050602061201685828601611f1b565b9150509250929050565b60006020828403121561203257600080fd5b600061204084828501611edc565b91505092915050565b60006020828403121561205b57600080fd5b600061206984828501611ef1565b91505092915050565b6000806040838503121561208557600080fd5b600061209385828601611ef1565b92505060206120a485828601611ec7565b9150509250929050565b6000602082840312156120c057600080fd5b60006120ce84828501611f06565b91505092915050565b6000602082840312156120e957600080fd5b60006120f784828501611f1b565b91505092915050565b612109816127c4565b82525050565b612118816127d6565b82525050565b612127816127e2565b82525050565b600061213882612688565b6121428185612693565b935061215281856020860161284f565b61215b8161296b565b840191505092915050565b600061217182612688565b61217b81856126a4565b935061218b81856020860161284f565b80840191505092915050565b60006121a4602083612693565b91506121af8261297c565b602082019050919050565b60006121c7602383612693565b91506121d2826129a5565b604082019050919050565b60006121ea601483612693565b91506121f5826129f4565b602082019050919050565b600061220d602283612693565b915061221882612a1d565b604082019050919050565b6000612230602283612693565b915061223b82612a6c565b604082019050919050565b6000612253601d83612693565b915061225e82612abb565b602082019050919050565b6000612276602683612693565b915061228182612ae4565b604082019050919050565b6000612299601083612693565b91506122a482612b33565b602082019050919050565b60006122bc602183612693565b91506122c782612b5c565b604082019050919050565b60006122df602583612693565b91506122ea82612bab565b604082019050919050565b6000612302602483612693565b915061230d82612bfa565b604082019050919050565b60006123256017836126a4565b915061233082612c49565b601782019050919050565b6000612348602583612693565b915061235382612c72565b604082019050919050565b600061236b6011836126a4565b915061237682612cc1565b601182019050919050565b600061238e602f83612693565b915061239982612cea565b604082019050919050565b60006123b1601f83612693565b91506123bc82612d39565b602082019050919050565b6123d081612838565b82525050565b6123df81612842565b82525050565b60006123f082612318565b91506123fc8285612166565b91506124078261235e565b91506124138284612166565b91508190509392505050565b60006020820190506124346000830184612100565b92915050565b600060208201905061244f600083018461210f565b92915050565b600060208201905061246a600083018461211e565b92915050565b6000602082019050818103600083015261248a818461212d565b905092915050565b600060208201905081810360008301526124ab81612197565b9050919050565b600060208201905081810360008301526124cb816121ba565b9050919050565b600060208201905081810360008301526124eb816121dd565b9050919050565b6000602082019050818103600083015261250b81612200565b9050919050565b6000602082019050818103600083015261252b81612223565b9050919050565b6000602082019050818103600083015261254b81612246565b9050919050565b6000602082019050818103600083015261256b81612269565b9050919050565b6000602082019050818103600083015261258b8161228c565b9050919050565b600060208201905081810360008301526125ab816122af565b9050919050565b600060208201905081810360008301526125cb816122d2565b9050919050565b600060208201905081810360008301526125eb816122f5565b9050919050565b6000602082019050818103600083015261260b8161233b565b9050919050565b6000602082019050818103600083015261262b81612381565b9050919050565b6000602082019050818103600083015261264b816123a4565b9050919050565b600060208201905061266760008301846123c7565b92915050565b600060208201905061268260008301846123d6565b92915050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b60006126ba82612838565b91506126c583612838565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156126fa576126f96128de565b5b828201905092915050565b600061271082612838565b915061271b83612838565b92508261272b5761272a61290d565b5b828204905092915050565b600061274182612838565b915061274c83612838565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612785576127846128de565b5b828202905092915050565b600061279b82612838565b91506127a683612838565b9250828210156127b9576127b86128de565b5b828203905092915050565b60006127cf82612818565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561286d578082015181840152602081019050612852565b8381111561287c576000848401525b50505050565b600061288d82612838565b915060008214156128a1576128a06128de565b5b600182039050919050565b600060028204905060018216806128c457607f821691505b602082108114156128d8576128d761293c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b612d6b816127c4565b8114612d7657600080fd5b50565b612d82816127d6565b8114612d8d57600080fd5b50565b612d99816127e2565b8114612da457600080fd5b50565b612db0816127ec565b8114612dbb57600080fd5b50565b612dc781612838565b8114612dd257600080fd5b5056fea264697066735822122073b1fc8a4350a58f83e65b751f3d71512c113624ada906b1fcdd14e7e66a66d064736f6c63430008040033

Deployed Bytecode Sourcemap

57361:3753:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30730:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44812:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47163:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45932:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60315:792;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32553:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32994:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57611:23;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45774:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34138:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48648:238;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58723:77;;;:::i;:::-;;58982:107;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56583:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38072:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46103:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56993:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58576:73;;;:::i;:::-;;31026:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45031:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58399:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30131:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49389:436;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59583:724;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58155:118;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57542:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33434:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46692:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57641:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57473:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30730:204;30815:4;30854:32;30839:47;;;:11;:47;;;;:87;;;;30890:36;30914:11;30890:23;:36::i;:::-;30839:87;30832:94;;30730:204;;;:::o;44812:100::-;44866:13;44899:5;44892:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44812:100;:::o;47163:201::-;47246:4;47263:13;47279:12;:10;:12::i;:::-;47263:28;;47302:32;47311:5;47318:7;47327:6;47302:8;:32::i;:::-;47352:4;47345:11;;;47163:201;;;;:::o;45932:108::-;45993:7;46020:12;;46013:19;;45932:108;:::o;60315:792::-;60438:4;60455:15;60473:12;:10;:12::i;:::-;60455:30;;60496:38;60512:4;60518:7;60527:6;60496:15;:38::i;:::-;60564:4;60551:17;;:9;;;;;;;;;;;:17;;;:44;;;;;60581:14;60572:6;:23;60551:44;60547:491;;;60612:11;60651:14;60642:6;:23;60638:305;;;60699:14;60690:6;:23;60686:172;;;60744:24;60763:4;60744:14;60755:2;60744:6;:10;;:14;;;;:::i;:::-;:18;;:24;;;;:::i;:::-;60738:30;;60686:172;;;60823:15;60834:3;60823:6;:10;;:15;;;;:::i;:::-;60817:21;;60686:172;60638:305;;;60904:23;60922:4;60904:13;60915:1;60904:6;:10;;:13;;;;:::i;:::-;:17;;:23;;;;:::i;:::-;60898:29;;60638:305;60957:30;60967:4;60973:8;;;;;;;;;;;60983:3;60957:9;:30::i;:::-;61011:15;61022:3;61011:6;:10;;:15;;;;:::i;:::-;61002:24;;60547:491;;61048:27;61058:4;61064:2;61068:6;61048:9;:27::i;:::-;61095:4;61088:11;;;60315:792;;;;;:::o;32553:131::-;32627:7;32654:6;:12;32661:4;32654:12;;;;;;;;;;;:22;;;32647:29;;32553:131;;;:::o;32994:147::-;33077:18;33090:4;33077:12;:18::i;:::-;30622:16;30633:4;30622:10;:16::i;:::-;33108:25:::1;33119:4;33125:7;33108:10;:25::i;:::-;32994:147:::0;;;:::o;57611:23::-;;;;;;;;;;;;;:::o;45774:93::-;45832:5;45857:2;45850:9;;45774:93;:::o;34138:218::-;34245:12;:10;:12::i;:::-;34234:23;;:7;:23;;;34226:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;34322:26;34334:4;34340:7;34322:11;:26::i;:::-;34138:218;;:::o;48648:238::-;48736:4;48753:13;48769:12;:10;:12::i;:::-;48753:28;;48792:64;48801:5;48808:7;48845:10;48817:25;48827:5;48834:7;48817:9;:25::i;:::-;:38;;;;:::i;:::-;48792:8;:64::i;:::-;48874:4;48867:11;;;48648:238;;;;:::o;58723:77::-;57511:24;30622:16;30633:4;30622:10;:16::i;:::-;58782:10:::1;:8;:10::i;:::-;58723:77:::0;:::o;58982:107::-;57580:24;30622:16;30633:4;30622:10;:16::i;:::-;59064:17:::1;59070:2;59074:6;59064:5;:17::i;:::-;58982:107:::0;;;:::o;56583:91::-;56639:27;56645:12;:10;:12::i;:::-;56659:6;56639:5;:27::i;:::-;56583:91;:::o;38072:86::-;38119:4;38143:7;;;;;;;;;;;38136:14;;38072:86;:::o;46103:127::-;46177:7;46204:9;:18;46214:7;46204:18;;;;;;;;;;;;;;;;46197:25;;46103:127;;;:::o;56993:164::-;57070:46;57086:7;57095:12;:10;:12::i;:::-;57109:6;57070:15;:46::i;:::-;57127:22;57133:7;57142:6;57127:5;:22::i;:::-;56993:164;;:::o;58576:73::-;57511:24;30622:16;30633:4;30622:10;:16::i;:::-;58633:8:::1;:6;:8::i;:::-;58576:73:::0;:::o;31026:147::-;31112:4;31136:6;:12;31143:4;31136:12;;;;;;;;;;;:20;;:29;31157:7;31136:29;;;;;;;;;;;;;;;;;;;;;;;;;31129:36;;31026:147;;;;:::o;45031:104::-;45087:13;45120:7;45113:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45031:104;:::o;58399:105::-;57580:24;30622:16;30633:4;30622:10;:16::i;:::-;58490:6:::1;58478:9;;:18;;;;;;;;;;;;;;;;;;58399:105:::0;;:::o;30131:49::-;30176:4;30131:49;;;:::o;49389:436::-;49482:4;49499:13;49515:12;:10;:12::i;:::-;49499:28;;49538:24;49565:25;49575:5;49582:7;49565:9;:25::i;:::-;49538:52;;49629:15;49609:16;:35;;49601:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;49722:60;49731:5;49738:7;49766:15;49747:16;:34;49722:8;:60::i;:::-;49813:4;49806:11;;;;49389:436;;;;:::o;59583:724::-;59681:4;59703:13;59719:12;:10;:12::i;:::-;59703:28;;59762:4;59749:17;;:9;;;;;;;;;;;:17;;;:44;;;;;59779:14;59770:6;:23;59749:44;59744:493;;;59810:11;59849:14;59840:6;:23;59836:305;;;59897:14;59888:6;:23;59884:172;;;59942:24;59961:4;59942:14;59953:2;59942:6;:10;;:14;;;;:::i;:::-;:18;;:24;;;;:::i;:::-;59936:30;;59884:172;;;60021:15;60032:3;60021:6;:10;;:15;;;;:::i;:::-;60015:21;;59884:172;59836:305;;;60102:23;60120:4;60102:13;60113:1;60102:6;:10;;:13;;;;:::i;:::-;:17;;:23;;;;:::i;:::-;60096:29;;59836:305;60155:31;60165:5;60172:8;;;;;;;;;;;60182:3;60155:9;:31::i;:::-;60210:15;60221:3;60210:6;:10;;:15;;;;:::i;:::-;60201:24;;59744:493;;60249:28;60259:5;60266:2;60270:6;60249:9;:28::i;:::-;60295:4;60288:11;;;59583:724;;;;:::o;58155:118::-;57580:24;30622:16;30633:4;30622:10;:16::i;:::-;58253:12:::1;58242:8;;:23;;;;;;;;;;;;;;;;;;58155:118:::0;;:::o;57542:62::-;57580:24;57542:62;:::o;33434:149::-;33518:18;33531:4;33518:12;:18::i;:::-;30622:16;30633:4;30622:10;:16::i;:::-;33549:26:::1;33561:4;33567:7;33549:11;:26::i;:::-;33434:149:::0;;;:::o;46692:151::-;46781:7;46808:11;:18;46820:5;46808:18;;;;;;;;;;;;;;;:27;46827:7;46808:27;;;;;;;;;;;;;;;;46801:34;;46692:151;;;;:::o;57641:29::-;;;;;;;;;;;;;:::o;57473:62::-;57511:24;57473:62;:::o;8856:157::-;8941:4;8980:25;8965:40;;;:11;:40;;;;8958:47;;8856:157;;;:::o;27939:98::-;27992:7;28019:10;28012:17;;27939:98;:::o;53416:380::-;53569:1;53552:19;;:5;:19;;;;53544:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53650:1;53631:21;;:7;:21;;;;53623:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;53734:6;53704:11;:18;53716:5;53704:18;;;;;;;;;;;;;;;:27;53723:7;53704:27;;;;;;;;;;;;;;;:36;;;;53772:7;53756:32;;53765:5;53756:32;;;53781:6;53756:32;;;;;;:::i;:::-;;;;;;;;53416:380;;;:::o;54087:453::-;54222:24;54249:25;54259:5;54266:7;54249:9;:25::i;:::-;54222:52;;54309:17;54289:16;:37;54285:248;;54371:6;54351:16;:26;;54343:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;54455:51;54464:5;54471:7;54499:6;54480:16;:25;54455:8;:51::i;:::-;54285:248;54087:453;;;;:::o;3647:98::-;3705:7;3736:1;3732;:5;;;;:::i;:::-;3725:12;;3647:98;;;;:::o;4046:::-;4104:7;4135:1;4131;:5;;;;:::i;:::-;4124:12;;4046:98;;;;:::o;50295:840::-;50442:1;50426:18;;:4;:18;;;;50418:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;50519:1;50505:16;;:2;:16;;;;50497:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;50574:38;50595:4;50601:2;50605:6;50574:20;:38::i;:::-;50625:19;50647:9;:15;50657:4;50647:15;;;;;;;;;;;;;;;;50625:37;;50696:6;50681:11;:21;;50673:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;50813:6;50799:11;:20;50781:9;:15;50791:4;50781:15;;;;;;;;;;;;;;;:38;;;;51016:6;50999:9;:13;51009:2;50999:13;;;;;;;;;;;;;;;;:23;;;;;;;;;;;51066:2;51051:26;;51060:4;51051:26;;;51070:6;51051:26;;;;;;:::i;:::-;;;;;;;;51090:37;51110:4;51116:2;51120:6;51090:19;:37::i;:::-;50295:840;;;;:::o;3290:98::-;3348:7;3379:1;3375;:5;;;;:::i;:::-;3368:12;;3290:98;;;;:::o;31477:105::-;31544:30;31555:4;31561:12;:10;:12::i;:::-;31544:10;:30::i;:::-;31477:105;:::o;35735:238::-;35819:22;35827:4;35833:7;35819;:22::i;:::-;35814:152;;35890:4;35858:6;:12;35865:4;35858:12;;;;;;;;;;;:20;;:29;35879:7;35858:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;35941:12;:10;:12::i;:::-;35914:40;;35932:7;35914:40;;35926:4;35914:40;;;;;;;;;;35814:152;35735:238;;:::o;36153:239::-;36237:22;36245:4;36251:7;36237;:22::i;:::-;36233:152;;;36308:5;36276:6;:12;36283:4;36276:12;;;;;;;;;;;:20;;:29;36297:7;36276:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;36360:12;:10;:12::i;:::-;36333:40;;36351:7;36333:40;;36345:4;36333:40;;;;;;;;;;36233:152;36153:239;;:::o;38927:120::-;37936:16;:14;:16::i;:::-;38996:5:::1;38986:7;;:15;;;;;;;;;;;;;;;;;;39017:22;39026:12;:10;:12::i;:::-;39017:22;;;;;;:::i;:::-;;;;;;;;38927:120::o:0;51422:548::-;51525:1;51506:21;;:7;:21;;;;51498:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;51576:49;51605:1;51609:7;51618:6;51576:20;:49::i;:::-;51654:6;51638:12;;:22;;;;;;;:::i;:::-;;;;;;;;51831:6;51809:9;:18;51819:7;51809:18;;;;;;;;;;;;;;;;:28;;;;;;;;;;;51885:7;51864:37;;51881:1;51864:37;;;51894:6;51864:37;;;;;;:::i;:::-;;;;;;;;51914:48;51942:1;51946:7;51955:6;51914:19;:48::i;:::-;51422:548;;:::o;52303:675::-;52406:1;52387:21;;:7;:21;;;;52379:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;52459:49;52480:7;52497:1;52501:6;52459:20;:49::i;:::-;52521:22;52546:9;:18;52556:7;52546:18;;;;;;;;;;;;;;;;52521:43;;52601:6;52583:14;:24;;52575:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;52720:6;52703:14;:23;52682:9;:18;52692:7;52682:18;;;;;;;;;;;;;;;:44;;;;52837:6;52821:12;;:22;;;;;;;;;;;52898:1;52872:37;;52881:7;52872:37;;;52902:6;52872:37;;;;;;:::i;:::-;;;;;;;;52922:48;52942:7;52959:1;52963:6;52922:19;:48::i;:::-;52303:675;;;:::o;38668:118::-;37677:19;:17;:19::i;:::-;38738:4:::1;38728:7;;:14;;;;;;;;;;;;;;;;;;38758:20;38765:12;:10;:12::i;:::-;38758:20;;;;;;:::i;:::-;;;;;;;;38668:118::o:0;59374:201::-;37677:19;:17;:19::i;:::-;59523:44:::1;59550:4;59556:2;59560:6;59523:26;:44::i;:::-;59374:201:::0;;;:::o;55869:124::-;;;;:::o;31872:492::-;31961:22;31969:4;31975:7;31961;:22::i;:::-;31956:401;;32149:28;32169:7;32149:19;:28::i;:::-;32250:38;32278:4;32270:13;;32285:2;32250:19;:38::i;:::-;32054:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;32000:345;;;;;;;;;;;:::i;:::-;;;;;;;;31956:401;31872:492;;:::o;38416:108::-;38483:8;:6;:8::i;:::-;38475:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;38416:108::o;38231:::-;38302:8;:6;:8::i;:::-;38301:9;38293:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;38231:108::o;55140:125::-;;;;:::o;24061:151::-;24119:13;24152:52;24180:4;24164:22;;22216:2;24152:52;;:11;:52::i;:::-;24145:59;;24061:151;;;:::o;23457:447::-;23532:13;23558:19;23603:1;23594:6;23590:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;23580:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23558:47;;23616:15;:6;23623:1;23616:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;23642;:6;23649:1;23642:9;;;;;;;;;;;;;;;;;;;:15;;;;;;;;;;;23673:9;23698:1;23689:6;23685:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;23673:26;;23668:131;23705:1;23701;:5;23668:131;;;23740:8;23757:3;23749:5;:11;23740:21;;;;;;;;;;;;;;;;;;23728:6;23735:1;23728:9;;;;;;;;;;;;;;;;;;;:33;;;;;;;;;;;23786:1;23776:11;;;;;23708:3;;;;:::i;:::-;;;23668:131;;;;23826:1;23817:5;:10;23809:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;23889:6;23875:21;;;23457:447;;;;:::o;7:139:1:-;53:5;91:6;78:20;69:29;;107:33;134:5;107:33;:::i;:::-;59:87;;;;:::o;152:133::-;195:5;233:6;220:20;211:29;;249:30;273:5;249:30;:::i;:::-;201:84;;;;:::o;291:139::-;337:5;375:6;362:20;353:29;;391:33;418:5;391:33;:::i;:::-;343:87;;;;:::o;436:137::-;481:5;519:6;506:20;497:29;;535:32;561:5;535:32;:::i;:::-;487:86;;;;:::o;579:139::-;625:5;663:6;650:20;641:29;;679:33;706:5;679:33;:::i;:::-;631:87;;;;:::o;724:262::-;783:6;832:2;820:9;811:7;807:23;803:32;800:2;;;848:1;845;838:12;800:2;891:1;916:53;961:7;952:6;941:9;937:22;916:53;:::i;:::-;906:63;;862:117;790:196;;;;:::o;992:407::-;1060:6;1068;1117:2;1105:9;1096:7;1092:23;1088:32;1085:2;;;1133:1;1130;1123:12;1085:2;1176:1;1201:53;1246:7;1237:6;1226:9;1222:22;1201:53;:::i;:::-;1191:63;;1147:117;1303:2;1329:53;1374:7;1365:6;1354:9;1350:22;1329:53;:::i;:::-;1319:63;;1274:118;1075:324;;;;;:::o;1405:552::-;1482:6;1490;1498;1547:2;1535:9;1526:7;1522:23;1518:32;1515:2;;;1563:1;1560;1553:12;1515:2;1606:1;1631:53;1676:7;1667:6;1656:9;1652:22;1631:53;:::i;:::-;1621:63;;1577:117;1733:2;1759:53;1804:7;1795:6;1784:9;1780:22;1759:53;:::i;:::-;1749:63;;1704:118;1861:2;1887:53;1932:7;1923:6;1912:9;1908:22;1887:53;:::i;:::-;1877:63;;1832:118;1505:452;;;;;:::o;1963:407::-;2031:6;2039;2088:2;2076:9;2067:7;2063:23;2059:32;2056:2;;;2104:1;2101;2094:12;2056:2;2147:1;2172:53;2217:7;2208:6;2197:9;2193:22;2172:53;:::i;:::-;2162:63;;2118:117;2274:2;2300:53;2345:7;2336:6;2325:9;2321:22;2300:53;:::i;:::-;2290:63;;2245:118;2046:324;;;;;:::o;2376:256::-;2432:6;2481:2;2469:9;2460:7;2456:23;2452:32;2449:2;;;2497:1;2494;2487:12;2449:2;2540:1;2565:50;2607:7;2598:6;2587:9;2583:22;2565:50;:::i;:::-;2555:60;;2511:114;2439:193;;;;:::o;2638:262::-;2697:6;2746:2;2734:9;2725:7;2721:23;2717:32;2714:2;;;2762:1;2759;2752:12;2714:2;2805:1;2830:53;2875:7;2866:6;2855:9;2851:22;2830:53;:::i;:::-;2820:63;;2776:117;2704:196;;;;:::o;2906:407::-;2974:6;2982;3031:2;3019:9;3010:7;3006:23;3002:32;2999:2;;;3047:1;3044;3037:12;2999:2;3090:1;3115:53;3160:7;3151:6;3140:9;3136:22;3115:53;:::i;:::-;3105:63;;3061:117;3217:2;3243:53;3288:7;3279:6;3268:9;3264:22;3243:53;:::i;:::-;3233:63;;3188:118;2989:324;;;;;:::o;3319:260::-;3377:6;3426:2;3414:9;3405:7;3401:23;3397:32;3394:2;;;3442:1;3439;3432:12;3394:2;3485:1;3510:52;3554:7;3545:6;3534:9;3530:22;3510:52;:::i;:::-;3500:62;;3456:116;3384:195;;;;:::o;3585:262::-;3644:6;3693:2;3681:9;3672:7;3668:23;3664:32;3661:2;;;3709:1;3706;3699:12;3661:2;3752:1;3777:53;3822:7;3813:6;3802:9;3798:22;3777:53;:::i;:::-;3767:63;;3723:117;3651:196;;;;:::o;3853:118::-;3940:24;3958:5;3940:24;:::i;:::-;3935:3;3928:37;3918:53;;:::o;3977:109::-;4058:21;4073:5;4058:21;:::i;:::-;4053:3;4046:34;4036:50;;:::o;4092:118::-;4179:24;4197:5;4179:24;:::i;:::-;4174:3;4167:37;4157:53;;:::o;4216:364::-;4304:3;4332:39;4365:5;4332:39;:::i;:::-;4387:71;4451:6;4446:3;4387:71;:::i;:::-;4380:78;;4467:52;4512:6;4507:3;4500:4;4493:5;4489:16;4467:52;:::i;:::-;4544:29;4566:6;4544:29;:::i;:::-;4539:3;4535:39;4528:46;;4308:272;;;;;:::o;4586:377::-;4692:3;4720:39;4753:5;4720:39;:::i;:::-;4775:89;4857:6;4852:3;4775:89;:::i;:::-;4768:96;;4873:52;4918:6;4913:3;4906:4;4899:5;4895:16;4873:52;:::i;:::-;4950:6;4945:3;4941:16;4934:23;;4696:267;;;;;:::o;4969:366::-;5111:3;5132:67;5196:2;5191:3;5132:67;:::i;:::-;5125:74;;5208:93;5297:3;5208:93;:::i;:::-;5326:2;5321:3;5317:12;5310:19;;5115:220;;;:::o;5341:366::-;5483:3;5504:67;5568:2;5563:3;5504:67;:::i;:::-;5497:74;;5580:93;5669:3;5580:93;:::i;:::-;5698:2;5693:3;5689:12;5682:19;;5487:220;;;:::o;5713:366::-;5855:3;5876:67;5940:2;5935:3;5876:67;:::i;:::-;5869:74;;5952:93;6041:3;5952:93;:::i;:::-;6070:2;6065:3;6061:12;6054:19;;5859:220;;;:::o;6085:366::-;6227:3;6248:67;6312:2;6307:3;6248:67;:::i;:::-;6241:74;;6324:93;6413:3;6324:93;:::i;:::-;6442:2;6437:3;6433:12;6426:19;;6231:220;;;:::o;6457:366::-;6599:3;6620:67;6684:2;6679:3;6620:67;:::i;:::-;6613:74;;6696:93;6785:3;6696:93;:::i;:::-;6814:2;6809:3;6805:12;6798:19;;6603:220;;;:::o;6829:366::-;6971:3;6992:67;7056:2;7051:3;6992:67;:::i;:::-;6985:74;;7068:93;7157:3;7068:93;:::i;:::-;7186:2;7181:3;7177:12;7170:19;;6975:220;;;:::o;7201:366::-;7343:3;7364:67;7428:2;7423:3;7364:67;:::i;:::-;7357:74;;7440:93;7529:3;7440:93;:::i;:::-;7558:2;7553:3;7549:12;7542:19;;7347:220;;;:::o;7573:366::-;7715:3;7736:67;7800:2;7795:3;7736:67;:::i;:::-;7729:74;;7812:93;7901:3;7812:93;:::i;:::-;7930:2;7925:3;7921:12;7914:19;;7719:220;;;:::o;7945:366::-;8087:3;8108:67;8172:2;8167:3;8108:67;:::i;:::-;8101:74;;8184:93;8273:3;8184:93;:::i;:::-;8302:2;8297:3;8293:12;8286:19;;8091:220;;;:::o;8317:366::-;8459:3;8480:67;8544:2;8539:3;8480:67;:::i;:::-;8473:74;;8556:93;8645:3;8556:93;:::i;:::-;8674:2;8669:3;8665:12;8658:19;;8463:220;;;:::o;8689:366::-;8831:3;8852:67;8916:2;8911:3;8852:67;:::i;:::-;8845:74;;8928:93;9017:3;8928:93;:::i;:::-;9046:2;9041:3;9037:12;9030:19;;8835:220;;;:::o;9061:402::-;9221:3;9242:85;9324:2;9319:3;9242:85;:::i;:::-;9235:92;;9336:93;9425:3;9336:93;:::i;:::-;9454:2;9449:3;9445:12;9438:19;;9225:238;;;:::o;9469:366::-;9611:3;9632:67;9696:2;9691:3;9632:67;:::i;:::-;9625:74;;9708:93;9797:3;9708:93;:::i;:::-;9826:2;9821:3;9817:12;9810:19;;9615:220;;;:::o;9841:402::-;10001:3;10022:85;10104:2;10099:3;10022:85;:::i;:::-;10015:92;;10116:93;10205:3;10116:93;:::i;:::-;10234:2;10229:3;10225:12;10218:19;;10005:238;;;:::o;10249:366::-;10391:3;10412:67;10476:2;10471:3;10412:67;:::i;:::-;10405:74;;10488:93;10577:3;10488:93;:::i;:::-;10606:2;10601:3;10597:12;10590:19;;10395:220;;;:::o;10621:366::-;10763:3;10784:67;10848:2;10843:3;10784:67;:::i;:::-;10777:74;;10860:93;10949:3;10860:93;:::i;:::-;10978:2;10973:3;10969:12;10962:19;;10767:220;;;:::o;10993:118::-;11080:24;11098:5;11080:24;:::i;:::-;11075:3;11068:37;11058:53;;:::o;11117:112::-;11200:22;11216:5;11200:22;:::i;:::-;11195:3;11188:35;11178:51;;:::o;11235:967::-;11617:3;11639:148;11783:3;11639:148;:::i;:::-;11632:155;;11804:95;11895:3;11886:6;11804:95;:::i;:::-;11797:102;;11916:148;12060:3;11916:148;:::i;:::-;11909:155;;12081:95;12172:3;12163:6;12081:95;:::i;:::-;12074:102;;12193:3;12186:10;;11621:581;;;;;:::o;12208:222::-;12301:4;12339:2;12328:9;12324:18;12316:26;;12352:71;12420:1;12409:9;12405:17;12396:6;12352:71;:::i;:::-;12306:124;;;;:::o;12436:210::-;12523:4;12561:2;12550:9;12546:18;12538:26;;12574:65;12636:1;12625:9;12621:17;12612:6;12574:65;:::i;:::-;12528:118;;;;:::o;12652:222::-;12745:4;12783:2;12772:9;12768:18;12760:26;;12796:71;12864:1;12853:9;12849:17;12840:6;12796:71;:::i;:::-;12750:124;;;;:::o;12880:313::-;12993:4;13031:2;13020:9;13016:18;13008:26;;13080:9;13074:4;13070:20;13066:1;13055:9;13051:17;13044:47;13108:78;13181:4;13172:6;13108:78;:::i;:::-;13100:86;;12998:195;;;;:::o;13199:419::-;13365:4;13403:2;13392:9;13388:18;13380:26;;13452:9;13446:4;13442:20;13438:1;13427:9;13423:17;13416:47;13480:131;13606:4;13480:131;:::i;:::-;13472:139;;13370:248;;;:::o;13624:419::-;13790:4;13828:2;13817:9;13813:18;13805:26;;13877:9;13871:4;13867:20;13863:1;13852:9;13848:17;13841:47;13905:131;14031:4;13905:131;:::i;:::-;13897:139;;13795:248;;;:::o;14049:419::-;14215:4;14253:2;14242:9;14238:18;14230:26;;14302:9;14296:4;14292:20;14288:1;14277:9;14273:17;14266:47;14330:131;14456:4;14330:131;:::i;:::-;14322:139;;14220:248;;;:::o;14474:419::-;14640:4;14678:2;14667:9;14663:18;14655:26;;14727:9;14721:4;14717:20;14713:1;14702:9;14698:17;14691:47;14755:131;14881:4;14755:131;:::i;:::-;14747:139;;14645:248;;;:::o;14899:419::-;15065:4;15103:2;15092:9;15088:18;15080:26;;15152:9;15146:4;15142:20;15138:1;15127:9;15123:17;15116:47;15180:131;15306:4;15180:131;:::i;:::-;15172:139;;15070:248;;;:::o;15324:419::-;15490:4;15528:2;15517:9;15513:18;15505:26;;15577:9;15571:4;15567:20;15563:1;15552:9;15548:17;15541:47;15605:131;15731:4;15605:131;:::i;:::-;15597:139;;15495:248;;;:::o;15749:419::-;15915:4;15953:2;15942:9;15938:18;15930:26;;16002:9;15996:4;15992:20;15988:1;15977:9;15973:17;15966:47;16030:131;16156:4;16030:131;:::i;:::-;16022:139;;15920:248;;;:::o;16174:419::-;16340:4;16378:2;16367:9;16363:18;16355:26;;16427:9;16421:4;16417:20;16413:1;16402:9;16398:17;16391:47;16455:131;16581:4;16455:131;:::i;:::-;16447:139;;16345:248;;;:::o;16599:419::-;16765:4;16803:2;16792:9;16788:18;16780:26;;16852:9;16846:4;16842:20;16838:1;16827:9;16823:17;16816:47;16880:131;17006:4;16880:131;:::i;:::-;16872:139;;16770:248;;;:::o;17024:419::-;17190:4;17228:2;17217:9;17213:18;17205:26;;17277:9;17271:4;17267:20;17263:1;17252:9;17248:17;17241:47;17305:131;17431:4;17305:131;:::i;:::-;17297:139;;17195:248;;;:::o;17449:419::-;17615:4;17653:2;17642:9;17638:18;17630:26;;17702:9;17696:4;17692:20;17688:1;17677:9;17673:17;17666:47;17730:131;17856:4;17730:131;:::i;:::-;17722:139;;17620:248;;;:::o;17874:419::-;18040:4;18078:2;18067:9;18063:18;18055:26;;18127:9;18121:4;18117:20;18113:1;18102:9;18098:17;18091:47;18155:131;18281:4;18155:131;:::i;:::-;18147:139;;18045:248;;;:::o;18299:419::-;18465:4;18503:2;18492:9;18488:18;18480:26;;18552:9;18546:4;18542:20;18538:1;18527:9;18523:17;18516:47;18580:131;18706:4;18580:131;:::i;:::-;18572:139;;18470:248;;;:::o;18724:419::-;18890:4;18928:2;18917:9;18913:18;18905:26;;18977:9;18971:4;18967:20;18963:1;18952:9;18948:17;18941:47;19005:131;19131:4;19005:131;:::i;:::-;18997:139;;18895:248;;;:::o;19149:222::-;19242:4;19280:2;19269:9;19265:18;19257:26;;19293:71;19361:1;19350:9;19346:17;19337:6;19293:71;:::i;:::-;19247:124;;;;:::o;19377:214::-;19466:4;19504:2;19493:9;19489:18;19481:26;;19517:67;19581:1;19570:9;19566:17;19557:6;19517:67;:::i;:::-;19471:120;;;;:::o;19597:99::-;19649:6;19683:5;19677:12;19667:22;;19656:40;;;:::o;19702:169::-;19786:11;19820:6;19815:3;19808:19;19860:4;19855:3;19851:14;19836:29;;19798:73;;;;:::o;19877:148::-;19979:11;20016:3;20001:18;;19991:34;;;;:::o;20031:305::-;20071:3;20090:20;20108:1;20090:20;:::i;:::-;20085:25;;20124:20;20142:1;20124:20;:::i;:::-;20119:25;;20278:1;20210:66;20206:74;20203:1;20200:81;20197:2;;;20284:18;;:::i;:::-;20197:2;20328:1;20325;20321:9;20314:16;;20075:261;;;;:::o;20342:185::-;20382:1;20399:20;20417:1;20399:20;:::i;:::-;20394:25;;20433:20;20451:1;20433:20;:::i;:::-;20428:25;;20472:1;20462:2;;20477:18;;:::i;:::-;20462:2;20519:1;20516;20512:9;20507:14;;20384:143;;;;:::o;20533:348::-;20573:7;20596:20;20614:1;20596:20;:::i;:::-;20591:25;;20630:20;20648:1;20630:20;:::i;:::-;20625:25;;20818:1;20750:66;20746:74;20743:1;20740:81;20735:1;20728:9;20721:17;20717:105;20714:2;;;20825:18;;:::i;:::-;20714:2;20873:1;20870;20866:9;20855:20;;20581:300;;;;:::o;20887:191::-;20927:4;20947:20;20965:1;20947:20;:::i;:::-;20942:25;;20981:20;20999:1;20981:20;:::i;:::-;20976:25;;21020:1;21017;21014:8;21011:2;;;21025:18;;:::i;:::-;21011:2;21070:1;21067;21063:9;21055:17;;20932:146;;;;:::o;21084:96::-;21121:7;21150:24;21168:5;21150:24;:::i;:::-;21139:35;;21129:51;;;:::o;21186:90::-;21220:7;21263:5;21256:13;21249:21;21238:32;;21228:48;;;:::o;21282:77::-;21319:7;21348:5;21337:16;;21327:32;;;:::o;21365:149::-;21401:7;21441:66;21434:5;21430:78;21419:89;;21409:105;;;:::o;21520:126::-;21557:7;21597:42;21590:5;21586:54;21575:65;;21565:81;;;:::o;21652:77::-;21689:7;21718:5;21707:16;;21697:32;;;:::o;21735:86::-;21770:7;21810:4;21803:5;21799:16;21788:27;;21778:43;;;:::o;21827:307::-;21895:1;21905:113;21919:6;21916:1;21913:13;21905:113;;;22004:1;21999:3;21995:11;21989:18;21985:1;21980:3;21976:11;21969:39;21941:2;21938:1;21934:10;21929:15;;21905:113;;;22036:6;22033:1;22030:13;22027:2;;;22116:1;22107:6;22102:3;22098:16;22091:27;22027:2;21876:258;;;;:::o;22140:171::-;22179:3;22202:24;22220:5;22202:24;:::i;:::-;22193:33;;22248:4;22241:5;22238:15;22235:2;;;22256:18;;:::i;:::-;22235:2;22303:1;22296:5;22292:13;22285:20;;22183:128;;;:::o;22317:320::-;22361:6;22398:1;22392:4;22388:12;22378:22;;22445:1;22439:4;22435:12;22466:18;22456:2;;22522:4;22514:6;22510:17;22500:27;;22456:2;22584;22576:6;22573:14;22553:18;22550:38;22547:2;;;22603:18;;:::i;:::-;22547:2;22368:269;;;;:::o;22643:180::-;22691:77;22688:1;22681:88;22788:4;22785:1;22778:15;22812:4;22809:1;22802:15;22829:180;22877:77;22874:1;22867:88;22974:4;22971:1;22964:15;22998:4;22995:1;22988:15;23015:180;23063:77;23060:1;23053:88;23160:4;23157:1;23150:15;23184:4;23181:1;23174:15;23201:102;23242:6;23293:2;23289:7;23284:2;23277:5;23273:14;23269:28;23259:38;;23249:54;;;:::o;23309:182::-;23449:34;23445:1;23437:6;23433:14;23426:58;23415:76;:::o;23497:222::-;23637:34;23633:1;23625:6;23621:14;23614:58;23706:5;23701:2;23693:6;23689:15;23682:30;23603:116;:::o;23725:170::-;23865:22;23861:1;23853:6;23849:14;23842:46;23831:64;:::o;23901:221::-;24041:34;24037:1;24029:6;24025:14;24018:58;24110:4;24105:2;24097:6;24093:15;24086:29;24007:115;:::o;24128:221::-;24268:34;24264:1;24256:6;24252:14;24245:58;24337:4;24332:2;24324:6;24320:15;24313:29;24234:115;:::o;24355:179::-;24495:31;24491:1;24483:6;24479:14;24472:55;24461:73;:::o;24540:225::-;24680:34;24676:1;24668:6;24664:14;24657:58;24749:8;24744:2;24736:6;24732:15;24725:33;24646:119;:::o;24771:166::-;24911:18;24907:1;24899:6;24895:14;24888:42;24877:60;:::o;24943:220::-;25083:34;25079:1;25071:6;25067:14;25060:58;25152:3;25147:2;25139:6;25135:15;25128:28;25049:114;:::o;25169:224::-;25309:34;25305:1;25297:6;25293:14;25286:58;25378:7;25373:2;25365:6;25361:15;25354:32;25275:118;:::o;25399:223::-;25539:34;25535:1;25527:6;25523:14;25516:58;25608:6;25603:2;25595:6;25591:15;25584:31;25505:117;:::o;25628:173::-;25768:25;25764:1;25756:6;25752:14;25745:49;25734:67;:::o;25807:224::-;25947:34;25943:1;25935:6;25931:14;25924:58;26016:7;26011:2;26003:6;25999:15;25992:32;25913:118;:::o;26037:167::-;26177:19;26173:1;26165:6;26161:14;26154:43;26143:61;:::o;26210:234::-;26350:34;26346:1;26338:6;26334:14;26327:58;26419:17;26414:2;26406:6;26402:15;26395:42;26316:128;:::o;26450:181::-;26590:33;26586:1;26578:6;26574:14;26567:57;26556:75;:::o;26637:122::-;26710:24;26728:5;26710:24;:::i;:::-;26703:5;26700:35;26690:2;;26749:1;26746;26739:12;26690:2;26680:79;:::o;26765:116::-;26835:21;26850:5;26835:21;:::i;:::-;26828:5;26825:32;26815:2;;26871:1;26868;26861:12;26815:2;26805:76;:::o;26887:122::-;26960:24;26978:5;26960:24;:::i;:::-;26953:5;26950:35;26940:2;;26999:1;26996;26989:12;26940:2;26930:79;:::o;27015:120::-;27087:23;27104:5;27087:23;:::i;:::-;27080:5;27077:34;27067:2;;27125:1;27122;27115:12;27067:2;27057:78;:::o;27141:122::-;27214:24;27232:5;27214:24;:::i;:::-;27207:5;27204:35;27194:2;;27253:1;27250;27243:12;27194:2;27184:79;:::o

Swarm Source

ipfs://73b1fc8a4350a58f83e65b751f3d71512c113624ada906b1fcdd14e7e66a66d0
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.