ETH Price: $2,390.92 (+0.79%)

Token

MusicRacerNFT333 (MRCR)
 

Overview

Max Total Supply

47 MRCR

Holders

36

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
0xaimbot.eth
Balance
1 MRCR
0x3597c57789289cd6d0621E82684a3D1a5a50Bc8f
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
MusicRacerNFT333

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-13
*/

// Sources flattened with hardhat v2.6.5 https://hardhat.org

// File contracts/Car.sol


pragma solidity >=0.8.3;

/// @title описание формирования начальной цены машины
struct PriceData {
    /// @notice начальная цена 1=0.001 eth
    uint256 StartPrice;
    /// @notice конечная цена (когда все продано) 1=0.001 eth
    uint256 EndPrice;
    /// @notice тип формирования цены
    /// 0 - только стартовая цена
    /// 1 - линейная интерполяция от начальной цены к конечной
    uint256 PriceType;
}

/// @title тип части машины
struct CarPartType {
    /// @notice вероятность генерации не нуливого значения 100000=100%
    uint256 Probability;
    /// @notice сколько всего частей имеется
    uint256 Count;
}

/// @title тип машины
struct CarType {
    /// @notice все типы частей
    CarPartType[] PartTypes;
    /// @notice вероятности окрасок 100% будет окраска=100000
    uint256[] Colors;
    /// @notice сколько машин создано
    uint256 Count;
    /// @notice максимальное количество генерируемых машин
    uint256 MaxCount;
    /// @notice цена минта
    PriceData Price;
    /// @notice можно ли перекрашивать машины
}

/// @title описание инстанции одной машины
struct Car {
    /// @notice ID типа машины (больше 0, тк 0 это отсуствие типа)
    uint256 TypeId;
    /// @notice установленные части машины 0 - часть не задана
    uint256[] Parts;
    /// @notice какие цвета в машине включены, а какие нет
    bool[] ColorsEnable;
    /// @notice цвета машины
    uint256[] Colors;
}


// File prb-math/contracts/[email protected]

pragma solidity >=0.8.4;

/// @notice Emitted when the result overflows uint256.
error PRBMath__MulDivFixedPointOverflow(uint256 prod1);

/// @notice Emitted when the result overflows uint256.
error PRBMath__MulDivOverflow(uint256 prod1, uint256 denominator);

/// @notice Emitted when one of the inputs is type(int256).min.
error PRBMath__MulDivSignedInputTooSmall();

/// @notice Emitted when the intermediary absolute result overflows int256.
error PRBMath__MulDivSignedOverflow(uint256 rAbs);

/// @notice Emitted when the input is MIN_SD59x18.
error PRBMathSD59x18__AbsInputTooSmall();

/// @notice Emitted when ceiling a number overflows SD59x18.
error PRBMathSD59x18__CeilOverflow(int256 x);

/// @notice Emitted when one of the inputs is MIN_SD59x18.
error PRBMathSD59x18__DivInputTooSmall();

/// @notice Emitted when one of the intermediary unsigned results overflows SD59x18.
error PRBMathSD59x18__DivOverflow(uint256 rAbs);

/// @notice Emitted when the input is greater than 133.084258667509499441.
error PRBMathSD59x18__ExpInputTooBig(int256 x);

/// @notice Emitted when the input is greater than 192.
error PRBMathSD59x18__Exp2InputTooBig(int256 x);

/// @notice Emitted when flooring a number underflows SD59x18.
error PRBMathSD59x18__FloorUnderflow(int256 x);

/// @notice Emitted when converting a basic integer to the fixed-point format overflows SD59x18.
error PRBMathSD59x18__FromIntOverflow(int256 x);

/// @notice Emitted when converting a basic integer to the fixed-point format underflows SD59x18.
error PRBMathSD59x18__FromIntUnderflow(int256 x);

/// @notice Emitted when the product of the inputs is negative.
error PRBMathSD59x18__GmNegativeProduct(int256 x, int256 y);

/// @notice Emitted when multiplying the inputs overflows SD59x18.
error PRBMathSD59x18__GmOverflow(int256 x, int256 y);

/// @notice Emitted when the input is less than or equal to zero.
error PRBMathSD59x18__LogInputTooSmall(int256 x);

/// @notice Emitted when one of the inputs is MIN_SD59x18.
error PRBMathSD59x18__MulInputTooSmall();

/// @notice Emitted when the intermediary absolute result overflows SD59x18.
error PRBMathSD59x18__MulOverflow(uint256 rAbs);

/// @notice Emitted when the intermediary absolute result overflows SD59x18.
error PRBMathSD59x18__PowuOverflow(uint256 rAbs);

/// @notice Emitted when the input is negative.
error PRBMathSD59x18__SqrtNegativeInput(int256 x);

/// @notice Emitted when the calculating the square root overflows SD59x18.
error PRBMathSD59x18__SqrtOverflow(int256 x);

/// @notice Emitted when addition overflows UD60x18.
error PRBMathUD60x18__AddOverflow(uint256 x, uint256 y);

/// @notice Emitted when ceiling a number overflows UD60x18.
error PRBMathUD60x18__CeilOverflow(uint256 x);

/// @notice Emitted when the input is greater than 133.084258667509499441.
error PRBMathUD60x18__ExpInputTooBig(uint256 x);

/// @notice Emitted when the input is greater than 192.
error PRBMathUD60x18__Exp2InputTooBig(uint256 x);

/// @notice Emitted when converting a basic integer to the fixed-point format format overflows UD60x18.
error PRBMathUD60x18__FromUintOverflow(uint256 x);

/// @notice Emitted when multiplying the inputs overflows UD60x18.
error PRBMathUD60x18__GmOverflow(uint256 x, uint256 y);

/// @notice Emitted when the input is less than 1.
error PRBMathUD60x18__LogInputTooSmall(uint256 x);

/// @notice Emitted when the calculating the square root overflows UD60x18.
error PRBMathUD60x18__SqrtOverflow(uint256 x);

/// @notice Emitted when subtraction underflows UD60x18.
error PRBMathUD60x18__SubUnderflow(uint256 x, uint256 y);

/// @dev Common mathematical functions used in both PRBMathSD59x18 and PRBMathUD60x18. Note that this shared library
/// does not always assume the signed 59.18-decimal fixed-point or the unsigned 60.18-decimal fixed-point
/// representation. When it does not, it is explicitly mentioned in the NatSpec documentation.
library PRBMath {
    /// STRUCTS ///

    struct SD59x18 {
        int256 value;
    }

    struct UD60x18 {
        uint256 value;
    }

    /// STORAGE ///

    /// @dev How many trailing decimals can be represented.
    uint256 internal constant SCALE = 1e18;

    /// @dev Largest power of two divisor of SCALE.
    uint256 internal constant SCALE_LPOTD = 262144;

    /// @dev SCALE inverted mod 2^256.
    uint256 internal constant SCALE_INVERSE = 78156646155174841979727994598816262306175212592076161876661508869554232690281;

    /// FUNCTIONS ///

    /// @notice Calculates the binary exponent of x using the binary fraction method.
    /// @dev Has to use 192.64-bit fixed-point numbers.
    /// See https://ethereum.stackexchange.com/a/96594/24693.
    /// @param x The exponent as an unsigned 192.64-bit fixed-point number.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function exp2(uint256 x) internal pure returns (uint256 result) {
        unchecked {
            // Start from 0.5 in the 192.64-bit fixed-point format.
            result = 0x800000000000000000000000000000000000000000000000;

            // Multiply the result by root(2, 2^-i) when the bit at position i is 1. None of the intermediary results overflows
            // because the initial result is 2^191 and all magic factors are less than 2^65.
            if (x & 0x8000000000000000 > 0) {
                result = (result * 0x16A09E667F3BCC909) >> 64;
            }
            if (x & 0x4000000000000000 > 0) {
                result = (result * 0x1306FE0A31B7152DF) >> 64;
            }
            if (x & 0x2000000000000000 > 0) {
                result = (result * 0x1172B83C7D517ADCE) >> 64;
            }
            if (x & 0x1000000000000000 > 0) {
                result = (result * 0x10B5586CF9890F62A) >> 64;
            }
            if (x & 0x800000000000000 > 0) {
                result = (result * 0x1059B0D31585743AE) >> 64;
            }
            if (x & 0x400000000000000 > 0) {
                result = (result * 0x102C9A3E778060EE7) >> 64;
            }
            if (x & 0x200000000000000 > 0) {
                result = (result * 0x10163DA9FB33356D8) >> 64;
            }
            if (x & 0x100000000000000 > 0) {
                result = (result * 0x100B1AFA5ABCBED61) >> 64;
            }
            if (x & 0x80000000000000 > 0) {
                result = (result * 0x10058C86DA1C09EA2) >> 64;
            }
            if (x & 0x40000000000000 > 0) {
                result = (result * 0x1002C605E2E8CEC50) >> 64;
            }
            if (x & 0x20000000000000 > 0) {
                result = (result * 0x100162F3904051FA1) >> 64;
            }
            if (x & 0x10000000000000 > 0) {
                result = (result * 0x1000B175EFFDC76BA) >> 64;
            }
            if (x & 0x8000000000000 > 0) {
                result = (result * 0x100058BA01FB9F96D) >> 64;
            }
            if (x & 0x4000000000000 > 0) {
                result = (result * 0x10002C5CC37DA9492) >> 64;
            }
            if (x & 0x2000000000000 > 0) {
                result = (result * 0x1000162E525EE0547) >> 64;
            }
            if (x & 0x1000000000000 > 0) {
                result = (result * 0x10000B17255775C04) >> 64;
            }
            if (x & 0x800000000000 > 0) {
                result = (result * 0x1000058B91B5BC9AE) >> 64;
            }
            if (x & 0x400000000000 > 0) {
                result = (result * 0x100002C5C89D5EC6D) >> 64;
            }
            if (x & 0x200000000000 > 0) {
                result = (result * 0x10000162E43F4F831) >> 64;
            }
            if (x & 0x100000000000 > 0) {
                result = (result * 0x100000B1721BCFC9A) >> 64;
            }
            if (x & 0x80000000000 > 0) {
                result = (result * 0x10000058B90CF1E6E) >> 64;
            }
            if (x & 0x40000000000 > 0) {
                result = (result * 0x1000002C5C863B73F) >> 64;
            }
            if (x & 0x20000000000 > 0) {
                result = (result * 0x100000162E430E5A2) >> 64;
            }
            if (x & 0x10000000000 > 0) {
                result = (result * 0x1000000B172183551) >> 64;
            }
            if (x & 0x8000000000 > 0) {
                result = (result * 0x100000058B90C0B49) >> 64;
            }
            if (x & 0x4000000000 > 0) {
                result = (result * 0x10000002C5C8601CC) >> 64;
            }
            if (x & 0x2000000000 > 0) {
                result = (result * 0x1000000162E42FFF0) >> 64;
            }
            if (x & 0x1000000000 > 0) {
                result = (result * 0x10000000B17217FBB) >> 64;
            }
            if (x & 0x800000000 > 0) {
                result = (result * 0x1000000058B90BFCE) >> 64;
            }
            if (x & 0x400000000 > 0) {
                result = (result * 0x100000002C5C85FE3) >> 64;
            }
            if (x & 0x200000000 > 0) {
                result = (result * 0x10000000162E42FF1) >> 64;
            }
            if (x & 0x100000000 > 0) {
                result = (result * 0x100000000B17217F8) >> 64;
            }
            if (x & 0x80000000 > 0) {
                result = (result * 0x10000000058B90BFC) >> 64;
            }
            if (x & 0x40000000 > 0) {
                result = (result * 0x1000000002C5C85FE) >> 64;
            }
            if (x & 0x20000000 > 0) {
                result = (result * 0x100000000162E42FF) >> 64;
            }
            if (x & 0x10000000 > 0) {
                result = (result * 0x1000000000B17217F) >> 64;
            }
            if (x & 0x8000000 > 0) {
                result = (result * 0x100000000058B90C0) >> 64;
            }
            if (x & 0x4000000 > 0) {
                result = (result * 0x10000000002C5C860) >> 64;
            }
            if (x & 0x2000000 > 0) {
                result = (result * 0x1000000000162E430) >> 64;
            }
            if (x & 0x1000000 > 0) {
                result = (result * 0x10000000000B17218) >> 64;
            }
            if (x & 0x800000 > 0) {
                result = (result * 0x1000000000058B90C) >> 64;
            }
            if (x & 0x400000 > 0) {
                result = (result * 0x100000000002C5C86) >> 64;
            }
            if (x & 0x200000 > 0) {
                result = (result * 0x10000000000162E43) >> 64;
            }
            if (x & 0x100000 > 0) {
                result = (result * 0x100000000000B1721) >> 64;
            }
            if (x & 0x80000 > 0) {
                result = (result * 0x10000000000058B91) >> 64;
            }
            if (x & 0x40000 > 0) {
                result = (result * 0x1000000000002C5C8) >> 64;
            }
            if (x & 0x20000 > 0) {
                result = (result * 0x100000000000162E4) >> 64;
            }
            if (x & 0x10000 > 0) {
                result = (result * 0x1000000000000B172) >> 64;
            }
            if (x & 0x8000 > 0) {
                result = (result * 0x100000000000058B9) >> 64;
            }
            if (x & 0x4000 > 0) {
                result = (result * 0x10000000000002C5D) >> 64;
            }
            if (x & 0x2000 > 0) {
                result = (result * 0x1000000000000162E) >> 64;
            }
            if (x & 0x1000 > 0) {
                result = (result * 0x10000000000000B17) >> 64;
            }
            if (x & 0x800 > 0) {
                result = (result * 0x1000000000000058C) >> 64;
            }
            if (x & 0x400 > 0) {
                result = (result * 0x100000000000002C6) >> 64;
            }
            if (x & 0x200 > 0) {
                result = (result * 0x10000000000000163) >> 64;
            }
            if (x & 0x100 > 0) {
                result = (result * 0x100000000000000B1) >> 64;
            }
            if (x & 0x80 > 0) {
                result = (result * 0x10000000000000059) >> 64;
            }
            if (x & 0x40 > 0) {
                result = (result * 0x1000000000000002C) >> 64;
            }
            if (x & 0x20 > 0) {
                result = (result * 0x10000000000000016) >> 64;
            }
            if (x & 0x10 > 0) {
                result = (result * 0x1000000000000000B) >> 64;
            }
            if (x & 0x8 > 0) {
                result = (result * 0x10000000000000006) >> 64;
            }
            if (x & 0x4 > 0) {
                result = (result * 0x10000000000000003) >> 64;
            }
            if (x & 0x2 > 0) {
                result = (result * 0x10000000000000001) >> 64;
            }
            if (x & 0x1 > 0) {
                result = (result * 0x10000000000000001) >> 64;
            }

            // We're doing two things at the same time:
            //
            //   1. Multiply the result by 2^n + 1, where "2^n" is the integer part and the one is added to account for
            //      the fact that we initially set the result to 0.5. This is accomplished by subtracting from 191
            //      rather than 192.
            //   2. Convert the result to the unsigned 60.18-decimal fixed-point format.
            //
            // This works because 2^(191-ip) = 2^ip / 2^191, where "ip" is the integer part "2^n".
            result *= SCALE;
            result >>= (191 - (x >> 64));
        }
    }

    /// @notice Finds the zero-based index of the first one in the binary representation of x.
    /// @dev See the note on msb in the "Find First Set" Wikipedia article https://en.wikipedia.org/wiki/Find_first_set
    /// @param x The uint256 number for which to find the index of the most significant bit.
    /// @return msb The index of the most significant bit as an uint256.
    function mostSignificantBit(uint256 x) internal pure returns (uint256 msb) {
        if (x >= 2**128) {
            x >>= 128;
            msb += 128;
        }
        if (x >= 2**64) {
            x >>= 64;
            msb += 64;
        }
        if (x >= 2**32) {
            x >>= 32;
            msb += 32;
        }
        if (x >= 2**16) {
            x >>= 16;
            msb += 16;
        }
        if (x >= 2**8) {
            x >>= 8;
            msb += 8;
        }
        if (x >= 2**4) {
            x >>= 4;
            msb += 4;
        }
        if (x >= 2**2) {
            x >>= 2;
            msb += 2;
        }
        if (x >= 2**1) {
            // No need to shift x any more.
            msb += 1;
        }
    }

    /// @notice Calculates floor(x*y÷denominator) with full precision.
    ///
    /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.
    ///
    /// Requirements:
    /// - The denominator cannot be zero.
    /// - The result must fit within uint256.
    ///
    /// Caveats:
    /// - This function does not work with fixed-point numbers.
    ///
    /// @param x The multiplicand as an uint256.
    /// @param y The multiplier as an uint256.
    /// @param denominator The divisor as an uint256.
    /// @return result The result as an uint256.
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
        // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
        // variables such that product = prod1 * 2^256 + prod0.
        uint256 prod0; // Least significant 256 bits of the product
        uint256 prod1; // Most significant 256 bits of the product
        assembly {
            let mm := mulmod(x, y, not(0))
            prod0 := mul(x, y)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

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

        // Make sure the result is less than 2^256. Also prevents denominator == 0.
        if (prod1 >= denominator) {
            revert PRBMath__MulDivOverflow(prod1, denominator);
        }

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

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

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

        // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
        // See https://cs.stackexchange.com/q/138556/92363.
        unchecked {
            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 lpotdod = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by lpotdod.
                denominator := div(denominator, lpotdod)

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

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

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

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

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

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

    /// @notice Calculates floor(x*y÷1e18) with full precision.
    ///
    /// @dev Variant of "mulDiv" with constant folding, i.e. in which the denominator is always 1e18. Before returning the
    /// final result, we add 1 if (x * y) % SCALE >= HALF_SCALE. Without this, 6.6e-19 would be truncated to 0 instead of
    /// being rounded to 1e-18.  See "Listing 6" and text above it at https://accu.org/index.php/journals/1717.
    ///
    /// Requirements:
    /// - The result must fit within uint256.
    ///
    /// Caveats:
    /// - The body is purposely left uncommented; see the NatSpec comments in "PRBMath.mulDiv" to understand how this works.
    /// - It is assumed that the result can never be type(uint256).max when x and y solve the following two equations:
    ///     1. x * y = type(uint256).max * SCALE
    ///     2. (x * y) % SCALE >= SCALE / 2
    ///
    /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.
    /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function mulDivFixedPoint(uint256 x, uint256 y) internal pure returns (uint256 result) {
        uint256 prod0;
        uint256 prod1;
        assembly {
            let mm := mulmod(x, y, not(0))
            prod0 := mul(x, y)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

        if (prod1 >= SCALE) {
            revert PRBMath__MulDivFixedPointOverflow(prod1);
        }

        uint256 remainder;
        uint256 roundUpUnit;
        assembly {
            remainder := mulmod(x, y, SCALE)
            roundUpUnit := gt(remainder, 499999999999999999)
        }

        if (prod1 == 0) {
            unchecked {
                result = (prod0 / SCALE) + roundUpUnit;
                return result;
            }
        }

        assembly {
            result := add(
                mul(
                    or(
                        div(sub(prod0, remainder), SCALE_LPOTD),
                        mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, SCALE_LPOTD), SCALE_LPOTD), 1))
                    ),
                    SCALE_INVERSE
                ),
                roundUpUnit
            )
        }
    }

    /// @notice Calculates floor(x*y÷denominator) with full precision.
    ///
    /// @dev An extension of "mulDiv" for signed numbers. Works by computing the signs and the absolute values separately.
    ///
    /// Requirements:
    /// - None of the inputs can be type(int256).min.
    /// - The result must fit within int256.
    ///
    /// @param x The multiplicand as an int256.
    /// @param y The multiplier as an int256.
    /// @param denominator The divisor as an int256.
    /// @return result The result as an int256.
    function mulDivSigned(
        int256 x,
        int256 y,
        int256 denominator
    ) internal pure returns (int256 result) {
        if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {
            revert PRBMath__MulDivSignedInputTooSmall();
        }

        // Get hold of the absolute values of x, y and the denominator.
        uint256 ax;
        uint256 ay;
        uint256 ad;
        unchecked {
            ax = x < 0 ? uint256(-x) : uint256(x);
            ay = y < 0 ? uint256(-y) : uint256(y);
            ad = denominator < 0 ? uint256(-denominator) : uint256(denominator);
        }

        // Compute the absolute value of (x*y)÷denominator. The result must fit within int256.
        uint256 rAbs = mulDiv(ax, ay, ad);
        if (rAbs > uint256(type(int256).max)) {
            revert PRBMath__MulDivSignedOverflow(rAbs);
        }

        // Get the signs of x, y and the denominator.
        uint256 sx;
        uint256 sy;
        uint256 sd;
        assembly {
            sx := sgt(x, sub(0, 1))
            sy := sgt(y, sub(0, 1))
            sd := sgt(denominator, sub(0, 1))
        }

        // XOR over sx, sy and sd. This is checking whether there are one or three negative signs in the inputs.
        // If yes, the result should be negative.
        result = sx ^ sy ^ sd == 0 ? -int256(rAbs) : int256(rAbs);
    }

    /// @notice Calculates the square root of x, rounding down.
    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
    ///
    /// Caveats:
    /// - This function does not work with fixed-point numbers.
    ///
    /// @param x The uint256 number for which to calculate the square root.
    /// @return result The result as an uint256.
    function sqrt(uint256 x) internal pure returns (uint256 result) {
        if (x == 0) {
            return 0;
        }

        // Set the initial guess to the closest power of two that is higher than x.
        uint256 xAux = uint256(x);
        result = 1;
        if (xAux >= 0x100000000000000000000000000000000) {
            xAux >>= 128;
            result <<= 64;
        }
        if (xAux >= 0x10000000000000000) {
            xAux >>= 64;
            result <<= 32;
        }
        if (xAux >= 0x100000000) {
            xAux >>= 32;
            result <<= 16;
        }
        if (xAux >= 0x10000) {
            xAux >>= 16;
            result <<= 8;
        }
        if (xAux >= 0x100) {
            xAux >>= 8;
            result <<= 4;
        }
        if (xAux >= 0x10) {
            xAux >>= 4;
            result <<= 2;
        }
        if (xAux >= 0x8) {
            result <<= 1;
        }

        // The operations can never overflow because the result is max 2^127 when it enters this block.
        unchecked {
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1;
            result = (result + x / result) >> 1; // Seven iterations should be enough
            uint256 roundedDownResult = x / result;
            return result >= roundedDownResult ? roundedDownResult : result;
        }
    }
}


// File prb-math/contracts/[email protected]

pragma solidity >=0.8.4;

/// @title PRBMathUD60x18
/// @author Paul Razvan Berg
/// @notice Smart contract library for advanced fixed-point math that works with uint256 numbers considered to have 18
/// trailing decimals. We call this number representation unsigned 60.18-decimal fixed-point, since there can be up to 60
/// digits in the integer part and up to 18 decimals in the fractional part. The numbers are bound by the minimum and the
/// maximum values permitted by the Solidity type uint256.
library PRBMathUD60x18 {
    /// @dev Half the SCALE number.
    uint256 internal constant HALF_SCALE = 5e17;

    /// @dev log2(e) as an unsigned 60.18-decimal fixed-point number.
    uint256 internal constant LOG2_E = 1442695040888963407;

    /// @dev The maximum value an unsigned 60.18-decimal fixed-point number can have.
    uint256 internal constant MAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;

    /// @dev The maximum whole value an unsigned 60.18-decimal fixed-point number can have.
    uint256 internal constant MAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457000000000000000000;

    /// @dev How many trailing decimals can be represented.
    uint256 internal constant SCALE = 1e18;

    /// @notice Calculates arithmetic average of x and y, rounding down.
    /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.
    /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.
    /// @return result The arithmetic average as an unsigned 60.18-decimal fixed-point number.
    function avg(uint256 x, uint256 y) internal pure returns (uint256 result) {
        // The operations can never overflow.
        unchecked {
            // The last operand checks if both x and y are odd and if that is the case, we add 1 to the result. We need
            // to do this because if both numbers are odd, the 0.5 remainder gets truncated twice.
            result = (x >> 1) + (y >> 1) + (x & y & 1);
        }
    }

    /// @notice Yields the least unsigned 60.18 decimal fixed-point number greater than or equal to x.
    ///
    /// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
    ///
    /// Requirements:
    /// - x must be less than or equal to MAX_WHOLE_UD60x18.
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number to ceil.
    /// @param result The least integer greater than or equal to x, as an unsigned 60.18-decimal fixed-point number.
    function ceil(uint256 x) internal pure returns (uint256 result) {
        if (x > MAX_WHOLE_UD60x18) {
            revert PRBMathUD60x18__CeilOverflow(x);
        }
        assembly {
            // Equivalent to "x % SCALE" but faster.
            let remainder := mod(x, SCALE)

            // Equivalent to "SCALE - remainder" but faster.
            let delta := sub(SCALE, remainder)

            // Equivalent to "x + delta * (remainder > 0 ? 1 : 0)" but faster.
            result := add(x, mul(delta, gt(remainder, 0)))
        }
    }

    /// @notice Divides two unsigned 60.18-decimal fixed-point numbers, returning a new unsigned 60.18-decimal fixed-point number.
    ///
    /// @dev Uses mulDiv to enable overflow-safe multiplication and division.
    ///
    /// Requirements:
    /// - The denominator cannot be zero.
    ///
    /// @param x The numerator as an unsigned 60.18-decimal fixed-point number.
    /// @param y The denominator as an unsigned 60.18-decimal fixed-point number.
    /// @param result The quotient as an unsigned 60.18-decimal fixed-point number.
    function div(uint256 x, uint256 y) internal pure returns (uint256 result) {
        result = PRBMath.mulDiv(x, SCALE, y);
    }

    /// @notice Returns Euler's number as an unsigned 60.18-decimal fixed-point number.
    /// @dev See https://en.wikipedia.org/wiki/E_(mathematical_constant).
    function e() internal pure returns (uint256 result) {
        result = 2718281828459045235;
    }

    /// @notice Calculates the natural exponent of x.
    ///
    /// @dev Based on the insight that e^x = 2^(x * log2(e)).
    ///
    /// Requirements:
    /// - All from "log2".
    /// - x must be less than 133.084258667509499441.
    ///
    /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function exp(uint256 x) internal pure returns (uint256 result) {
        // Without this check, the value passed to "exp2" would be greater than 192.
        if (x >= 133084258667509499441) {
            revert PRBMathUD60x18__ExpInputTooBig(x);
        }

        // Do the fixed-point multiplication inline to save gas.
        unchecked {
            uint256 doubleScaleProduct = x * LOG2_E;
            result = exp2((doubleScaleProduct + HALF_SCALE) / SCALE);
        }
    }

    /// @notice Calculates the binary exponent of x using the binary fraction method.
    ///
    /// @dev See https://ethereum.stackexchange.com/q/79903/24693.
    ///
    /// Requirements:
    /// - x must be 192 or less.
    /// - The result must fit within MAX_UD60x18.
    ///
    /// @param x The exponent as an unsigned 60.18-decimal fixed-point number.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function exp2(uint256 x) internal pure returns (uint256 result) {
        // 2^192 doesn't fit within the 192.64-bit format used internally in this function.
        if (x >= 192e18) {
            revert PRBMathUD60x18__Exp2InputTooBig(x);
        }

        unchecked {
            // Convert x to the 192.64-bit fixed-point format.
            uint256 x192x64 = (x << 64) / SCALE;

            // Pass x to the PRBMath.exp2 function, which uses the 192.64-bit fixed-point number representation.
            result = PRBMath.exp2(x192x64);
        }
    }

    /// @notice Yields the greatest unsigned 60.18 decimal fixed-point number less than or equal to x.
    /// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional counterparts.
    /// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
    /// @param x The unsigned 60.18-decimal fixed-point number to floor.
    /// @param result The greatest integer less than or equal to x, as an unsigned 60.18-decimal fixed-point number.
    function floor(uint256 x) internal pure returns (uint256 result) {
        assembly {
            // Equivalent to "x % SCALE" but faster.
            let remainder := mod(x, SCALE)

            // Equivalent to "x - remainder * (remainder > 0 ? 1 : 0)" but faster.
            result := sub(x, mul(remainder, gt(remainder, 0)))
        }
    }

    /// @notice Yields the excess beyond the floor of x.
    /// @dev Based on the odd function definition https://en.wikipedia.org/wiki/Fractional_part.
    /// @param x The unsigned 60.18-decimal fixed-point number to get the fractional part of.
    /// @param result The fractional part of x as an unsigned 60.18-decimal fixed-point number.
    function frac(uint256 x) internal pure returns (uint256 result) {
        assembly {
            result := mod(x, SCALE)
        }
    }

    /// @notice Converts a number from basic integer form to unsigned 60.18-decimal fixed-point representation.
    ///
    /// @dev Requirements:
    /// - x must be less than or equal to MAX_UD60x18 divided by SCALE.
    ///
    /// @param x The basic integer to convert.
    /// @param result The same number in unsigned 60.18-decimal fixed-point representation.
    function fromUint(uint256 x) internal pure returns (uint256 result) {
        unchecked {
            if (x > MAX_UD60x18 / SCALE) {
                revert PRBMathUD60x18__FromUintOverflow(x);
            }
            result = x * SCALE;
        }
    }

    /// @notice Calculates geometric mean of x and y, i.e. sqrt(x * y), rounding down.
    ///
    /// @dev Requirements:
    /// - x * y must fit within MAX_UD60x18, lest it overflows.
    ///
    /// @param x The first operand as an unsigned 60.18-decimal fixed-point number.
    /// @param y The second operand as an unsigned 60.18-decimal fixed-point number.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function gm(uint256 x, uint256 y) internal pure returns (uint256 result) {
        if (x == 0) {
            return 0;
        }

        unchecked {
            // Checking for overflow this way is faster than letting Solidity do it.
            uint256 xy = x * y;
            if (xy / x != y) {
                revert PRBMathUD60x18__GmOverflow(x, y);
            }

            // We don't need to multiply by the SCALE here because the x*y product had already picked up a factor of SCALE
            // during multiplication. See the comments within the "sqrt" function.
            result = PRBMath.sqrt(xy);
        }
    }

    /// @notice Calculates 1 / x, rounding towards zero.
    ///
    /// @dev Requirements:
    /// - x cannot be zero.
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the inverse.
    /// @return result The inverse as an unsigned 60.18-decimal fixed-point number.
    function inv(uint256 x) internal pure returns (uint256 result) {
        unchecked {
            // 1e36 is SCALE * SCALE.
            result = 1e36 / x;
        }
    }

    /// @notice Calculates the natural logarithm of x.
    ///
    /// @dev Based on the insight that ln(x) = log2(x) / log2(e).
    ///
    /// Requirements:
    /// - All from "log2".
    ///
    /// Caveats:
    /// - All from "log2".
    /// - This doesn't return exactly 1 for 2.718281828459045235, for that we would need more fine-grained precision.
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the natural logarithm.
    /// @return result The natural logarithm as an unsigned 60.18-decimal fixed-point number.
    function ln(uint256 x) internal pure returns (uint256 result) {
        // Do the fixed-point multiplication inline to save gas. This is overflow-safe because the maximum value that log2(x)
        // can return is 196205294292027477728.
        unchecked {
            result = (log2(x) * SCALE) / LOG2_E;
        }
    }

    /// @notice Calculates the common logarithm of x.
    ///
    /// @dev First checks if x is an exact power of ten and it stops if yes. If it's not, calculates the common
    /// logarithm based on the insight that log10(x) = log2(x) / log2(10).
    ///
    /// Requirements:
    /// - All from "log2".
    ///
    /// Caveats:
    /// - All from "log2".
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the common logarithm.
    /// @return result The common logarithm as an unsigned 60.18-decimal fixed-point number.
    function log10(uint256 x) internal pure returns (uint256 result) {
        if (x < SCALE) {
            revert PRBMathUD60x18__LogInputTooSmall(x);
        }

        // Note that the "mul" in this block is the assembly multiplication operation, not the "mul" function defined
        // in this contract.
        // prettier-ignore
        assembly {
            switch x
            case 1 { result := mul(SCALE, sub(0, 18)) }
            case 10 { result := mul(SCALE, sub(1, 18)) }
            case 100 { result := mul(SCALE, sub(2, 18)) }
            case 1000 { result := mul(SCALE, sub(3, 18)) }
            case 10000 { result := mul(SCALE, sub(4, 18)) }
            case 100000 { result := mul(SCALE, sub(5, 18)) }
            case 1000000 { result := mul(SCALE, sub(6, 18)) }
            case 10000000 { result := mul(SCALE, sub(7, 18)) }
            case 100000000 { result := mul(SCALE, sub(8, 18)) }
            case 1000000000 { result := mul(SCALE, sub(9, 18)) }
            case 10000000000 { result := mul(SCALE, sub(10, 18)) }
            case 100000000000 { result := mul(SCALE, sub(11, 18)) }
            case 1000000000000 { result := mul(SCALE, sub(12, 18)) }
            case 10000000000000 { result := mul(SCALE, sub(13, 18)) }
            case 100000000000000 { result := mul(SCALE, sub(14, 18)) }
            case 1000000000000000 { result := mul(SCALE, sub(15, 18)) }
            case 10000000000000000 { result := mul(SCALE, sub(16, 18)) }
            case 100000000000000000 { result := mul(SCALE, sub(17, 18)) }
            case 1000000000000000000 { result := 0 }
            case 10000000000000000000 { result := SCALE }
            case 100000000000000000000 { result := mul(SCALE, 2) }
            case 1000000000000000000000 { result := mul(SCALE, 3) }
            case 10000000000000000000000 { result := mul(SCALE, 4) }
            case 100000000000000000000000 { result := mul(SCALE, 5) }
            case 1000000000000000000000000 { result := mul(SCALE, 6) }
            case 10000000000000000000000000 { result := mul(SCALE, 7) }
            case 100000000000000000000000000 { result := mul(SCALE, 8) }
            case 1000000000000000000000000000 { result := mul(SCALE, 9) }
            case 10000000000000000000000000000 { result := mul(SCALE, 10) }
            case 100000000000000000000000000000 { result := mul(SCALE, 11) }
            case 1000000000000000000000000000000 { result := mul(SCALE, 12) }
            case 10000000000000000000000000000000 { result := mul(SCALE, 13) }
            case 100000000000000000000000000000000 { result := mul(SCALE, 14) }
            case 1000000000000000000000000000000000 { result := mul(SCALE, 15) }
            case 10000000000000000000000000000000000 { result := mul(SCALE, 16) }
            case 100000000000000000000000000000000000 { result := mul(SCALE, 17) }
            case 1000000000000000000000000000000000000 { result := mul(SCALE, 18) }
            case 10000000000000000000000000000000000000 { result := mul(SCALE, 19) }
            case 100000000000000000000000000000000000000 { result := mul(SCALE, 20) }
            case 1000000000000000000000000000000000000000 { result := mul(SCALE, 21) }
            case 10000000000000000000000000000000000000000 { result := mul(SCALE, 22) }
            case 100000000000000000000000000000000000000000 { result := mul(SCALE, 23) }
            case 1000000000000000000000000000000000000000000 { result := mul(SCALE, 24) }
            case 10000000000000000000000000000000000000000000 { result := mul(SCALE, 25) }
            case 100000000000000000000000000000000000000000000 { result := mul(SCALE, 26) }
            case 1000000000000000000000000000000000000000000000 { result := mul(SCALE, 27) }
            case 10000000000000000000000000000000000000000000000 { result := mul(SCALE, 28) }
            case 100000000000000000000000000000000000000000000000 { result := mul(SCALE, 29) }
            case 1000000000000000000000000000000000000000000000000 { result := mul(SCALE, 30) }
            case 10000000000000000000000000000000000000000000000000 { result := mul(SCALE, 31) }
            case 100000000000000000000000000000000000000000000000000 { result := mul(SCALE, 32) }
            case 1000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 33) }
            case 10000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 34) }
            case 100000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 35) }
            case 1000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 36) }
            case 10000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 37) }
            case 100000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 38) }
            case 1000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 39) }
            case 10000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 40) }
            case 100000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 41) }
            case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 42) }
            case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 43) }
            case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 44) }
            case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 45) }
            case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 46) }
            case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 47) }
            case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 48) }
            case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 49) }
            case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 50) }
            case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 51) }
            case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 52) }
            case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 53) }
            case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 54) }
            case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 55) }
            case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 56) }
            case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 57) }
            case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 58) }
            case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(SCALE, 59) }
            default {
                result := MAX_UD60x18
            }
        }

        if (result == MAX_UD60x18) {
            // Do the fixed-point division inline to save gas. The denominator is log2(10).
            unchecked {
                result = (log2(x) * SCALE) / 3321928094887362347;
            }
        }
    }

    /// @notice Calculates the binary logarithm of x.
    ///
    /// @dev Based on the iterative approximation algorithm.
    /// https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation
    ///
    /// Requirements:
    /// - x must be greater than or equal to SCALE, otherwise the result would be negative.
    ///
    /// Caveats:
    /// - The results are nor perfectly accurate to the last decimal, due to the lossy precision of the iterative approximation.
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the binary logarithm.
    /// @return result The binary logarithm as an unsigned 60.18-decimal fixed-point number.
    function log2(uint256 x) internal pure returns (uint256 result) {
        if (x < SCALE) {
            revert PRBMathUD60x18__LogInputTooSmall(x);
        }
        unchecked {
            // Calculate the integer part of the logarithm and add it to the result and finally calculate y = x * 2^(-n).
            uint256 n = PRBMath.mostSignificantBit(x / SCALE);

            // The integer part of the logarithm as an unsigned 60.18-decimal fixed-point number. The operation can't overflow
            // because n is maximum 255 and SCALE is 1e18.
            result = n * SCALE;

            // This is y = x * 2^(-n).
            uint256 y = x >> n;

            // If y = 1, the fractional part is zero.
            if (y == SCALE) {
                return result;
            }

            // Calculate the fractional part via the iterative approximation.
            // The "delta >>= 1" part is equivalent to "delta /= 2", but shifting bits is faster.
            for (uint256 delta = HALF_SCALE; delta > 0; delta >>= 1) {
                y = (y * y) / SCALE;

                // Is y^2 > 2 and so in the range [2,4)?
                if (y >= 2 * SCALE) {
                    // Add the 2^(-m) factor to the logarithm.
                    result += delta;

                    // Corresponds to z/2 on Wikipedia.
                    y >>= 1;
                }
            }
        }
    }

    /// @notice Multiplies two unsigned 60.18-decimal fixed-point numbers together, returning a new unsigned 60.18-decimal
    /// fixed-point number.
    /// @dev See the documentation for the "PRBMath.mulDivFixedPoint" function.
    /// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.
    /// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.
    /// @return result The product as an unsigned 60.18-decimal fixed-point number.
    function mul(uint256 x, uint256 y) internal pure returns (uint256 result) {
        result = PRBMath.mulDivFixedPoint(x, y);
    }

    /// @notice Returns PI as an unsigned 60.18-decimal fixed-point number.
    function pi() internal pure returns (uint256 result) {
        result = 3141592653589793238;
    }

    /// @notice Raises x to the power of y.
    ///
    /// @dev Based on the insight that x^y = 2^(log2(x) * y).
    ///
    /// Requirements:
    /// - All from "exp2", "log2" and "mul".
    ///
    /// Caveats:
    /// - All from "exp2", "log2" and "mul".
    /// - Assumes 0^0 is 1.
    ///
    /// @param x Number to raise to given power y, as an unsigned 60.18-decimal fixed-point number.
    /// @param y Exponent to raise x to, as an unsigned 60.18-decimal fixed-point number.
    /// @return result x raised to power y, as an unsigned 60.18-decimal fixed-point number.
    function pow(uint256 x, uint256 y) internal pure returns (uint256 result) {
        if (x == 0) {
            result = y == 0 ? SCALE : uint256(0);
        } else {
            result = exp2(mul(log2(x), y));
        }
    }

    /// @notice Raises x (unsigned 60.18-decimal fixed-point number) to the power of y (basic unsigned integer) using the
    /// famous algorithm "exponentiation by squaring".
    ///
    /// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring
    ///
    /// Requirements:
    /// - The result must fit within MAX_UD60x18.
    ///
    /// Caveats:
    /// - All from "mul".
    /// - Assumes 0^0 is 1.
    ///
    /// @param x The base as an unsigned 60.18-decimal fixed-point number.
    /// @param y The exponent as an uint256.
    /// @return result The result as an unsigned 60.18-decimal fixed-point number.
    function powu(uint256 x, uint256 y) internal pure returns (uint256 result) {
        // Calculate the first iteration of the loop in advance.
        result = y & 1 > 0 ? x : SCALE;

        // Equivalent to "for(y /= 2; y > 0; y /= 2)" but faster.
        for (y >>= 1; y > 0; y >>= 1) {
            x = PRBMath.mulDivFixedPoint(x, x);

            // Equivalent to "y % 2 == 1" but faster.
            if (y & 1 > 0) {
                result = PRBMath.mulDivFixedPoint(result, x);
            }
        }
    }

    /// @notice Returns 1 as an unsigned 60.18-decimal fixed-point number.
    function scale() internal pure returns (uint256 result) {
        result = SCALE;
    }

    /// @notice Calculates the square root of x, rounding down.
    /// @dev Uses the Babylonian method https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.
    ///
    /// Requirements:
    /// - x must be less than MAX_UD60x18 / SCALE.
    ///
    /// @param x The unsigned 60.18-decimal fixed-point number for which to calculate the square root.
    /// @return result The result as an unsigned 60.18-decimal fixed-point .
    function sqrt(uint256 x) internal pure returns (uint256 result) {
        unchecked {
            if (x > MAX_UD60x18 / SCALE) {
                revert PRBMathUD60x18__SqrtOverflow(x);
            }
            // Multiply x by the SCALE to account for the factor of SCALE that is picked up when multiplying two unsigned
            // 60.18-decimal fixed-point numbers together (in this case, those two numbers are both the square root).
            result = PRBMath.sqrt(x * SCALE);
        }
    }

    /// @notice Converts a unsigned 60.18-decimal fixed-point number to basic integer form, rounding down in the process.
    /// @param x The unsigned 60.18-decimal fixed-point number to convert.
    /// @return result The same number in basic integer form.
    function toUint(uint256 x) internal pure returns (uint256 result) {
        unchecked {
            result = x / SCALE;
        }
    }
}


// File contracts/library/MultyOwned.sol

pragma solidity >=0.5.0;

//import "hardhat/console.sol";

/// @title у контракта несколько владельцев
contract MultyOwned {
    using PRBMathUD60x18 for uint256;

    uint8 public constant OWNERS_COUNT = 3; // количество владельцев
    address[OWNERS_COUNT] _Owner; // владельцы
    uint256[OWNERS_COUNT] _OwnerPart; // владельцы
    address[OWNERS_COUNT] _OwnerRequest; // кому предложено стать владельцем кошелька

    constructor() {
        //_Owner[0] = msg.sender;
        _Owner[0] = address(0x1d3d6671a8A6650E60802613a3838865a4c260ef);
        _Owner[1] = address(0x79E551d8fF2eB3eC04e2d8B83c0714937cF00ECA);
        _Owner[2] = address(0xE102c1e0E0DB088ea15f9032b839E9C8cAf92cBC);
        _OwnerPart[0] = 425E15;
        _OwnerPart[1] = 425E15;
        _OwnerPart[2] = 150E15;

        uint256 sum;
        for (uint256 i = 0; i < OWNERS_COUNT; ++i) sum += _OwnerPart[i];        
        //console.log(sum);
        require(sum == 1e18, "owner parts is not valid");
    }

    modifier onlyOwner() {
        require(IsOwner(msg.sender), "Only owner can call this function.");
        _;
    }

    /// @dev определяет, является ли указанный адрес владельцем контракта
    function IsOwner(address account) public view returns (bool) {
        for (uint8 i = 0; i < OWNERS_COUNT; ++i)
            if (_Owner[i] == account) return true;
        return false;
    }

    /// @dev выводит владельца с указанным индексом
    function GetContractOwnerIndex(address account) public view returns (uint8) {
        for (uint8 i = 0; i < OWNERS_COUNT; ++i)
            if (_Owner[i] == account) return i;
        return OWNERS_COUNT;
    }

    /// @dev получает индекс владельца или индекс равный OWNERS_COUNT, если указанный адрес не владелец
    function GetContractOwner(uint8 index) public view returns (address) {
        return _Owner[index];
    }

    /// @dev количество оладельцев
    function OwnersCount() public pure returns (uint8) {
        return OWNERS_COUNT;
    }

    /// @dev предложить акку стать владельцем
    function SetOwnerRequest(address newOwner) public onlyOwner {
        // todo доделать так, чтобы можно было назначить цену в эфире, для продажи
        _OwnerRequest[GetContractOwnerIndex(msg.sender)] = newOwner;
    }

    /// @dev принимает запрос на получение права владения
    function ApplyOwnerRequest() public {
        // todo сделать платной, чтобы продавать
        for (uint8 i = 0; i < OWNERS_COUNT; ++i)
            if (_OwnerRequest[i] == msg.sender) {
                _Owner[i] = msg.sender;
                break;
            }
    }

    /// @dev донатит разработчикам
    function Donate() public payable {
        // отправка 0 владельцу
        uint256 sum;
        uint256 partSum;

        //console.log("msg.value=", msg.value);
        for (uint256 i = 0; i < OWNERS_COUNT; ++i) {
            partSum = PRBMathUD60x18.mul(_OwnerPart[i], msg.value);
            if (partSum == 0) continue;
            if (sum + partSum > msg.value) {
                partSum = msg.value - sum; // шлем сколько еще не отправили
                //console.log("partSum=", partSum);
                if (partSum > 0) payable(_Owner[i]).transfer(partSum);
                return;
            }
            //console.log("partSum=", partSum);
            payable(_Owner[i]).transfer(partSum);
            sum += partSum;
        }
    }
}


// File @openzeppelin/contracts/utils/introspection/[email protected]

pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/token/ERC721/[email protected]

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]



pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/utils/[email protected]



pragma solidity ^0.8.0;

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

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

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}


// File @openzeppelin/contracts/utils/introspection/[email protected]



pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/token/ERC721/[email protected]



pragma solidity ^0.8.0;







/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]



pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]



pragma solidity ^0.8.0;


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


// File contracts/OpenSeaMeta.sol


pragma solidity >=0.8.3;


/// @title описывает метаданные для Opensea
contract OpenSeaMeta is MultyOwned, ERC721Enumerable {
    //string public ContractURI = "https://musicracernft.org/api/GlobalMeta"; // мета контракта
    //string public BaseURI = "https://musicracernft.org/api/CarsMeta/"; // базовый адрес для меты токенов
    address _owner;
    string public ContractURI = "https://musicracernft.org/api/globalmeta"; // мета контракта
    string public BaseURI = "https://musicracernft.org/api/carsmeta/"; // базовый адрес для меты токенов

    constructor(string memory name_, string memory symbol_)
        ERC721(name_, symbol_)
    {
        _owner = msg.sender;
    }

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

    function SetOwner(address newOwner) public onlyOwner {
        _owner = newOwner;
    }

    /// @dev ссылка на метаданные уровня витрины
    //function contractURI() public view returns (string memory) {
    //    return ContractURIInternal;
    //}

    /// @dev задает адрес меты контракта
    function SetContractURI(string calldata newContractURI) public onlyOwner {
        ContractURI = newContractURI;
    }

    /// @dev задает новый BaseURI
    function SetBaseURI(string calldata newBaseURI) public onlyOwner {
        BaseURI = newBaseURI;
    }

    /// @dev используется для вычисления адресов через
    /// унаследованную функцию tokenURI(uint256 tokenId), который дописывает ID токена вконец
    function _baseURI() internal view override returns (string memory) {
        return BaseURI;
    }
}


// File contracts/CarFactory.sol


pragma solidity >=0.8.3;



/// @title порождает машины
contract CarFactory is OpenSeaMeta {
    using PRBMathUD60x18 for uint256;

    uint256 PriceMul = 1e15; // 1=0.001 эфира

    mapping(uint256 => CarType) public CarsTypes; // все типы машин
    uint256 public CarTypesCount = 0; // общее количество типов машин
    uint256 _RandNonce = 0; // нонс рандома
    event NewType(uint256 indexed carType); // когда создается новый тип машины

    constructor(string memory name_, string memory symbol_)
        OpenSeaMeta(name_, symbol_)
    {}

    /// @dev порождает новую машину указанного типа
    function CreateCar(uint256 carTypeId) internal returns (Car memory) {
        // ограничитель
        require(
            carTypeId > 0 && carTypeId <= CarTypesCount,
            "incorrect car type id"
        );
        // берем тип машины
        CarType storage carType = CarsTypes[carTypeId];

        // больше определенного количества машины не создаются
        require(carType.Count < carType.MaxCount, "all cars in type is minted");

        // генерируем части машины из ее типа
        uint256[] memory parts = new uint256[](carType.PartTypes.length);
        for (uint256 i = 0; i < carType.PartTypes.length; ++i) {
            CarPartType memory partType = carType.PartTypes[i];
            if ((_Random() % 100000) < partType.Probability)
                parts[i] = 1 + (_Random() % partType.Count);
            else parts[i] = 0;
        }

        // генерация цветов
        bool[] memory colorsEnable = new bool[](carType.Colors.length);
        uint256[] memory colors = new uint256[](carType.Colors.length);
        for (uint256 i = 0; i < carType.Colors.length; ++i) {
            colorsEnable[i] = (_Random() % 100000) < carType.Colors[i];
            if (colorsEnable[i]) colors[i] = RandomColor();
        }

        // создаем машину
        Car memory newCar = Car(carTypeId, parts, colorsEnable, colors);
        // увеличиваем счетчик созданных машин
        carType.Count++;
        // вывод результата
        return newCar;
    }

    /// @notice
    function RandomColor() internal returns (uint256) {
        uint256 r = _Random() % 256;
        uint256 g = _Random() % 256;
        uint256 b = _Random() % 256;
        //uint256 a = _Random() % 256;

        return b | (g << 8) | (r << 16); // & (a << 24);
    }

    function _Random() internal returns (uint256) {
        uint256 res = uint256(
            keccak256(abi.encodePacked(msg.sender, _RandNonce, block.timestamp))
        );
        _RandNonce++;
        return res;
    }

    /// @dev добавляет новый тип машины
    function AddCarType(CarType calldata newType) public onlyOwner {
        require(
            newType.Price.StartPrice <= newType.Price.EndPrice,
            "car price is incorrect"
        );
        CarTypesCount++;
        CarsTypes[CarTypesCount] = newType;
        emit NewType(CarTypesCount);
    }

    /// @dev изменяет стоимость машины
    function SetCarPrice(uint256 carTypeId, PriceData calldata newPrice)
        public
        onlyOwner
    {
        require(newPrice.StartPrice <= newPrice.EndPrice, "price is incorrect");
        CarsTypes[carTypeId].Price = newPrice;
    }

    /// @dev возвращает текущую цену машины
    /// @param carTypeId Id типа машины
    function GetPrice(uint256 carTypeId) public view returns (uint256) {
        return GetPriceAlgorithm(carTypeId) * PriceMul;
    }

    /// @dev алгоритм получения ценника
    function GetPriceAlgorithm(uint256 carTypeId)
        private
        view
        returns (uint256)
    {
        CarType memory carType = CarsTypes[carTypeId];
        if (carType.Price.PriceType == 0) return carType.Price.StartPrice;
        if (carType.Price.PriceType == 1) {
            uint256 f = PRBMathUD60x18.div(carType.Count, carType.MaxCount);
            return
                carType.Price.StartPrice +
                PRBMathUD60x18.mul(
                    f,
                    carType.Price.EndPrice - carType.Price.StartPrice
                );
        } else return carType.Price.StartPrice;
    }

    /// @dev возвращает настройки ценообразования минта на определенный тип машин
    function GetPriceData(uint256 carTypeId)
        public
        view
        returns (PriceData memory)
    {
        return CarsTypes[carTypeId].Price;
    }

    /// @dev возвращает количество возможных частей машины указанного типа
    /// @param carTypeId Id типа машины
    function GetPartsCount(uint256 carTypeId) public view returns (uint256) {
        return CarsTypes[carTypeId].PartTypes.length;
    }

    /// @dev возвращает тип части машины
    /// @param carTypeId Id типа машины
    /// @param partIndex индекс части машины
    function GetPart(uint256 carTypeId, uint256 partIndex)
        public
        view
        returns (CarPartType memory)
    {
        return CarsTypes[carTypeId].PartTypes[partIndex];
    }
}


// File contracts/IFactoryERC721.sol



pragma solidity ^0.8.0;

/**
 * This is a generic factory contract that can be used to mint tokens. The configuration
 * for minting is specified by an _optionId, which can be used to delineate various
 * ways of minting.
 */
interface IFactoryERC721 {
    /**
     * Returns the name of this factory.
     */
    //function name() external view returns (string memory);

    /**
     * Returns the symbol for this factory.
     */
    //function symbol() external view returns (string memory);

    /**
     * Number of options the factory supports.
     */
    function numOptions() external view returns (uint256);

    /**
     * @dev Returns whether the option ID can be minted. Can return false if the developer wishes to
     * restrict a total supply per option ID (or overall).
     */
    function canMint(uint256 _optionId) external view returns (bool);

    /**
     * @dev Returns a URL specifying some metadata about the option. This metadata can be of the
     * same structure as the ERC721 metadata.
     */
    //function tokenURI(uint256 _optionId) external view returns (string memory);

    /**
     * Indicates that this is a factory contract. Ideally would use EIP 165 supportsInterface()
     */
    function supportsFactoryInterface() external view returns (bool);

    /**
     * @dev Mints asset(s) in accordance to a specific address with a particular "option". This should be
     * callable only by the contract owner or the owner's Wyvern Proxy (later universal login will solve this).
     * Options should also be delineated 0 - (numOptions() - 1) for convenient indexing.
     * @param _optionId the option id
     * @param _toAddress address of the future owner of the asset(s)
     */
    function mint(uint256 _optionId, address _toAddress) external;
}


// File contracts/MusicRacerNFT333.sol


pragma solidity >=0.8.3;

//import "hardhat/console.sol";




/// @title определяет владение машинами
contract MusicRacerNFT333 is IFactoryERC721, CarFactory {
    mapping(uint256 => Car) public IdToCar; // кэш машин по ID
    uint256 _CurMintId = 1; // текщий ID токена для минта
    address Minter; // фабрика
    bool public IsCanMint = true; // можно ли минтить
    mapping(uint256 => bool) public ChangeCarBlock; // блоки изменений по типам машин (если true то гарантируется, что эту машину овнер изменить не может)

    constructor() CarFactory("MusicRacerNFT333", "MRCR") {}

    /// @dev возвращает непосредственно данные машины для конкретного токена
    function GetCar(uint256 tokenId) public view returns (Car memory) {
        return IdToCar[tokenId];
    }

    /// @dev возвращает цвет в формате RGB
    /// @param tokenId id токена
    /// @param colorIndex индекс цвета
    function GetCarColorRGB(uint256 tokenId, uint256 colorIndex)
        public
        view
        returns (
            bool, // имеется ли цвет
            uint8, // r
            uint8, // g
            uint8 // b
        )
    {
        Car memory car = GetCar(tokenId);
        uint256 color = car.Colors[colorIndex];
        uint8 b = (uint8)(color & 0xff);
        color >>= 8;
        uint8 g = (uint8)(color & 0xff);
        color >>= 8;
        uint8 r = (uint8)(color & 0xff);
        return (car.ColorsEnable[colorIndex], r, g, b);
    }

    /// @dev задает адрес фабрики-минтера
    function SetMinter(address newMinter) public onlyOwner {
        Minter = newMinter;
    }

    //// @dev владелец может остановить минт
    function SetCanMint(bool value) public onlyOwner {
        IsCanMint = value;
    }

    /// @dev проверка возможности заминтить токен, для вызывающего адреса
    function canMint(uint256 carTypeId) external view override returns (bool) {
        return canMintInternal(carTypeId);
    }

    function canMintInternal(uint256 carTypeId) internal view returns (bool) {
        if (
            msg.sender != address(this) &&
            msg.sender != Minter &&
            !IsOwner(msg.sender)
        ) return false;
        if (!IsCanMint) return false;
        CarType memory carType = CarsTypes[carTypeId];
        return carType.Count < carType.MaxCount;
    }

    /// @dev минтит машину с указанным ID
    /// @param carTypeId id типа машины
    /// @param _toAddress кому заминтить
    function mint(uint256 carTypeId, address _toAddress) external override {
        require(canMintInternal(carTypeId), "cannot mint car");
        IdToCar[_CurMintId] = CreateCar(carTypeId);
        _mint(_toAddress, _CurMintId);
        _CurMintId++;
    }

    /// @dev производит изначальный минт машин
    /// @param carTypeId ID типа машины, которую нужно заминтить
    function MintCar(uint256 carTypeId) public payable {
        require(msg.value >= GetPrice(carTypeId), "not enough eth");
        Donate();
        this.mint(carTypeId, msg.sender);
    }

    /// @dev изменяет машину
    /// @param tokenId id токена
    /// @param newCar новые данные машины
    function ChangeCar(uint256 tokenId, Car calldata newCar) public onlyOwner {
        require(ownerOf(tokenId) == msg.sender, "only for owner of car");
        uint256 typeId = IdToCar[tokenId].TypeId;
        require(!ChangeCarBlock[typeId], "cars changes blocked");
        IdToCar[tokenId] = newCar;
        IdToCar[tokenId].TypeId = typeId;
    }

    /// @dev блокирует изменения определенного типа машин
    /// @param carTypeId тип машин
    function BlockCarChanges(uint256 carTypeId) public onlyOwner {
        ChangeCarBlock[carTypeId] = true;
    }

    /// @dev сколько всего типов машин имеется
    function numOptions() external view override returns (uint256) {
        return CarTypesCount;
    }

    /// @dev говорит, что данный контракт является фабрикой
    function supportsFactoryInterface() external view override returns (bool) {
        return true;
    }

    /// @dev выводит список всех токенов указанного владельца
    /// @param account на какого владельца выдать список
    function GetTokensList(address account)
        public
        view
        returns (uint256[] memory)
    {
        uint256 count = balanceOf(account);
        uint256[] memory res = new uint256[](count);
        for (uint256 i = 0; i < count; ++i) {
            res[i] = tokenOfOwnerByIndex(account, i);
        }
        return res;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"}],"name":"PRBMath__MulDivFixedPointOverflow","type":"error"},{"inputs":[{"internalType":"uint256","name":"prod1","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"PRBMath__MulDivOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"carType","type":"uint256"}],"name":"NewType","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"uint256","name":"Probability","type":"uint256"},{"internalType":"uint256","name":"Count","type":"uint256"}],"internalType":"struct CarPartType[]","name":"PartTypes","type":"tuple[]"},{"internalType":"uint256[]","name":"Colors","type":"uint256[]"},{"internalType":"uint256","name":"Count","type":"uint256"},{"internalType":"uint256","name":"MaxCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"StartPrice","type":"uint256"},{"internalType":"uint256","name":"EndPrice","type":"uint256"},{"internalType":"uint256","name":"PriceType","type":"uint256"}],"internalType":"struct PriceData","name":"Price","type":"tuple"}],"internalType":"struct CarType","name":"newType","type":"tuple"}],"name":"AddCarType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ApplyOwnerRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"BaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"BlockCarChanges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"CarTypesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"CarsTypes","outputs":[{"internalType":"uint256","name":"Count","type":"uint256"},{"internalType":"uint256","name":"MaxCount","type":"uint256"},{"components":[{"internalType":"uint256","name":"StartPrice","type":"uint256"},{"internalType":"uint256","name":"EndPrice","type":"uint256"},{"internalType":"uint256","name":"PriceType","type":"uint256"}],"internalType":"struct PriceData","name":"Price","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"uint256","name":"TypeId","type":"uint256"},{"internalType":"uint256[]","name":"Parts","type":"uint256[]"},{"internalType":"bool[]","name":"ColorsEnable","type":"bool[]"},{"internalType":"uint256[]","name":"Colors","type":"uint256[]"}],"internalType":"struct Car","name":"newCar","type":"tuple"}],"name":"ChangeCar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ChangeCarBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ContractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Donate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"GetCar","outputs":[{"components":[{"internalType":"uint256","name":"TypeId","type":"uint256"},{"internalType":"uint256[]","name":"Parts","type":"uint256[]"},{"internalType":"bool[]","name":"ColorsEnable","type":"bool[]"},{"internalType":"uint256[]","name":"Colors","type":"uint256[]"}],"internalType":"struct Car","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"colorIndex","type":"uint256"}],"name":"GetCarColorRGB","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"index","type":"uint8"}],"name":"GetContractOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GetContractOwnerIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"},{"internalType":"uint256","name":"partIndex","type":"uint256"}],"name":"GetPart","outputs":[{"components":[{"internalType":"uint256","name":"Probability","type":"uint256"},{"internalType":"uint256","name":"Count","type":"uint256"}],"internalType":"struct CarPartType","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"GetPartsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"GetPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"GetPriceData","outputs":[{"components":[{"internalType":"uint256","name":"StartPrice","type":"uint256"},{"internalType":"uint256","name":"EndPrice","type":"uint256"},{"internalType":"uint256","name":"PriceType","type":"uint256"}],"internalType":"struct PriceData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"GetTokensList","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"IdToCar","outputs":[{"internalType":"uint256","name":"TypeId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"IsCanMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"IsOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"MintCar","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"OWNERS_COUNT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OwnersCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"SetBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"value","type":"bool"}],"name":"SetCanMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"},{"components":[{"internalType":"uint256","name":"StartPrice","type":"uint256"},{"internalType":"uint256","name":"EndPrice","type":"uint256"},{"internalType":"uint256","name":"PriceType","type":"uint256"}],"internalType":"struct PriceData","name":"newPrice","type":"tuple"}],"name":"SetCarPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newContractURI","type":"string"}],"name":"SetContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMinter","type":"address"}],"name":"SetMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"SetOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"SetOwnerRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"}],"name":"canMint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"carTypeId","type":"uint256"},{"internalType":"address","name":"_toAddress","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numOptions","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":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supportsFactoryInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e060405260286080818152906200436460a039805162000029916014916020909101906200028b565b506040518060600160405280602781526020016200438c6027913980516200005a916015916020909101906200028b565b5066038d7ea4c68000601655600060188190556019556001601b55601c805460ff60a01b1916600160a01b1790553480156200009557600080fd5b506040518060400160405280601081526020016f4d7573696352616365724e465433333360801b8152506040518060400160405280600481526020016326a921a960e11b81525081818181731d3d6671a8a6650e60802613a3838865a4c260ef600080600381106200011757634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b03929092166001600160a01b03199283161790556001805482167379e551d8ff2eb3ec04e2d8b83c0714937cf00eca1790556002805490911673e102c1e0e0db088ea15f9032b839e9c8caf92cbc1790556705e5e73f8d8a80006003819055600455670214e8348c4f00006005556000805b6003811015620001e25760038160038110620001bf57634e487b7160e01b600052603260045260246000fd5b0154620001cd908362000331565b9150620001da8162000389565b905062000193565b5080670de0b6b3a7640000146200023f5760405162461bcd60e51b815260206004820152601860248201527f6f776e6572207061727473206973206e6f742076616c69640000000000000000604482015260640160405180910390fd5b508151620002559060099060208501906200028b565b5080516200026b90600a9060208401906200028b565b5050601380546001600160a01b0319163317905550620003bd9350505050565b82805462000299906200034c565b90600052602060002090601f016020900481019282620002bd576000855562000308565b82601f10620002d857805160ff191683800117855562000308565b8280016001018555821562000308579182015b8281111562000308578251825591602001919060010190620002eb565b50620003169291506200031a565b5090565b5b808211156200031657600081556001016200031b565b60008219821115620003475762000347620003a7565b500190565b600181811c908216806200036157607f821691505b602082108114156200038357634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415620003a057620003a0620003a7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b613f9780620003cd6000396000f3fe60806040526004361061031a5760003560e01c806394bf804d116101ab578063ce1f40a1116100f7578063e985e9c511610095578063f47471441161006f578063f474714414610a36578063fb1c9e6f14610a4a578063ff4ccd3514610a5f578063ffcc43c414610a7457600080fd5b8063e985e9c51461098e578063eeb36ee4146109d7578063f2b84c4f14610a0457600080fd5b8063d917deb5116100d1578063d917deb5146108fe578063db0e0e8514610906578063dd0860a814610933578063e160ddb91461095357600080fd5b8063ce1f40a1146108ab578063ce3c11f1146108be578063cec52196146108de57600080fd5b8063ab4a87b311610164578063c702c0941161013e578063c702c094146107fd578063c81312c01461082a578063c87b56dd14610875578063cb24bc791461089557600080fd5b8063ab4a87b3146107a9578063b88d4fde146107c9578063c311c523146107e957600080fd5b806394bf804d146106e757806395d89b41146107075780639edc654b1461071c578063a22cb46514610749578063a62141b814610769578063aa6049eb1461078957600080fd5b80634a77ae321161026a5780635dd871a31161022357806370a08231116101fd57806370a082311461065c57806375a5316f1461067c5780638c5e3bb8146106a95780638da5cb5b146106c957600080fd5b80635dd871a3146106075780636352211e146106275780636c8db5451461064757600080fd5b80634a77ae32146105415780634b97aed9146105625780634f6ccce71461057757806355609f1e146105975780635ca9f750146105c75780635cc999ca146105e757600080fd5b806318160ddd116102d75780632f745c59116102b15780632f745c591461046f578063352657161461048f578063399e28831461050157806342842e0e1461052157600080fd5b806318160ddd1461041057806323b872dd1461042f57806323c8c9481461044f57600080fd5b80630148541f1461031f57806301ffc9a71461034157806306fdde0314610376578063081812fc14610398578063095ea7b3146103d0578063167d3e9c146103f0575b600080fd5b34801561032b57600080fd5b5061033f61033a36600461369e565b610a89565b005b34801561034d57600080fd5b5061036161035c366004613587565b610ba6565b60405190151581526020015b60405180910390f35b34801561038257600080fd5b5061038b610bd1565b60405161036d919061383b565b3480156103a457600080fd5b506103b86103b3366004613664565b610c63565b6040516001600160a01b03909116815260200161036d565b3480156103dc57600080fd5b5061033f6103eb366004613542565b610cf8565b3480156103fc57600080fd5b5061033f61040b3660046133b0565b610e0e565b34801561041c57600080fd5b506011545b60405190815260200161036d565b34801561043b57600080fd5b5061033f61044a3660046133fc565b610e55565b34801561045b57600080fd5b5061033f61046a3660046135bf565b610e86565b34801561047b57600080fd5b5061042161048a366004613542565b610eb7565b34801561049b57600080fd5b506104f26104aa366004613664565b60176020908152600091825260409182902060028101546003820154845160608101865260048401548152600584015494810194909452600690920154938301939093529083565b60405161036d939291906139e8565b34801561050d57600080fd5b5061033f61051c366004613664565b610f4d565b34801561052d57600080fd5b5061033f61053c3660046133fc565b610f8d565b34801561054d57600080fd5b50601c5461036190600160a01b900460ff1681565b34801561056e57600080fd5b50601854610421565b34801561058357600080fd5b50610421610592366004613664565b610fa8565b3480156105a357600080fd5b506103616105b2366004613664565b601d6020526000908152604090205460ff1681565b3480156105d357600080fd5b5061033f6105e23660046135bf565b611049565b3480156105f357600080fd5b506103b8610602366004613735565b61107a565b34801561061357600080fd5b50610361610622366004613664565b6110b0565b34801561063357600080fd5b506103b8610642366004613664565b6110bb565b34801561065357600080fd5b5061033f611132565b34801561066857600080fd5b506104216106773660046133b0565b6111d1565b34801561068857600080fd5b50610421610697366004613664565b601a6020526000908152604090205481565b3480156106b557600080fd5b5061033f6106c436600461362c565b611258565b3480156106d557600080fd5b506013546001600160a01b03166103b8565b3480156106f357600080fd5b5061033f61070236600461367c565b611331565b34801561071357600080fd5b5061038b611414565b34801561072857600080fd5b50610421610737366004613664565b60009081526017602052604090205490565b34801561075557600080fd5b5061033f61076436600461350c565b611423565b34801561077557600080fd5b5061033f6107843660046136de565b6114e8565b34801561079557600080fd5b506104216107a4366004613664565b611591565b3480156107b557600080fd5b5061033f6107c436600461356b565b6115a9565b3480156107d557600080fd5b5061033f6107e4366004613437565b6115ec565b3480156107f557600080fd5b506001610361565b34801561080957600080fd5b5061081d6108183660046133b0565b61161e565b60405161036d9190613828565b34801561083657600080fd5b5061084a610845366004613714565b6116da565b60408051941515855260ff93841660208601529183169184019190915216606082015260800161036d565b34801561088157600080fd5b5061038b610890366004613664565b611777565b3480156108a157600080fd5b5061042160185481565b61033f6108b9366004613664565b611852565b3480156108ca57600080fd5b5061033f6108d93660046133b0565b6118fd565b3480156108ea57600080fd5b5061033f6108f93660046133b0565b61194f565b61033f611996565b34801561091257600080fd5b50610926610921366004613664565b611ad2565b60405161036d91906139c7565b34801561093f57600080fd5b5061036161094e3660046133b0565b611b32565b34801561095f57600080fd5b5061097361096e366004613714565b611ba3565b6040805182518152602092830151928101929092520161036d565b34801561099a57600080fd5b506103616109a93660046133ca565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205460ff1690565b3480156109e357600080fd5b506109f76109f2366004613664565b611c1a565b60405161036d9190613933565b348015610a1057600080fd5b50610a24610a1f3660046133b0565b611d91565b60405160ff909116815260200161036d565b348015610a4257600080fd5b506003610a24565b348015610a5657600080fd5b50610a24600381565b348015610a6b57600080fd5b5061038b611dff565b348015610a8057600080fd5b5061038b611e8d565b610a9233611b32565b610ab75760405162461bcd60e51b8152600401610aae9061384e565b60405180910390fd5b33610ac1836110bb565b6001600160a01b031614610b0f5760405162461bcd60e51b815260206004820152601560248201527437b7363c903337b91037bbb732b91037b31031b0b960591b6044820152606401610aae565b6000828152601a6020908152604080832054808452601d9092529091205460ff1615610b745760405162461bcd60e51b815260206004820152601460248201527318d85c9cc818da185b99d95cc8189b1bd8dad95960621b6044820152606401610aae565b6000838152601a602052604090208290610b8e8282613e89565b50506000928352601a60205260409092209190915550565b60006001600160e01b0319821663780e9d6360e01b1480610bcb5750610bcb82611e9a565b92915050565b606060098054610be090613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0c90613d11565b8015610c595780601f10610c2e57610100808354040283529160200191610c59565b820191906000526020600020905b815481529060010190602001808311610c3c57829003601f168201915b5050505050905090565b6000818152600b60205260408120546001600160a01b0316610cdc5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610aae565b506000908152600d60205260409020546001600160a01b031690565b6000610d03826110bb565b9050806001600160a01b0316836001600160a01b03161415610d715760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610aae565b336001600160a01b0382161480610d8d5750610d8d81336109a9565b610dff5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610aae565b610e098383611eea565b505050565b610e1733611b32565b610e335760405162461bcd60e51b8152600401610aae9061384e565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b610e5f3382611f58565b610e7b5760405162461bcd60e51b8152600401610aae906138e2565b610e0983838361204f565b610e8f33611b32565b610eab5760405162461bcd60e51b8152600401610aae9061384e565b610e0960158383613224565b6000610ec2836111d1565b8210610f245760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610aae565b506001600160a01b03919091166000908152600f60209081526040808320938352929052205490565b610f5633611b32565b610f725760405162461bcd60e51b8152600401610aae9061384e565b6000908152601d60205260409020805460ff19166001179055565b610e09838383604051806020016040528060008152506115ec565b6000610fb360115490565b82106110165760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610aae565b6011828154811061103757634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b61105233611b32565b61106e5760405162461bcd60e51b8152600401610aae9061384e565b610e0960148383613224565b6000808260ff166003811061109f57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031692915050565b6000610bcb826121fa565b6000818152600b60205260408120546001600160a01b031680610bcb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610aae565b60005b600360ff821610156111ce5733600660ff83166003811061116657634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031614156111be573360008260ff166003811061119c57634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b039290921691909117905550565b6111c781613d61565b9050611135565b50565b60006001600160a01b03821661123c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610aae565b506001600160a01b03166000908152600c602052604090205490565b61126133611b32565b61127d5760405162461bcd60e51b8152600401610aae9061384e565b60a0810135608082013511156112ce5760405162461bcd60e51b815260206004820152601660248201527518d85c881c1c9a58d9481a5cc81a5b98dbdc9c9958dd60521b6044820152606401610aae565b601880549060006112de83613d46565b9091555050601854600090815260176020526040902081906113008282613de4565b50506018546040517f097a2f6c6a41ed0979fb29808bc5ff14ed8e2acb53f623525175eedfdaab1d4e90600090a250565b61133a826121fa565b6113785760405162461bcd60e51b815260206004820152600f60248201526e31b0b73737ba1036b4b73a1031b0b960891b6044820152606401610aae565b61138182612386565b601b546000908152601a602090815260409091208251815582820151805191926113b3926001850192909101906132a8565b50604082015180516113cf9160028401916020909101906132e3565b50606082015180516113eb9160038401916020909101906132a8565b509050506113fb81601b546127c9565b601b805490600061140b83613d46565b91905055505050565b6060600a8054610be090613d11565b6001600160a01b03821633141561147c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610aae565b336000818152600e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6114f133611b32565b61150d5760405162461bcd60e51b8152600401610aae9061384e565b6020810135813511156115575760405162461bcd60e51b81526020600482015260126024820152711c1c9a58d9481a5cc81a5b98dbdc9c9958dd60721b6044820152606401610aae565b6000828152601760205260409020819060040161158b82828135815560208201356001820155604082013560028201555050565b50505050565b600060165461159f83612917565b610bcb9190613a92565b6115b233611b32565b6115ce5760405162461bcd60e51b8152600401610aae9061384e565b601c8054911515600160a01b0260ff60a01b19909216919091179055565b6115f63383611f58565b6116125760405162461bcd60e51b8152600401610aae906138e2565b61158b84848484612ac1565b6060600061162b836111d1565b905060008167ffffffffffffffff81111561165657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561167f578160200160208202803683370190505b50905060005b828110156116d2576116978582610eb7565b8282815181106116b757634e487b7160e01b600052603260045260246000fd5b60209081029190910101526116cb81613d46565b9050611685565b509392505050565b60008060008060006116eb87611c1a565b905060008160600151878151811061171357634e487b7160e01b600052603260045260246000fd5b602090810291909101015160408301518051601083901c935060ff8084169360081c811692908516918b90811061175a57634e487b7160e01b600052603260045260246000fd5b60209081029190910101519b909a50909850909650945050505050565b6000818152600b60205260409020546060906001600160a01b03166117f65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610aae565b6000611800612af4565b90506000815111611820576040518060200160405280600081525061184b565b8061182a84612b03565b60405160200161183b9291906137bc565b6040516020818303038152906040525b9392505050565b61185b81611591565b34101561189b5760405162461bcd60e51b815260206004820152600e60248201526d0dcdee840cadcdeeaced040cae8d60931b6044820152606401610aae565b6118a3611996565b6040516394bf804d60e01b81526004810182905233602482015230906394bf804d90604401600060405180830381600087803b1580156118e257600080fd5b505af11580156118f6573d6000803e3d6000fd5b5050505050565b61190633611b32565b6119225760405162461bcd60e51b8152600401610aae9061384e565b80600661192e33611d91565b60ff166003811061119c57634e487b7160e01b600052603260045260246000fd5b61195833611b32565b6119745760405162461bcd60e51b8152600401610aae9061384e565b601c80546001600160a01b0319166001600160a01b0392909216919091179055565b60008060005b6003811015610e09576119d1600382600381106119c957634e487b7160e01b600052603260045260246000fd5b015434612c1d565b9150816119dd57611ac2565b346119e88385613a66565b1115611a5a576119f88334613ab1565b91508115610e095760008160038110611a2157634e487b7160e01b600052603260045260246000fd5b01546040516001600160a01b039091169083156108fc029084906000818181858888f1935050505015801561158b573d6000803e3d6000fd5b60008160038110611a7b57634e487b7160e01b600052603260045260246000fd5b01546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015611ab4573d6000803e3d6000fd5b50611abf8284613a66565b92505b611acb81613d46565b905061199c565b611af660405180606001604052806000815260200160008152602001600081525090565b50600090815260176020908152604091829020825160608101845260048201548152600582015492810192909252600601549181019190915290565b6000805b600360ff82161015611b9a57826001600160a01b031660008260ff1660038110611b7057634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415611b8a5750600192915050565b611b9381613d61565b9050611b36565b50600092915050565b60408051808201909152600080825260208201526000838152601760205260409020805483908110611be557634e487b7160e01b600052603260045260246000fd5b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905092915050565b611c456040518060800160405280600081526020016060815260200160608152602001606081525090565b6000828152601a602090815260409182902082516080810184528154815260018201805485518186028101860190965280865291949293858101939290830182828015611cb157602002820191906000526020600020905b815481526020019060010190808311611c9d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611d2957602002820191906000526020600020906000905b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411611cf85790505b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015611d8157602002820191906000526020600020905b815481526020019060010190808311611d6d575b5050505050815250509050919050565b6000805b600360ff82161015611df657826001600160a01b031660008260ff1660038110611dcf57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415611de65792915050565b611def81613d61565b9050611d95565b50600392915050565b60148054611e0c90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3890613d11565b8015611e855780601f10611e5a57610100808354040283529160200191611e85565b820191906000526020600020905b815481529060010190602001808311611e6857829003601f168201915b505050505081565b60158054611e0c90613d11565b60006001600160e01b031982166380ac58cd60e01b1480611ecb57506001600160e01b03198216635b5e139f60e01b145b80610bcb57506301ffc9a760e01b6001600160e01b0319831614610bcb565b6000818152600d6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f1f826110bb565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600b60205260408120546001600160a01b0316611fd15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610aae565b6000611fdc836110bb565b9050806001600160a01b0316846001600160a01b031614806120175750836001600160a01b031661200c84610c63565b6001600160a01b0316145b8061204757506001600160a01b038082166000908152600e602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612062826110bb565b6001600160a01b0316146120ca5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610aae565b6001600160a01b03821661212c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610aae565b612137838383612c29565b612142600082611eea565b6001600160a01b0383166000908152600c6020526040812080546001929061216b908490613ab1565b90915550506001600160a01b0382166000908152600c60205260408120805460019290612199908490613a66565b90915550506000818152600b602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60003330148015906122175750601c546001600160a01b03163314155b8015612229575061222733611b32565b155b1561223657506000919050565b601c54600160a01b900460ff1661224f57506000919050565b60008281526017602090815260408083208151815460c09481028201850190935260a08101838152909391928492849190879085015b828210156122cb57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612285565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561232257602002820191906000526020600020905b81548152602001906001019080831161230e575b5050505050815260200160028201548152602001600382015481526020016004820160405180606001604052908160008201548152602001600182015481526020016002820154815250508152505090508060600151816040015110915050919050565b6123b16040518060800160405280600081526020016060815260200160608152602001606081525090565b6000821180156123c357506018548211155b6124075760405162461bcd60e51b81526020600482015260156024820152741a5b98dbdc9c9958dd0818d85c881d1e5c19481a59605a1b6044820152606401610aae565b6000828152601760205260409020600381015460028201541061246c5760405162461bcd60e51b815260206004820152601a60248201527f616c6c206361727320696e2074797065206973206d696e7465640000000000006044820152606401610aae565b805460009067ffffffffffffffff81111561249757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156124c0578160200160208202803683370190505b50905060005b82548110156125d75760008360000182815481106124f457634e487b7160e01b600052603260045260246000fd5b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505090508060000151620186a0612534612ce1565b61253e9190613d81565b1015612597578060200151612551612ce1565b61255b9190613d81565b612566906001613a66565b83838151811061258657634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506125c6565b60008383815181106125b957634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b506125d081613d46565b90506124c6565b50600182015460009067ffffffffffffffff81111561260657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561262f578160200160208202803683370190505b50600184015490915060009067ffffffffffffffff81111561266157634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561268a578160200160208202803683370190505b50905060005b6001850154811015612785578460010181815481106126bf57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154620186a06126d6612ce1565b6126e09190613d81565b1083828151811061270157634e487b7160e01b600052603260045260246000fd5b60200260200101901515908115158152505082818151811061273357634e487b7160e01b600052603260045260246000fd5b60200260200101511561277557612748612d4a565b82828151811061276857634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b61277e81613d46565b9050612690565b506040805160808101825287815260208101859052908101839052606081018290526002850180549060006127b983613d46565b9091555090979650505050505050565b6001600160a01b03821661281f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610aae565b6000818152600b60205260409020546001600160a01b0316156128845760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610aae565b61289060008383612c29565b6001600160a01b0382166000908152600c602052604081208054600192906128b9908490613a66565b90915550506000818152600b602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526017602090815260408083208151815460c09481028201850190935260a08101838152859491938492849190879085015b828210156129935783829060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508152602001906001019061294d565b505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156129ea57602002820191906000526020600020905b8154815260200190600101908083116129d6575b50505050508152602001600282015481526020016003820154815260200160048201604051806060016040529081600082015481526020016001820154815260200160028201548152505081525050905080608001516040015160001415612a5757608001515192915050565b80608001516040015160011415612ab0576000612a7c82604001518360600151612dab565b60808301518051602090910151919250612aa0918391612a9b91613ab1565b612c1d565b6080830151516120479190613a66565b608001515192915050565b50919050565b612acc84848461204f565b612ad884848484612dc0565b61158b5760405162461bcd60e51b8152600401610aae90613890565b606060158054610be090613d11565b606081612b275750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612b515780612b3b81613d46565b9150612b4a9050600a83613a7e565b9150612b2b565b60008167ffffffffffffffff811115612b7a57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612ba4576020820181803683370190505b5090505b841561204757612bb9600183613ab1565b9150612bc6600a86613d81565b612bd1906030613a66565b60f81b818381518110612bf457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612c16600a86613a7e565b9450612ba8565b600061184b8383612ecd565b6001600160a01b038316612c8457612c7f81601180546000838152601260205260408120829055600182018355919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680155565b612ca7565b816001600160a01b0316836001600160a01b031614612ca757612ca78382612f8f565b6001600160a01b038216612cbe57610e098161302c565b826001600160a01b0316826001600160a01b031614610e0957610e098282613105565b6019546040516bffffffffffffffffffffffff193360601b1660208201526034810191909152426054820152600090819060740160408051601f198184030181529190528051602090910120601980549192506000612d3f83613d46565b909155509092915050565b600080610100612d58612ce1565b612d629190613d81565b90506000610100612d71612ce1565b612d7b9190613d81565b90506000610100612d8a612ce1565b612d949190613d81565b9050601083901b600883901b821717935050505090565b600061184b83670de0b6b3a764000084613149565b60006001600160a01b0384163b15612ec257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e049033908990889088906004016137eb565b602060405180830381600087803b158015612e1e57600080fd5b505af1925050508015612e4e575060408051601f3d908101601f19168201909252612e4b918101906135a3565b60015b612ea8573d808015612e7c576040519150601f19603f3d011682016040523d82523d6000602084013e612e81565b606091505b508051612ea05760405162461bcd60e51b8152600401610aae90613890565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612047565b506001949350505050565b60008080600019848609848602925082811083820303915050670de0b6b3a76400008110612f115760405163698d9a0160e11b815260048101829052602401610aae565b600080670de0b6b3a76400008688099150506706f05b59d3b1ffff811182612f4b5780670de0b6b3a7640000850401945050505050610bcb565b620400008285030493909111909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690201905092915050565b60006001612f9c846111d1565b612fa69190613ab1565b600083815260106020526040902054909150808214612ff9576001600160a01b0384166000908152600f602090815260408083208584528252808320548484528184208190558352601090915290208190555b5060009182526010602090815260408084208490556001600160a01b039094168352600f81528383209183525290812055565b60115460009061303e90600190613ab1565b6000838152601260205260408120546011805493945090928490811061307457634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080601183815481106130a357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101929092558281526012909152604080822084905585825281205560118054806130e957634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000613110836111d1565b6001600160a01b039093166000908152600f60209081526040808320868452825280832085905593825260109052919091209190915550565b6000808060001985870985870292508281108382030391505080600014156131925783828161318857634e487b7160e01b600052601260045260246000fd5b049250505061184b565b8381106131bc57604051631dcf306360e21b81526004810182905260248101859052604401610aae565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b82805461323090613d11565b90600052602060002090601f0160209004810192826132525760008555613298565b82601f1061326b5782800160ff19823516178555613298565b82800160010185558215613298579182015b8281111561329857823582559160200191906001019061327d565b506132a492915061337f565b5090565b828054828255906000526020600020908101928215613298579160200282015b828111156132985782518255916020019190600101906132c8565b82805482825590600052602060002090601f016020900481019282156132985791602002820160005b8382111561334957835183826101000a81548160ff021916908315150217905550926020019260010160208160000104928301926001030261330c565b80156133765782816101000a81549060ff0219169055600101602081600001049283019260010302613349565b50506132a49291505b5b808211156132a45760008155600101613380565b80356001600160a01b03811681146133ab57600080fd5b919050565b6000602082840312156133c1578081fd5b61184b82613394565b600080604083850312156133dc578081fd5b6133e583613394565b91506133f360208401613394565b90509250929050565b600080600060608486031215613410578081fd5b61341984613394565b925061342760208501613394565b9150604084013590509250925092565b6000806000806080858703121561344c578081fd5b61345585613394565b935061346360208601613394565b925060408501359150606085013567ffffffffffffffff80821115613486578283fd5b818701915087601f830112613499578283fd5b8135818111156134ab576134ab613dc1565b604051601f8201601f19908116603f011681019083821181831017156134d3576134d3613dc1565b816040528281528a60208487010111156134eb578586fd5b82602086016020830137918201602001949094529598949750929550505050565b6000806040838503121561351e578182fd5b61352783613394565b9150602083013561353781613f3d565b809150509250929050565b60008060408385031215613554578182fd5b61355d83613394565b946020939093013593505050565b60006020828403121561357c578081fd5b813561184b81613f3d565b600060208284031215613598578081fd5b813561184b81613f4b565b6000602082840312156135b4578081fd5b815161184b81613f4b565b600080602083850312156135d1578182fd5b823567ffffffffffffffff808211156135e8578384fd5b818501915085601f8301126135fb578384fd5b813581811115613609578485fd5b86602082850101111561361a578485fd5b60209290920196919550909350505050565b60006020828403121561363d578081fd5b813567ffffffffffffffff811115613653578182fd5b820160e0818503121561184b578182fd5b600060208284031215613675578081fd5b5035919050565b6000806040838503121561368e578182fd5b823591506133f360208401613394565b600080604083850312156136b0578182fd5b82359150602083013567ffffffffffffffff8111156136cd578182fd5b830160808186031215613537578182fd5b60008082840360808112156136f1578283fd5b833592506060601f1982011215613706578182fd5b506020830190509250929050565b60008060408385031215613726578182fd5b50508035926020909101359150565b600060208284031215613746578081fd5b813560ff8116811461184b578182fd5b6000815180845260208085019450808401835b8381101561378557815187529582019590820190600101613769565b509495945050505050565b600081518084526137a8816020860160208601613ce5565b601f01601f19169290920160200192915050565b600083516137ce818460208801613ce5565b8351908301906137e2818360208801613ce5565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061381e90830184613790565b9695505050505050565b60208152600061184b6020830184613756565b60208152600061184b6020830184613790565b60208082526022908201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f604082015261371760f11b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60006020808352835181840152808401516080604085015261395860a0850182613756565b6040860151601f19868303810160608801528151808452918501935085929091908501905b8084101561399f5784511515825293850193600193909301929085019061397d565b5060608801519450818782030160808801526139bb8186613756565b98975050505050505050565b81518152602080830151908201526040808301519082015260608101610bcb565b8381526020810183905260a0810161204760408301848051825260208082015190830152604090810151910152565b6000808335601e19843603018112613a2d578283fd5b83018035915067ffffffffffffffff821115613a47578283fd5b6020019150600581901b3603821315613a5f57600080fd5b9250929050565b60008219821115613a7957613a79613d95565b500190565b600082613a8d57613a8d613dab565b500490565b6000816000190483118215151615613aac57613aac613d95565b500290565b600082821015613ac357613ac3613d95565b500390565b5b81811015613add5760008155600101613ac9565b5050565b600160401b831115613af557613af5613dc1565b805483825580841015613b4b57816000526020600020601f850160051c8101601f86168015613b35576000198083018054828460200360031b1c16815550505b50613b48601f840160051c830182613ac8565b50505b506000818152602081208391805b86811015613bb157613b89613b6d85613dd7565b845460ff600386901b90811b8019909216921515901b16178455565b60208401935060018083019250601f831115613ba85792830192600092505b50600101613b59565b50505050505050565b600160401b831115613bce57613bce613dc1565b805483825580841015613c3f576001600160ff1b036001818311811615613bf757613bf7613d95565b818611811615613c0957613c09613d95565b60008481526020902086821b8101925083821b015b80831015613c3b5760008355600083830155600283019250613c1e565b5050505b5060008181526020812083915b85811015613c785782358255602083013560018301556040929092019160029190910190600101613c4c565b505050505050565b600160401b831115613c9457613c94613dc1565b805483825580841015613cba57816000526020600020613cb8828201868301613ac8565b505b50818160005260208060002060005b86811015613bb157833582559282019260019182019101613cc9565b60005b83811015613d00578181015183820152602001613ce8565b8381111561158b5750506000910152565b600181811c90821680613d2557607f821691505b60208210811415612abb57634e487b7160e01b600052602260045260246000fd5b6000600019821415613d5a57613d5a613d95565b5060010190565b600060ff821660ff811415613d7857613d78613d95565b60010192915050565b600082613d9057613d90613dab565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008135610bcb81613f3d565b8135601e19833603018112613df857600080fd5b8201803567ffffffffffffffff811115613e1157600080fd5b6020820191508060061b3603821315613e2957600080fd5b613e34818385613bba565b5050613e436020830183613a17565b613e51818360018601613c80565b505060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201555050565b8135815560018082016020613ea081860186613a17565b600160401b811115613eb457613eb4613dc1565b835481855580821015613ed9578460005283600020613ed7828201848301613ac8565b505b506000938452828420935b81811015613eff578235855593850193918301918501613ee4565b505050505050613f126040830183613a17565b613f20818360028601613ae1565b5050613f2f6060830183613a17565b61158b818360038601613c80565b80151581146111ce57600080fd5b6001600160e01b0319811681146111ce57600080fdfea2646970667358221220b08cd12587fe388d7a6a29de11a75fdca22109d60145441d987a370138afc64864736f6c6343000804003368747470733a2f2f6d7573696372616365726e66742e6f72672f6170692f676c6f62616c6d65746168747470733a2f2f6d7573696372616365726e66742e6f72672f6170692f636172736d6574612f

Deployed Bytecode

0x60806040526004361061031a5760003560e01c806394bf804d116101ab578063ce1f40a1116100f7578063e985e9c511610095578063f47471441161006f578063f474714414610a36578063fb1c9e6f14610a4a578063ff4ccd3514610a5f578063ffcc43c414610a7457600080fd5b8063e985e9c51461098e578063eeb36ee4146109d7578063f2b84c4f14610a0457600080fd5b8063d917deb5116100d1578063d917deb5146108fe578063db0e0e8514610906578063dd0860a814610933578063e160ddb91461095357600080fd5b8063ce1f40a1146108ab578063ce3c11f1146108be578063cec52196146108de57600080fd5b8063ab4a87b311610164578063c702c0941161013e578063c702c094146107fd578063c81312c01461082a578063c87b56dd14610875578063cb24bc791461089557600080fd5b8063ab4a87b3146107a9578063b88d4fde146107c9578063c311c523146107e957600080fd5b806394bf804d146106e757806395d89b41146107075780639edc654b1461071c578063a22cb46514610749578063a62141b814610769578063aa6049eb1461078957600080fd5b80634a77ae321161026a5780635dd871a31161022357806370a08231116101fd57806370a082311461065c57806375a5316f1461067c5780638c5e3bb8146106a95780638da5cb5b146106c957600080fd5b80635dd871a3146106075780636352211e146106275780636c8db5451461064757600080fd5b80634a77ae32146105415780634b97aed9146105625780634f6ccce71461057757806355609f1e146105975780635ca9f750146105c75780635cc999ca146105e757600080fd5b806318160ddd116102d75780632f745c59116102b15780632f745c591461046f578063352657161461048f578063399e28831461050157806342842e0e1461052157600080fd5b806318160ddd1461041057806323b872dd1461042f57806323c8c9481461044f57600080fd5b80630148541f1461031f57806301ffc9a71461034157806306fdde0314610376578063081812fc14610398578063095ea7b3146103d0578063167d3e9c146103f0575b600080fd5b34801561032b57600080fd5b5061033f61033a36600461369e565b610a89565b005b34801561034d57600080fd5b5061036161035c366004613587565b610ba6565b60405190151581526020015b60405180910390f35b34801561038257600080fd5b5061038b610bd1565b60405161036d919061383b565b3480156103a457600080fd5b506103b86103b3366004613664565b610c63565b6040516001600160a01b03909116815260200161036d565b3480156103dc57600080fd5b5061033f6103eb366004613542565b610cf8565b3480156103fc57600080fd5b5061033f61040b3660046133b0565b610e0e565b34801561041c57600080fd5b506011545b60405190815260200161036d565b34801561043b57600080fd5b5061033f61044a3660046133fc565b610e55565b34801561045b57600080fd5b5061033f61046a3660046135bf565b610e86565b34801561047b57600080fd5b5061042161048a366004613542565b610eb7565b34801561049b57600080fd5b506104f26104aa366004613664565b60176020908152600091825260409182902060028101546003820154845160608101865260048401548152600584015494810194909452600690920154938301939093529083565b60405161036d939291906139e8565b34801561050d57600080fd5b5061033f61051c366004613664565b610f4d565b34801561052d57600080fd5b5061033f61053c3660046133fc565b610f8d565b34801561054d57600080fd5b50601c5461036190600160a01b900460ff1681565b34801561056e57600080fd5b50601854610421565b34801561058357600080fd5b50610421610592366004613664565b610fa8565b3480156105a357600080fd5b506103616105b2366004613664565b601d6020526000908152604090205460ff1681565b3480156105d357600080fd5b5061033f6105e23660046135bf565b611049565b3480156105f357600080fd5b506103b8610602366004613735565b61107a565b34801561061357600080fd5b50610361610622366004613664565b6110b0565b34801561063357600080fd5b506103b8610642366004613664565b6110bb565b34801561065357600080fd5b5061033f611132565b34801561066857600080fd5b506104216106773660046133b0565b6111d1565b34801561068857600080fd5b50610421610697366004613664565b601a6020526000908152604090205481565b3480156106b557600080fd5b5061033f6106c436600461362c565b611258565b3480156106d557600080fd5b506013546001600160a01b03166103b8565b3480156106f357600080fd5b5061033f61070236600461367c565b611331565b34801561071357600080fd5b5061038b611414565b34801561072857600080fd5b50610421610737366004613664565b60009081526017602052604090205490565b34801561075557600080fd5b5061033f61076436600461350c565b611423565b34801561077557600080fd5b5061033f6107843660046136de565b6114e8565b34801561079557600080fd5b506104216107a4366004613664565b611591565b3480156107b557600080fd5b5061033f6107c436600461356b565b6115a9565b3480156107d557600080fd5b5061033f6107e4366004613437565b6115ec565b3480156107f557600080fd5b506001610361565b34801561080957600080fd5b5061081d6108183660046133b0565b61161e565b60405161036d9190613828565b34801561083657600080fd5b5061084a610845366004613714565b6116da565b60408051941515855260ff93841660208601529183169184019190915216606082015260800161036d565b34801561088157600080fd5b5061038b610890366004613664565b611777565b3480156108a157600080fd5b5061042160185481565b61033f6108b9366004613664565b611852565b3480156108ca57600080fd5b5061033f6108d93660046133b0565b6118fd565b3480156108ea57600080fd5b5061033f6108f93660046133b0565b61194f565b61033f611996565b34801561091257600080fd5b50610926610921366004613664565b611ad2565b60405161036d91906139c7565b34801561093f57600080fd5b5061036161094e3660046133b0565b611b32565b34801561095f57600080fd5b5061097361096e366004613714565b611ba3565b6040805182518152602092830151928101929092520161036d565b34801561099a57600080fd5b506103616109a93660046133ca565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205460ff1690565b3480156109e357600080fd5b506109f76109f2366004613664565b611c1a565b60405161036d9190613933565b348015610a1057600080fd5b50610a24610a1f3660046133b0565b611d91565b60405160ff909116815260200161036d565b348015610a4257600080fd5b506003610a24565b348015610a5657600080fd5b50610a24600381565b348015610a6b57600080fd5b5061038b611dff565b348015610a8057600080fd5b5061038b611e8d565b610a9233611b32565b610ab75760405162461bcd60e51b8152600401610aae9061384e565b60405180910390fd5b33610ac1836110bb565b6001600160a01b031614610b0f5760405162461bcd60e51b815260206004820152601560248201527437b7363c903337b91037bbb732b91037b31031b0b960591b6044820152606401610aae565b6000828152601a6020908152604080832054808452601d9092529091205460ff1615610b745760405162461bcd60e51b815260206004820152601460248201527318d85c9cc818da185b99d95cc8189b1bd8dad95960621b6044820152606401610aae565b6000838152601a602052604090208290610b8e8282613e89565b50506000928352601a60205260409092209190915550565b60006001600160e01b0319821663780e9d6360e01b1480610bcb5750610bcb82611e9a565b92915050565b606060098054610be090613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0c90613d11565b8015610c595780601f10610c2e57610100808354040283529160200191610c59565b820191906000526020600020905b815481529060010190602001808311610c3c57829003601f168201915b5050505050905090565b6000818152600b60205260408120546001600160a01b0316610cdc5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610aae565b506000908152600d60205260409020546001600160a01b031690565b6000610d03826110bb565b9050806001600160a01b0316836001600160a01b03161415610d715760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610aae565b336001600160a01b0382161480610d8d5750610d8d81336109a9565b610dff5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610aae565b610e098383611eea565b505050565b610e1733611b32565b610e335760405162461bcd60e51b8152600401610aae9061384e565b601380546001600160a01b0319166001600160a01b0392909216919091179055565b610e5f3382611f58565b610e7b5760405162461bcd60e51b8152600401610aae906138e2565b610e0983838361204f565b610e8f33611b32565b610eab5760405162461bcd60e51b8152600401610aae9061384e565b610e0960158383613224565b6000610ec2836111d1565b8210610f245760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610aae565b506001600160a01b03919091166000908152600f60209081526040808320938352929052205490565b610f5633611b32565b610f725760405162461bcd60e51b8152600401610aae9061384e565b6000908152601d60205260409020805460ff19166001179055565b610e09838383604051806020016040528060008152506115ec565b6000610fb360115490565b82106110165760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610aae565b6011828154811061103757634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b61105233611b32565b61106e5760405162461bcd60e51b8152600401610aae9061384e565b610e0960148383613224565b6000808260ff166003811061109f57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031692915050565b6000610bcb826121fa565b6000818152600b60205260408120546001600160a01b031680610bcb5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610aae565b60005b600360ff821610156111ce5733600660ff83166003811061116657634e487b7160e01b600052603260045260246000fd5b01546001600160a01b031614156111be573360008260ff166003811061119c57634e487b7160e01b600052603260045260246000fd5b0180546001600160a01b0319166001600160a01b039290921691909117905550565b6111c781613d61565b9050611135565b50565b60006001600160a01b03821661123c5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610aae565b506001600160a01b03166000908152600c602052604090205490565b61126133611b32565b61127d5760405162461bcd60e51b8152600401610aae9061384e565b60a0810135608082013511156112ce5760405162461bcd60e51b815260206004820152601660248201527518d85c881c1c9a58d9481a5cc81a5b98dbdc9c9958dd60521b6044820152606401610aae565b601880549060006112de83613d46565b9091555050601854600090815260176020526040902081906113008282613de4565b50506018546040517f097a2f6c6a41ed0979fb29808bc5ff14ed8e2acb53f623525175eedfdaab1d4e90600090a250565b61133a826121fa565b6113785760405162461bcd60e51b815260206004820152600f60248201526e31b0b73737ba1036b4b73a1031b0b960891b6044820152606401610aae565b61138182612386565b601b546000908152601a602090815260409091208251815582820151805191926113b3926001850192909101906132a8565b50604082015180516113cf9160028401916020909101906132e3565b50606082015180516113eb9160038401916020909101906132a8565b509050506113fb81601b546127c9565b601b805490600061140b83613d46565b91905055505050565b6060600a8054610be090613d11565b6001600160a01b03821633141561147c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610aae565b336000818152600e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6114f133611b32565b61150d5760405162461bcd60e51b8152600401610aae9061384e565b6020810135813511156115575760405162461bcd60e51b81526020600482015260126024820152711c1c9a58d9481a5cc81a5b98dbdc9c9958dd60721b6044820152606401610aae565b6000828152601760205260409020819060040161158b82828135815560208201356001820155604082013560028201555050565b50505050565b600060165461159f83612917565b610bcb9190613a92565b6115b233611b32565b6115ce5760405162461bcd60e51b8152600401610aae9061384e565b601c8054911515600160a01b0260ff60a01b19909216919091179055565b6115f63383611f58565b6116125760405162461bcd60e51b8152600401610aae906138e2565b61158b84848484612ac1565b6060600061162b836111d1565b905060008167ffffffffffffffff81111561165657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561167f578160200160208202803683370190505b50905060005b828110156116d2576116978582610eb7565b8282815181106116b757634e487b7160e01b600052603260045260246000fd5b60209081029190910101526116cb81613d46565b9050611685565b509392505050565b60008060008060006116eb87611c1a565b905060008160600151878151811061171357634e487b7160e01b600052603260045260246000fd5b602090810291909101015160408301518051601083901c935060ff8084169360081c811692908516918b90811061175a57634e487b7160e01b600052603260045260246000fd5b60209081029190910101519b909a50909850909650945050505050565b6000818152600b60205260409020546060906001600160a01b03166117f65760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610aae565b6000611800612af4565b90506000815111611820576040518060200160405280600081525061184b565b8061182a84612b03565b60405160200161183b9291906137bc565b6040516020818303038152906040525b9392505050565b61185b81611591565b34101561189b5760405162461bcd60e51b815260206004820152600e60248201526d0dcdee840cadcdeeaced040cae8d60931b6044820152606401610aae565b6118a3611996565b6040516394bf804d60e01b81526004810182905233602482015230906394bf804d90604401600060405180830381600087803b1580156118e257600080fd5b505af11580156118f6573d6000803e3d6000fd5b5050505050565b61190633611b32565b6119225760405162461bcd60e51b8152600401610aae9061384e565b80600661192e33611d91565b60ff166003811061119c57634e487b7160e01b600052603260045260246000fd5b61195833611b32565b6119745760405162461bcd60e51b8152600401610aae9061384e565b601c80546001600160a01b0319166001600160a01b0392909216919091179055565b60008060005b6003811015610e09576119d1600382600381106119c957634e487b7160e01b600052603260045260246000fd5b015434612c1d565b9150816119dd57611ac2565b346119e88385613a66565b1115611a5a576119f88334613ab1565b91508115610e095760008160038110611a2157634e487b7160e01b600052603260045260246000fd5b01546040516001600160a01b039091169083156108fc029084906000818181858888f1935050505015801561158b573d6000803e3d6000fd5b60008160038110611a7b57634e487b7160e01b600052603260045260246000fd5b01546040516001600160a01b039091169083156108fc029084906000818181858888f19350505050158015611ab4573d6000803e3d6000fd5b50611abf8284613a66565b92505b611acb81613d46565b905061199c565b611af660405180606001604052806000815260200160008152602001600081525090565b50600090815260176020908152604091829020825160608101845260048201548152600582015492810192909252600601549181019190915290565b6000805b600360ff82161015611b9a57826001600160a01b031660008260ff1660038110611b7057634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415611b8a5750600192915050565b611b9381613d61565b9050611b36565b50600092915050565b60408051808201909152600080825260208201526000838152601760205260409020805483908110611be557634e487b7160e01b600052603260045260246000fd5b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050905092915050565b611c456040518060800160405280600081526020016060815260200160608152602001606081525090565b6000828152601a602090815260409182902082516080810184528154815260018201805485518186028101860190965280865291949293858101939290830182828015611cb157602002820191906000526020600020905b815481526020019060010190808311611c9d575b5050505050815260200160028201805480602002602001604051908101604052809291908181526020018280548015611d2957602002820191906000526020600020906000905b825461010083900a900460ff161515815260206001928301818104948501949093039092029101808411611cf85790505b5050505050815260200160038201805480602002602001604051908101604052809291908181526020018280548015611d8157602002820191906000526020600020905b815481526020019060010190808311611d6d575b5050505050815250509050919050565b6000805b600360ff82161015611df657826001600160a01b031660008260ff1660038110611dcf57634e487b7160e01b600052603260045260246000fd5b01546001600160a01b03161415611de65792915050565b611def81613d61565b9050611d95565b50600392915050565b60148054611e0c90613d11565b80601f0160208091040260200160405190810160405280929190818152602001828054611e3890613d11565b8015611e855780601f10611e5a57610100808354040283529160200191611e85565b820191906000526020600020905b815481529060010190602001808311611e6857829003601f168201915b505050505081565b60158054611e0c90613d11565b60006001600160e01b031982166380ac58cd60e01b1480611ecb57506001600160e01b03198216635b5e139f60e01b145b80610bcb57506301ffc9a760e01b6001600160e01b0319831614610bcb565b6000818152600d6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f1f826110bb565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600b60205260408120546001600160a01b0316611fd15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610aae565b6000611fdc836110bb565b9050806001600160a01b0316846001600160a01b031614806120175750836001600160a01b031661200c84610c63565b6001600160a01b0316145b8061204757506001600160a01b038082166000908152600e602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316612062826110bb565b6001600160a01b0316146120ca5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610aae565b6001600160a01b03821661212c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610aae565b612137838383612c29565b612142600082611eea565b6001600160a01b0383166000908152600c6020526040812080546001929061216b908490613ab1565b90915550506001600160a01b0382166000908152600c60205260408120805460019290612199908490613a66565b90915550506000818152600b602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60003330148015906122175750601c546001600160a01b03163314155b8015612229575061222733611b32565b155b1561223657506000919050565b601c54600160a01b900460ff1661224f57506000919050565b60008281526017602090815260408083208151815460c09481028201850190935260a08101838152909391928492849190879085015b828210156122cb57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190612285565b5050505081526020016001820180548060200260200160405190810160405280929190818152602001828054801561232257602002820191906000526020600020905b81548152602001906001019080831161230e575b5050505050815260200160028201548152602001600382015481526020016004820160405180606001604052908160008201548152602001600182015481526020016002820154815250508152505090508060600151816040015110915050919050565b6123b16040518060800160405280600081526020016060815260200160608152602001606081525090565b6000821180156123c357506018548211155b6124075760405162461bcd60e51b81526020600482015260156024820152741a5b98dbdc9c9958dd0818d85c881d1e5c19481a59605a1b6044820152606401610aae565b6000828152601760205260409020600381015460028201541061246c5760405162461bcd60e51b815260206004820152601a60248201527f616c6c206361727320696e2074797065206973206d696e7465640000000000006044820152606401610aae565b805460009067ffffffffffffffff81111561249757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156124c0578160200160208202803683370190505b50905060005b82548110156125d75760008360000182815481106124f457634e487b7160e01b600052603260045260246000fd5b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505090508060000151620186a0612534612ce1565b61253e9190613d81565b1015612597578060200151612551612ce1565b61255b9190613d81565b612566906001613a66565b83838151811061258657634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506125c6565b60008383815181106125b957634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b506125d081613d46565b90506124c6565b50600182015460009067ffffffffffffffff81111561260657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561262f578160200160208202803683370190505b50600184015490915060009067ffffffffffffffff81111561266157634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561268a578160200160208202803683370190505b50905060005b6001850154811015612785578460010181815481106126bf57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154620186a06126d6612ce1565b6126e09190613d81565b1083828151811061270157634e487b7160e01b600052603260045260246000fd5b60200260200101901515908115158152505082818151811061273357634e487b7160e01b600052603260045260246000fd5b60200260200101511561277557612748612d4a565b82828151811061276857634e487b7160e01b600052603260045260246000fd5b6020026020010181815250505b61277e81613d46565b9050612690565b506040805160808101825287815260208101859052908101839052606081018290526002850180549060006127b983613d46565b9091555090979650505050505050565b6001600160a01b03821661281f5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610aae565b6000818152600b60205260409020546001600160a01b0316156128845760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610aae565b61289060008383612c29565b6001600160a01b0382166000908152600c602052604081208054600192906128b9908490613a66565b90915550506000818152600b602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60008181526017602090815260408083208151815460c09481028201850190935260a08101838152859491938492849190879085015b828210156129935783829060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508152602001906001019061294d565b505050508152602001600182018054806020026020016040519081016040528092919081815260200182805480156129ea57602002820191906000526020600020905b8154815260200190600101908083116129d6575b50505050508152602001600282015481526020016003820154815260200160048201604051806060016040529081600082015481526020016001820154815260200160028201548152505081525050905080608001516040015160001415612a5757608001515192915050565b80608001516040015160011415612ab0576000612a7c82604001518360600151612dab565b60808301518051602090910151919250612aa0918391612a9b91613ab1565b612c1d565b6080830151516120479190613a66565b608001515192915050565b50919050565b612acc84848461204f565b612ad884848484612dc0565b61158b5760405162461bcd60e51b8152600401610aae90613890565b606060158054610be090613d11565b606081612b275750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612b515780612b3b81613d46565b9150612b4a9050600a83613a7e565b9150612b2b565b60008167ffffffffffffffff811115612b7a57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612ba4576020820181803683370190505b5090505b841561204757612bb9600183613ab1565b9150612bc6600a86613d81565b612bd1906030613a66565b60f81b818381518110612bf457634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612c16600a86613a7e565b9450612ba8565b600061184b8383612ecd565b6001600160a01b038316612c8457612c7f81601180546000838152601260205260408120829055600182018355919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680155565b612ca7565b816001600160a01b0316836001600160a01b031614612ca757612ca78382612f8f565b6001600160a01b038216612cbe57610e098161302c565b826001600160a01b0316826001600160a01b031614610e0957610e098282613105565b6019546040516bffffffffffffffffffffffff193360601b1660208201526034810191909152426054820152600090819060740160408051601f198184030181529190528051602090910120601980549192506000612d3f83613d46565b909155509092915050565b600080610100612d58612ce1565b612d629190613d81565b90506000610100612d71612ce1565b612d7b9190613d81565b90506000610100612d8a612ce1565b612d949190613d81565b9050601083901b600883901b821717935050505090565b600061184b83670de0b6b3a764000084613149565b60006001600160a01b0384163b15612ec257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612e049033908990889088906004016137eb565b602060405180830381600087803b158015612e1e57600080fd5b505af1925050508015612e4e575060408051601f3d908101601f19168201909252612e4b918101906135a3565b60015b612ea8573d808015612e7c576040519150601f19603f3d011682016040523d82523d6000602084013e612e81565b606091505b508051612ea05760405162461bcd60e51b8152600401610aae90613890565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612047565b506001949350505050565b60008080600019848609848602925082811083820303915050670de0b6b3a76400008110612f115760405163698d9a0160e11b815260048101829052602401610aae565b600080670de0b6b3a76400008688099150506706f05b59d3b1ffff811182612f4b5780670de0b6b3a7640000850401945050505050610bcb565b620400008285030493909111909103600160ee1b02919091177faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac106690201905092915050565b60006001612f9c846111d1565b612fa69190613ab1565b600083815260106020526040902054909150808214612ff9576001600160a01b0384166000908152600f602090815260408083208584528252808320548484528184208190558352601090915290208190555b5060009182526010602090815260408084208490556001600160a01b039094168352600f81528383209183525290812055565b60115460009061303e90600190613ab1565b6000838152601260205260408120546011805493945090928490811061307457634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080601183815481106130a357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101929092558281526012909152604080822084905585825281205560118054806130e957634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000613110836111d1565b6001600160a01b039093166000908152600f60209081526040808320868452825280832085905593825260109052919091209190915550565b6000808060001985870985870292508281108382030391505080600014156131925783828161318857634e487b7160e01b600052601260045260246000fd5b049250505061184b565b8381106131bc57604051631dcf306360e21b81526004810182905260248101859052604401610aae565b600084868809600260036001881981018916988990049182028318808302840302808302840302808302840302808302840302808302840302918202909203026000889003889004909101858311909403939093029303949094049190911702949350505050565b82805461323090613d11565b90600052602060002090601f0160209004810192826132525760008555613298565b82601f1061326b5782800160ff19823516178555613298565b82800160010185558215613298579182015b8281111561329857823582559160200191906001019061327d565b506132a492915061337f565b5090565b828054828255906000526020600020908101928215613298579160200282015b828111156132985782518255916020019190600101906132c8565b82805482825590600052602060002090601f016020900481019282156132985791602002820160005b8382111561334957835183826101000a81548160ff021916908315150217905550926020019260010160208160000104928301926001030261330c565b80156133765782816101000a81549060ff0219169055600101602081600001049283019260010302613349565b50506132a49291505b5b808211156132a45760008155600101613380565b80356001600160a01b03811681146133ab57600080fd5b919050565b6000602082840312156133c1578081fd5b61184b82613394565b600080604083850312156133dc578081fd5b6133e583613394565b91506133f360208401613394565b90509250929050565b600080600060608486031215613410578081fd5b61341984613394565b925061342760208501613394565b9150604084013590509250925092565b6000806000806080858703121561344c578081fd5b61345585613394565b935061346360208601613394565b925060408501359150606085013567ffffffffffffffff80821115613486578283fd5b818701915087601f830112613499578283fd5b8135818111156134ab576134ab613dc1565b604051601f8201601f19908116603f011681019083821181831017156134d3576134d3613dc1565b816040528281528a60208487010111156134eb578586fd5b82602086016020830137918201602001949094529598949750929550505050565b6000806040838503121561351e578182fd5b61352783613394565b9150602083013561353781613f3d565b809150509250929050565b60008060408385031215613554578182fd5b61355d83613394565b946020939093013593505050565b60006020828403121561357c578081fd5b813561184b81613f3d565b600060208284031215613598578081fd5b813561184b81613f4b565b6000602082840312156135b4578081fd5b815161184b81613f4b565b600080602083850312156135d1578182fd5b823567ffffffffffffffff808211156135e8578384fd5b818501915085601f8301126135fb578384fd5b813581811115613609578485fd5b86602082850101111561361a578485fd5b60209290920196919550909350505050565b60006020828403121561363d578081fd5b813567ffffffffffffffff811115613653578182fd5b820160e0818503121561184b578182fd5b600060208284031215613675578081fd5b5035919050565b6000806040838503121561368e578182fd5b823591506133f360208401613394565b600080604083850312156136b0578182fd5b82359150602083013567ffffffffffffffff8111156136cd578182fd5b830160808186031215613537578182fd5b60008082840360808112156136f1578283fd5b833592506060601f1982011215613706578182fd5b506020830190509250929050565b60008060408385031215613726578182fd5b50508035926020909101359150565b600060208284031215613746578081fd5b813560ff8116811461184b578182fd5b6000815180845260208085019450808401835b8381101561378557815187529582019590820190600101613769565b509495945050505050565b600081518084526137a8816020860160208601613ce5565b601f01601f19169290920160200192915050565b600083516137ce818460208801613ce5565b8351908301906137e2818360208801613ce5565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061381e90830184613790565b9695505050505050565b60208152600061184b6020830184613756565b60208152600061184b6020830184613790565b60208082526022908201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f604082015261371760f11b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60006020808352835181840152808401516080604085015261395860a0850182613756565b6040860151601f19868303810160608801528151808452918501935085929091908501905b8084101561399f5784511515825293850193600193909301929085019061397d565b5060608801519450818782030160808801526139bb8186613756565b98975050505050505050565b81518152602080830151908201526040808301519082015260608101610bcb565b8381526020810183905260a0810161204760408301848051825260208082015190830152604090810151910152565b6000808335601e19843603018112613a2d578283fd5b83018035915067ffffffffffffffff821115613a47578283fd5b6020019150600581901b3603821315613a5f57600080fd5b9250929050565b60008219821115613a7957613a79613d95565b500190565b600082613a8d57613a8d613dab565b500490565b6000816000190483118215151615613aac57613aac613d95565b500290565b600082821015613ac357613ac3613d95565b500390565b5b81811015613add5760008155600101613ac9565b5050565b600160401b831115613af557613af5613dc1565b805483825580841015613b4b57816000526020600020601f850160051c8101601f86168015613b35576000198083018054828460200360031b1c16815550505b50613b48601f840160051c830182613ac8565b50505b506000818152602081208391805b86811015613bb157613b89613b6d85613dd7565b845460ff600386901b90811b8019909216921515901b16178455565b60208401935060018083019250601f831115613ba85792830192600092505b50600101613b59565b50505050505050565b600160401b831115613bce57613bce613dc1565b805483825580841015613c3f576001600160ff1b036001818311811615613bf757613bf7613d95565b818611811615613c0957613c09613d95565b60008481526020902086821b8101925083821b015b80831015613c3b5760008355600083830155600283019250613c1e565b5050505b5060008181526020812083915b85811015613c785782358255602083013560018301556040929092019160029190910190600101613c4c565b505050505050565b600160401b831115613c9457613c94613dc1565b805483825580841015613cba57816000526020600020613cb8828201868301613ac8565b505b50818160005260208060002060005b86811015613bb157833582559282019260019182019101613cc9565b60005b83811015613d00578181015183820152602001613ce8565b8381111561158b5750506000910152565b600181811c90821680613d2557607f821691505b60208210811415612abb57634e487b7160e01b600052602260045260246000fd5b6000600019821415613d5a57613d5a613d95565b5060010190565b600060ff821660ff811415613d7857613d78613d95565b60010192915050565b600082613d9057613d90613dab565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008135610bcb81613f3d565b8135601e19833603018112613df857600080fd5b8201803567ffffffffffffffff811115613e1157600080fd5b6020820191508060061b3603821315613e2957600080fd5b613e34818385613bba565b5050613e436020830183613a17565b613e51818360018601613c80565b505060408201356002820155606082013560038201556080820135600482015560a0820135600582015560c082013560068201555050565b8135815560018082016020613ea081860186613a17565b600160401b811115613eb457613eb4613dc1565b835481855580821015613ed9578460005283600020613ed7828201848301613ac8565b505b506000938452828420935b81811015613eff578235855593850193918301918501613ee4565b505050505050613f126040830183613a17565b613f20818360028601613ae1565b5050613f2f6060830183613a17565b61158b818360038601613c80565b80151581146111ce57600080fd5b6001600160e01b0319811681146111ce57600080fdfea2646970667358221220b08cd12587fe388d7a6a29de11a75fdca22109d60145441d987a370138afc64864736f6c63430008040033

Deployed Bytecode Sourcemap

108133:5130:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111690:354;;;;;;;;;;-1:-1:-1;111690:354:0;;;;;:::i;:::-;;:::i;:::-;;92291:224;;;;;;;;;;-1:-1:-1;92291:224:0;;;;;:::i;:::-;;:::i;:::-;;;9398:14:1;;9391:22;9373:41;;9361:2;9346:18;92291:224:0;;;;;;;;79180:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;80739:221::-;;;;;;;;;;-1:-1:-1;80739:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;8430:32:1;;;8412:51;;8400:2;8385:18;80739:221:0;8367:102:1;80262:411:0;;;;;;;;;;-1:-1:-1;80262:411:0;;;;;:::i;:::-;;:::i;99370:89::-;;;;;;;;;;-1:-1:-1;99370:89:0;;;;;:::i;:::-;;:::i;92931:113::-;;;;;;;;;;-1:-1:-1;93019:10:0;:17;92931:113;;;21569:25:1;;;21557:2;21542:18;92931:113:0;21524:76:1;81629:339:0;;;;;;;;;;-1:-1:-1;81629:339:0;;;;;:::i;:::-;;:::i;99906:104::-;;;;;;;;;;-1:-1:-1;99906:104:0;;;;;:::i;:::-;;:::i;92599:256::-;;;;;;;;;;-1:-1:-1;92599:256:0;;;;;:::i;:::-;;:::i;100616:44::-;;;;;;;;;;-1:-1:-1;100616:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;112195:112::-;;;;;;;;;;-1:-1:-1;112195:112:0;;;;;:::i;:::-;;:::i;82039:185::-;;;;;;;;;;-1:-1:-1;82039:185:0;;;;;:::i;:::-;;:::i;108388:28::-;;;;;;;;;;-1:-1:-1;108388:28:0;;;;-1:-1:-1;;;108388:28:0;;;;;;112392:102;;;;;;;;;;-1:-1:-1;112473:13:0;;112392:102;;93121:233;;;;;;;;;;-1:-1:-1;93121:233:0;;;;;:::i;:::-;;:::i;108457:46::-;;;;;;;;;;-1:-1:-1;108457:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;99732:120;;;;;;;;;;-1:-1:-1;99732:120:0;;;;;:::i;:::-;;:::i;55626:108::-;;;;;;;;;;-1:-1:-1;55626:108:0;;;;;:::i;:::-;;:::i;110211:126::-;;;;;;;;;;-1:-1:-1;110211:126:0;;;;;:::i;:::-;;:::i;78874:239::-;;;;;;;;;;-1:-1:-1;78874:239:0;;;;;:::i;:::-;;:::i;56353:303::-;;;;;;;;;;;;;:::i;78604:208::-;;;;;;;;;;-1:-1:-1;78604:208:0;;;;;:::i;:::-;;:::i;108196:38::-;;;;;;;;;;-1:-1:-1;108196:38:0;;;;;:::i;:::-;;;;;;;;;;;;;;103429:313;;;;;;;;;;-1:-1:-1;103429:313:0;;;;;:::i;:::-;;:::i;99283:79::-;;;;;;;;;;-1:-1:-1;99348:6:0;;-1:-1:-1;;;;;99348:6:0;99283:79;;110904:260;;;;;;;;;;-1:-1:-1;110904:260:0;;;;;:::i;:::-;;:::i;79349:104::-;;;;;;;;;;;;;:::i;105539:135::-;;;;;;;;;;-1:-1:-1;105539:135:0;;;;;:::i;:::-;105602:7;105629:20;;;:9;:20;;;;;:37;;105539:135;81032:295;;;;;;;;;;-1:-1:-1;81032:295:0;;;;;:::i;:::-;;:::i;103813:247::-;;;;;;;;;;-1:-1:-1;103813:247:0;;;;;:::i;:::-;;:::i;104191:132::-;;;;;;;;;;-1:-1:-1;104191:132:0;;;;;:::i;:::-;;:::i;109990:85::-;;;;;;;;;;-1:-1:-1;109990:85:0;;;;;:::i;:::-;;:::i;82295:328::-;;;;;;;;;;-1:-1:-1;82295:328:0;;;;;:::i;:::-;;:::i;112603:104::-;;;;;;;;;;-1:-1:-1;112695:4:0;112603:104;;112908:352;;;;;;;;;;-1:-1:-1;112908:352:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;109163:578::-;;;;;;;;;;-1:-1:-1;109163:578:0;;;;;:::i;:::-;;:::i;:::-;;;;9663:14:1;;9656:22;9638:41;;9727:4;9715:17;;;9710:2;9695:18;;9688:45;9769:17;;;9749:18;;;9742:45;;;;9823:17;9818:2;9803:18;;9796:45;9625:3;9610:19;109163:578:0;9592:255:1;79524:334:0;;;;;;;;;;-1:-1:-1;79524:334:0;;;;;:::i;:::-;;:::i;100697:32::-;;;;;;;;;;;;;;;;111347:191;;;;;;:::i;:::-;;:::i;55971:276::-;;;;;;;;;;-1:-1:-1;55971:276:0;;;;;:::i;:::-;;:::i;109817:92::-;;;;;;;;;;-1:-1:-1;109817:92:0;;;;;:::i;:::-;;:::i;56720:807::-;;;:::i;105185:164::-;;;;;;;;;;-1:-1:-1;105185:164:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;54945:194::-;;;;;;;;;;-1:-1:-1;54945:194:0;;;;;:::i;:::-;;:::i;105862:195::-;;;;;;;;;;-1:-1:-1;105862:195:0;;;;;:::i;:::-;;:::i;:::-;;;;19925:13:1;;19907:32;;19995:4;19983:17;;;19977:24;19955:20;;;19948:54;;;;19880:18;105862:195:0;19862:146:1;81398:164:0;;;;;;;;;;-1:-1:-1;81398:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;81519:25:0;;;81495:4;81519:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;81398:164;108890:108;;;;;;;;;;-1:-1:-1;108890:108:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;55234:213::-;;;;;;;;;;-1:-1:-1;55234:213:0;;;;;:::i;:::-;;:::i;:::-;;;22705:4:1;22693:17;;;22675:36;;22663:2;22648:18;55234:213:0;22630:87:1;55798:89:0;;;;;;;;;;-1:-1:-1;53814:1:0;55798:89;;53777:38;;;;;;;;;;;;53814:1;53777:38;;98902:70;;;;;;;;;;;;;:::i;99010:65::-;;;;;;;;;;;;;:::i;111690:354::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;;;;;;;;;111803:10:::1;111783:16;111791:7:::0;111783::::1;:16::i;:::-;-1:-1:-1::0;;;;;111783:30:0::1;;111775:64;;;::::0;-1:-1:-1;;;111775:64:0;;13270:2:1;111775:64:0::1;::::0;::::1;13252:21:1::0;13309:2;13289:18;;;13282:30;-1:-1:-1;;;13328:18:1;;;13321:51;13389:18;;111775:64:0::1;13242:171:1::0;111775:64:0::1;111850:14;111867:16:::0;;;:7:::1;:16;::::0;;;;;;;:23;111910:22;;;:14:::1;:22:::0;;;;;;;::::1;;111909:23;111901:56;;;::::0;-1:-1:-1;;;111901:56:0;;12209:2:1;111901:56:0::1;::::0;::::1;12191:21:1::0;12248:2;12228:18;;;12221:30;-1:-1:-1;;;12267:18:1;;;12260:50;12327:18;;111901:56:0::1;12181:170:1::0;111901:56:0::1;111968:16;::::0;;;:7:::1;:16;::::0;;;;111987:6;;111968:25:::1;111987:6:::0;111968:16;:25:::1;:::i;:::-;-1:-1:-1::0;;112004:16:0::1;::::0;;;:7:::1;:16;::::0;;;;;:32;;;;-1:-1:-1;111690:354:0:o;92291:224::-;92393:4;-1:-1:-1;;;;;;92417:50:0;;-1:-1:-1;;;92417:50:0;;:90;;;92471:36;92495:11;92471:23;:36::i;:::-;92410:97;92291:224;-1:-1:-1;;92291:224:0:o;79180:100::-;79234:13;79267:5;79260:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79180:100;:::o;80739:221::-;80815:7;84222:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84222:16:0;80835:73;;;;-1:-1:-1;;;80835:73:0;;16399:2:1;80835:73:0;;;16381:21:1;16438:2;16418:18;;;16411:30;16477:34;16457:18;;;16450:62;-1:-1:-1;;;16528:18:1;;;16521:42;16580:19;;80835:73:0;16371:234:1;80835:73:0;-1:-1:-1;80928:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;80928:24:0;;80739:221::o;80262:411::-;80343:13;80359:23;80374:7;80359:14;:23::i;:::-;80343:39;;80407:5;-1:-1:-1;;;;;80401:11:0;:2;-1:-1:-1;;;;;80401:11:0;;;80393:57;;;;-1:-1:-1;;;80393:57:0;;17982:2:1;80393:57:0;;;17964:21:1;18021:2;18001:18;;;17994:30;18060:34;18040:18;;;18033:62;-1:-1:-1;;;18111:18:1;;;18104:31;18152:19;;80393:57:0;17954:223:1;80393:57:0;73717:10;-1:-1:-1;;;;;80485:21:0;;;;:62;;-1:-1:-1;80510:37:0;80527:5;73717:10;81398:164;:::i;80510:37::-;80463:168;;;;-1:-1:-1;;;80463:168:0;;14792:2:1;80463:168:0;;;14774:21:1;14831:2;14811:18;;;14804:30;14870:34;14850:18;;;14843:62;14941:26;14921:18;;;14914:54;14985:19;;80463:168:0;14764:246:1;80463:168:0;80644:21;80653:2;80657:7;80644:8;:21::i;:::-;80262:411;;;:::o;99370:89::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;99434:6:::1;:17:::0;;-1:-1:-1;;;;;;99434:17:0::1;-1:-1:-1::0;;;;;99434:17:0;;;::::1;::::0;;;::::1;::::0;;99370:89::o;81629:339::-;81824:41;73717:10;81857:7;81824:18;:41::i;:::-;81816:103;;;;-1:-1:-1;;;81816:103:0;;;;;;;:::i;:::-;81932:28;81942:4;81948:2;81952:7;81932:9;:28::i;99906:104::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;99982:20:::1;:7;99992:10:::0;;99982:20:::1;:::i;92599:256::-:0;92696:7;92732:23;92749:5;92732:16;:23::i;:::-;92724:5;:31;92716:87;;;;-1:-1:-1;;;92716:87:0;;11031:2:1;92716:87:0;;;11013:21:1;11070:2;11050:18;;;11043:30;11109:34;11089:18;;;11082:62;-1:-1:-1;;;11160:18:1;;;11153:41;11211:19;;92716:87:0;11003:233:1;92716:87:0;-1:-1:-1;;;;;;92821:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;92599:256::o;112195:112::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;112267:25:::1;::::0;;;:14:::1;:25;::::0;;;;:32;;-1:-1:-1;;112267:32:0::1;112295:4;112267:32;::::0;;112195:112::o;82039:185::-;82177:39;82194:4;82200:2;82204:7;82177:39;;;;;;;;;;;;:16;:39::i;93121:233::-;93196:7;93232:30;93019:10;:17;;92931:113;93232:30;93224:5;:38;93216:95;;;;-1:-1:-1;;;93216:95:0;;19153:2:1;93216:95:0;;;19135:21:1;19192:2;19172:18;;;19165:30;19231:34;19211:18;;;19204:62;-1:-1:-1;;;19282:18:1;;;19275:42;19334:19;;93216:95:0;19125:234:1;93216:95:0;93329:10;93340:5;93329:17;;;;;;-1:-1:-1;;;93329:17:0;;;;;;;;;;;;;;;;;93322:24;;93121:233;;;:::o;99732:120::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;99816:28:::1;:11;99830:14:::0;;99816:28:::1;:::i;55626:108::-:0;55686:7;55713:6;55720:5;55713:13;;;;;;;-1:-1:-1;;;55713:13:0;;;;;;;;;;;-1:-1:-1;;;;;55713:13:0;;55626:108;-1:-1:-1;;55626:108:0:o;110211:126::-;110279:4;110303:26;110319:9;110303:15;:26::i;78874:239::-;78946:7;78982:16;;;:7;:16;;;;;;-1:-1:-1;;;;;78982:16:0;79017:19;79009:73;;;;-1:-1:-1;;;79009:73:0;;15628:2:1;79009:73:0;;;15610:21:1;15667:2;15647:18;;;15640:30;15706:34;15686:18;;;15679:62;-1:-1:-1;;;15757:18:1;;;15750:39;15806:19;;79009:73:0;15600:231:1;56353:303:0;56483:7;56478:171;53814:1;56496:16;;;;56478:171;;;56556:10;56536:13;:16;;;;;;;;-1:-1:-1;;;56536:16:0;;;;;;;;;;;-1:-1:-1;;;;;56536:16:0;:30;56532:117;;;56599:10;56587:6;56594:1;56587:9;;;;;;;-1:-1:-1;;;56587:9:0;;;;;;;;;;:22;;-1:-1:-1;;;;;;56587:22:0;-1:-1:-1;;;;;56587:22:0;;;;;;;;;;-1:-1:-1;56353:303:0:o;56532:117::-;56514:3;;;:::i;:::-;;;56478:171;;;;56353:303::o;78604:208::-;78676:7;-1:-1:-1;;;;;78704:19:0;;78696:74;;;;-1:-1:-1;;;78696:74:0;;15217:2:1;78696:74:0;;;15199:21:1;15256:2;15236:18;;;15229:30;15295:34;15275:18;;;15268:62;-1:-1:-1;;;15346:18:1;;;15339:40;15396:19;;78696:74:0;15189:232:1;78696:74:0;-1:-1:-1;;;;;;78788:16:0;;;;;:9;:16;;;;;;;78604:208::o;103429:313::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;103553:22;;;::::1;:13;::::0;::::1;103525:24;:50;;103503:122;;;::::0;-1:-1:-1;;;103503:122:0;;18802:2:1;103503:122:0::1;::::0;::::1;18784:21:1::0;18841:2;18821:18;;;18814:30;-1:-1:-1;;;18860:18:1;;;18853:52;18922:18;;103503:122:0::1;18774:172:1::0;103503:122:0::1;103636:13;:15:::0;;;:13:::1;:15;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;103672:13:0::1;::::0;103662:24:::1;::::0;;;:9:::1;:24;::::0;;;;103689:7;;103662:34:::1;103689:7:::0;103662:24;:34:::1;:::i;:::-;-1:-1:-1::0;;103720:13:0::1;::::0;103712:22:::1;::::0;::::1;::::0;;;::::1;103429:313:::0;:::o;110904:260::-;110994:26;111010:9;110994:15;:26::i;:::-;110986:54;;;;-1:-1:-1;;;110986:54:0;;17638:2:1;110986:54:0;;;17620:21:1;17677:2;17657:18;;;17650:30;-1:-1:-1;;;17696:18:1;;;17689:45;17751:18;;110986:54:0;17610:165:1;110986:54:0;111073:20;111083:9;111073;:20::i;:::-;111059:10;;111051:19;;;;:7;:19;;;;;;;;:42;;;;;;;;;;:19;;:42;;;;;;;;;;;:::i;:::-;-1:-1:-1;111051:42:0;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;111051:42:0;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;111104:29;111110:10;111122;;111104:5;:29::i;:::-;111144:10;:12;;;:10;:12;;;:::i;:::-;;;;;;110904:260;;:::o;79349:104::-;79405:13;79438:7;79431:14;;;;;:::i;81032:295::-;-1:-1:-1;;;;;81135:24:0;;73717:10;81135:24;;81127:62;;;;-1:-1:-1;;;81127:62:0;;14025:2:1;81127:62:0;;;14007:21:1;14064:2;14044:18;;;14037:30;14103:27;14083:18;;;14076:55;14148:18;;81127:62:0;13997:175:1;81127:62:0;73717:10;81202:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;81202:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;81202:53:0;;;;;;;;;;81271:48;;9373:41:1;;;81202:42:0;;73717:10;81271:48;;9346:18:1;81271:48:0;;;;;;;81032:295;;:::o;103813:247::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;103964:17:::1;::::0;::::1;;103941:19:::0;::::1;:40;;103933:71;;;::::0;-1:-1:-1;;;103933:71:0;;11862:2:1;103933:71:0::1;::::0;::::1;11844:21:1::0;11901:2;11881:18;;;11874:30;-1:-1:-1;;;11920:18:1;;;11913:48;11978:18;;103933:71:0::1;11834:168:1::0;103933:71:0::1;104015:20;::::0;;;:9:::1;:20;::::0;;;;104044:8;;104015:26:::1;;:37;104044:8:::0;104015:26;27925:5:1;27912:19;27906:4;27899:33;27986:2;27979:5;27975:14;27962:28;27958:1;27952:4;27948:12;27941:50;28045:2;28038:5;28034:14;28021:28;28017:1;28011:4;28007:12;28000:50;27889:167;;;104015:37:0::1;-1:-1:-1::0;;;;103813:247:0:o;104191:132::-;104249:7;104307:8;;104276:28;104294:9;104276:17;:28::i;:::-;:39;;;;:::i;109990:85::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;110050:9:::1;:17:::0;;;::::1;;-1:-1:-1::0;;;110050:17:0::1;-1:-1:-1::0;;;;110050:17:0;;::::1;::::0;;;::::1;::::0;;109990:85::o;82295:328::-;82470:41;73717:10;82503:7;82470:18;:41::i;:::-;82462:103;;;;-1:-1:-1;;;82462:103:0;;;;;;;:::i;:::-;82576:39;82590:4;82596:2;82600:7;82609:5;82576:13;:39::i;112908:352::-;112996:16;113030:13;113046:18;113056:7;113046:9;:18::i;:::-;113030:34;;113075:20;113112:5;113098:20;;;;;;-1:-1:-1;;;113098:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;113098:20:0;;113075:43;;113134:9;113129:103;113153:5;113149:1;:9;113129:103;;;113189:31;113209:7;113218:1;113189:19;:31::i;:::-;113180:3;113184:1;113180:6;;;;;;-1:-1:-1;;;113180:6:0;;;;;;;;;;;;;;;;;;:40;113160:3;;;:::i;:::-;;;113129:103;;;-1:-1:-1;113249:3:0;112908:352;-1:-1:-1;;;112908:352:0:o;109163:578::-;109286:4;109337:5;109362;109387;109425:14;109442:15;109449:7;109442:6;:15::i;:::-;109425:32;;109468:13;109484:3;:10;;;109495;109484:22;;;;;;-1:-1:-1;;;109484:22:0;;;;;;;;;;;;;;;;;;;109695:16;;;;:28;;109623:11;;;;;-1:-1:-1;109543:4:0;109535:12;;;;109569:1;109559:11;109599:12;;;109663;;;;109712:10;;109695:28;;;;-1:-1:-1;;;109695:28:0;;;;;;;;;;;;;;;;;;;;109725:1;;-1:-1:-1;109728:1:0;;-1:-1:-1;109731:1:0;;-1:-1:-1;109163:578:0;-1:-1:-1;;;;;109163:578:0:o;79524:334::-;84198:4;84222:16;;;:7;:16;;;;;;79597:13;;-1:-1:-1;;;;;84222:16:0;79623:76;;;;-1:-1:-1;;;79623:76:0;;17222:2:1;79623:76:0;;;17204:21:1;17261:2;17241:18;;;17234:30;17300:34;17280:18;;;17273:62;-1:-1:-1;;;17351:18:1;;;17344:45;17406:19;;79623:76:0;17194:237:1;79623:76:0;79712:21;79736:10;:8;:10::i;:::-;79712:34;;79788:1;79770:7;79764:21;:25;:86;;;;;;;;;;;;;;;;;79816:7;79825:18;:7;:16;:18::i;:::-;79799:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;79764:86;79757:93;79524:334;-1:-1:-1;;;79524:334:0:o;111347:191::-;111430:19;111439:9;111430:8;:19::i;:::-;111417:9;:32;;111409:59;;;;-1:-1:-1;;;111409:59:0;;19566:2:1;111409:59:0;;;19548:21:1;19605:2;19585:18;;;19578:30;-1:-1:-1;;;19624:18:1;;;19617:44;19678:18;;111409:59:0;19538:164:1;111409:59:0;111479:8;:6;:8::i;:::-;111498:32;;-1:-1:-1;;;111498:32:0;;;;;21779:25:1;;;111519:10:0;21820:18:1;;;21813:60;111498:4:0;;:9;;21752:18:1;;111498:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111347:191;:::o;55971:276::-;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;56231:8:::1;56180:13;56194:33;56216:10;56194:21;:33::i;:::-;56180:48;;;;;;;-1:-1:-1::0;;;56180:48:0::1;;;;;;;;109817:92:::0;54731:19;54739:10;54731:7;:19::i;:::-;54723:66;;;;-1:-1:-1;;;54723:66:0;;;;;;;:::i;:::-;109883:6:::1;:18:::0;;-1:-1:-1;;;;;;109883:18:0::1;-1:-1:-1::0;;;;;109883:18:0;;;::::1;::::0;;;::::1;::::0;;109817:92::o;56720:807::-;56814:11;56836:15;56918:9;56913:607;53814:1;56933:16;;56913:607;;;56981:44;57000:10;57011:1;57000:13;;;;;-1:-1:-1;;;57000:13:0;;;;;;;;;;;57015:9;56981:18;:44::i;:::-;56971:54;-1:-1:-1;57044:12:0;57040:26;;57058:8;;57040:26;57101:9;57085:13;57091:7;57085:3;:13;:::i;:::-;:25;57081:299;;;57141:15;57153:3;57141:9;:15;:::i;:::-;57131:25;-1:-1:-1;57290:11:0;;57286:53;;57311:6;57318:1;57311:9;;;;;-1:-1:-1;;;57311:9:0;;;;;;;;;;;57303:36;;-1:-1:-1;;;;;57311:9:0;;;;57303:36;;;;;57331:7;;57311:9;57303:36;57311:9;57303:36;57331:7;57311:9;57303:36;;;;;;;;;;;;;;;;;;;57081:299;57451:6;57458:1;57451:9;;;;;-1:-1:-1;;;57451:9:0;;;;;;;;;;;57443:36;;-1:-1:-1;;;;;57451:9:0;;;;57443:36;;;;;57471:7;;57451:9;57443:36;57451:9;57443:36;57471:7;57451:9;57443:36;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57494:14:0;57501:7;57494:14;;:::i;:::-;;;56913:607;56951:3;;;:::i;:::-;;;56913:607;;105185:164;105274:16;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;105274:16:0;-1:-1:-1;105315:20:0;;;;:9;:20;;;;;;;;;105308:33;;;;;;;105315:26;;;105308:33;;;;;;;;;;;;;;;;;;;;;;;;;105185:164::o;54945:194::-;55000:4;;55017:91;53814:1;55035:16;;;;55017:91;;;55088:7;-1:-1:-1;;;;;55075:20:0;:6;55082:1;55075:9;;;;;;;-1:-1:-1;;;55075:9:0;;;;;;;;;;;-1:-1:-1;;;;;55075:9:0;:20;55071:37;;;-1:-1:-1;55104:4:0;;54945:194;-1:-1:-1;;54945:194:0:o;55071:37::-;55053:3;;;:::i;:::-;;;55017:91;;;-1:-1:-1;55126:5:0;;54945:194;-1:-1:-1;;54945:194:0:o;105862:195::-;-1:-1:-1;;;;;;;;;;;;;;;;;106008:20:0;;;;:9;:20;;;;;:41;;106039:9;;106008:41;;;;-1:-1:-1;;;106008:41:0;;;;;;;;;;;;;;;;;;;106001:48;;;;;;;;;;;;;;;;;;;;;;;;;;;105862:195;;;;:::o;108890:108::-;108944:10;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108944:10:0;108974:16;;;;:7;:16;;;;;;;;;108967:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108974:16;;108967:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108890:108;;;:::o;55234:213::-;55303:5;;55321:88;53814:1;55339:16;;;;55321:88;;;55392:7;-1:-1:-1;;;;;55379:20:0;:6;55386:1;55379:9;;;;;;;-1:-1:-1;;;55379:9:0;;;;;;;;;;;-1:-1:-1;;;;;55379:9:0;:20;55375:34;;;55408:1;55234:213;-1:-1:-1;;55234:213:0:o;55375:34::-;55357:3;;;:::i;:::-;;;55321:88;;;-1:-1:-1;53814:1:0;;55234:213;-1:-1:-1;;55234:213:0:o;98902:70::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;99010:65::-;;;;;;;:::i;78235:305::-;78337:4;-1:-1:-1;;;;;;78374:40:0;;-1:-1:-1;;;78374:40:0;;:105;;-1:-1:-1;;;;;;;78431:48:0;;-1:-1:-1;;;78431:48:0;78374:105;:158;;;-1:-1:-1;;;;;;;;;;76842:40:0;;;78496:36;76733:157;88115:174;88190:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;88190:29:0;-1:-1:-1;;;;;88190:29:0;;;;;;;;:24;;88244:23;88190:24;88244:14;:23::i;:::-;-1:-1:-1;;;;;88235:46:0;;;;;;;;;;;88115:174;;:::o;84427:348::-;84520:4;84222:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84222:16:0;84537:73;;;;-1:-1:-1;;;84537:73:0;;14379:2:1;84537:73:0;;;14361:21:1;14418:2;14398:18;;;14391:30;14457:34;14437:18;;;14430:62;-1:-1:-1;;;14508:18:1;;;14501:42;14560:19;;84537:73:0;14351:234:1;84537:73:0;84621:13;84637:23;84652:7;84637:14;:23::i;:::-;84621:39;;84690:5;-1:-1:-1;;;;;84679:16:0;:7;-1:-1:-1;;;;;84679:16:0;;:51;;;;84723:7;-1:-1:-1;;;;;84699:31:0;:20;84711:7;84699:11;:20::i;:::-;-1:-1:-1;;;;;84699:31:0;;84679:51;:87;;;-1:-1:-1;;;;;;81519:25:0;;;81495:4;81519:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;84734:32;84671:96;84427:348;-1:-1:-1;;;;84427:348:0:o;87419:578::-;87578:4;-1:-1:-1;;;;;87551:31:0;:23;87566:7;87551:14;:23::i;:::-;-1:-1:-1;;;;;87551:31:0;;87543:85;;;;-1:-1:-1;;;87543:85:0;;16812:2:1;87543:85:0;;;16794:21:1;16851:2;16831:18;;;16824:30;16890:34;16870:18;;;16863:62;-1:-1:-1;;;16941:18:1;;;16934:39;16990:19;;87543:85:0;16784:231:1;87543:85:0;-1:-1:-1;;;;;87647:16:0;;87639:65;;;;-1:-1:-1;;;87639:65:0;;13620:2:1;87639:65:0;;;13602:21:1;13659:2;13639:18;;;13632:30;13698:34;13678:18;;;13671:62;-1:-1:-1;;;13749:18:1;;;13742:34;13793:19;;87639:65:0;13592:226:1;87639:65:0;87717:39;87738:4;87744:2;87748:7;87717:20;:39::i;:::-;87821:29;87838:1;87842:7;87821:8;:29::i;:::-;-1:-1:-1;;;;;87863:15:0;;;;;;:9;:15;;;;;:20;;87882:1;;87863:15;:20;;87882:1;;87863:20;:::i;:::-;;;;-1:-1:-1;;;;;;;87894:13:0;;;;;;:9;:13;;;;;:18;;87911:1;;87894:13;:18;;87911:1;;87894:18;:::i;:::-;;;;-1:-1:-1;;87923:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;87923:21:0;-1:-1:-1;;;;;87923:21:0;;;;;;;;;87962:27;;87923:16;;87962:27;;;;;;;87419:578;;;:::o;110345:380::-;110412:4;110447:10;110469:4;110447:27;;;;:64;;-1:-1:-1;110505:6:0;;-1:-1:-1;;;;;110505:6:0;110491:10;:20;;110447:64;:101;;;;;110529:19;110537:10;110529:7;:19::i;:::-;110528:20;110447:101;110429:143;;;-1:-1:-1;110567:5:0;;110345:380;-1:-1:-1;110345:380:0:o;110429:143::-;110588:9;;-1:-1:-1;;;110588:9:0;;;;110583:28;;-1:-1:-1;110606:5:0;;110345:380;-1:-1:-1;110345:380:0:o;110583:28::-;110622:22;110647:20;;;:9;:20;;;;;;;;110622:45;;;;;;;;;;;;;;;;;;;;;;;110647:20;;110622:45;;110647:20;;110622:45;:22;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110701:7;:16;;;110685:7;:13;;;:32;110678:39;;;110345:380;;;:::o;101155:1673::-;101211:10;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101211:10:0;101305:1;101293:9;:13;:43;;;;;101323:13;;101310:9;:26;;101293:43;101271:114;;;;-1:-1:-1;;;101271:114:0;;10681:2:1;101271:114:0;;;10663:21:1;10720:2;10700:18;;;10693:30;-1:-1:-1;;;10739:18:1;;;10732:51;10800:18;;101271:114:0;10653:171:1;101271:114:0;101439:23;101465:20;;;:9;:20;;;;;101632:16;;;;101616:13;;;;:32;101608:71;;;;-1:-1:-1;;;101608:71:0;;12915:2:1;101608:71:0;;;12897:21:1;12954:2;12934:18;;;12927:30;12993:28;12973:18;;;12966:56;13039:18;;101608:71:0;12887:176:1;101608:71:0;101807:24;;101768:22;;101793:39;;;;;;-1:-1:-1;;;101793:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;101793:39:0;;101768:64;;101848:9;101843:288;101867:24;;101863:28;;101843:288;;;101913:27;101943:7;:17;;101961:1;101943:20;;;;;;-1:-1:-1;;;101943:20:0;;;;;;;;;;;;;;;;;;;101913:50;;;;;;;;;;;;;;;;;;;;;;;;;;;102005:8;:20;;;101995:6;101983:9;:7;:9::i;:::-;:18;;;;:::i;:::-;101982:43;101978:141;;;102072:8;:14;;;102060:9;:7;:9::i;:::-;:26;;;;:::i;:::-;102055:32;;:1;:32;:::i;:::-;102044:5;102050:1;102044:8;;;;;;-1:-1:-1;;;102044:8:0;;;;;;;;;;;;;;:43;;;;;101978:141;;;102118:1;102107:5;102113:1;102107:8;;;;;;-1:-1:-1;;;102107:8:0;;;;;;;;;;;;;;:12;;;;;101978:141;-1:-1:-1;101893:3:0;;;:::i;:::-;;;101843:288;;;-1:-1:-1;102227:14:0;;;:21;102187:26;;102216:33;;;;;;-1:-1:-1;;;102216:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102216:33:0;-1:-1:-1;102300:14:0;;;:21;102187:62;;-1:-1:-1;102260:23:0;;102286:36;;;;;;-1:-1:-1;;;102286:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102286:36:0;;102260:62;;102338:9;102333:198;102357:14;;;:21;102353:25;;102333:198;;;102441:7;:14;;102456:1;102441:17;;;;;;-1:-1:-1;;;102441:17:0;;;;;;;;;;;;;;;;;102431:6;102419:9;:7;:9::i;:::-;:18;;;;:::i;:::-;102418:40;102400:12;102413:1;102400:15;;;;;;-1:-1:-1;;;102400:15:0;;;;;;;;;;;;;;:58;;;;;;;;;;;102477:12;102490:1;102477:15;;;;;;-1:-1:-1;;;102477:15:0;;;;;;;;;;;;;;;102473:46;;;102506:13;:11;:13::i;:::-;102494:6;102501:1;102494:9;;;;;;-1:-1:-1;;;102494:9:0;;;;;;;;;;;;;;:25;;;;;102473:46;102380:3;;;:::i;:::-;;;102333:198;;;-1:-1:-1;102603:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;102737:13;;;:15;;;102583:17;102737:15;;;:::i;:::-;;;;-1:-1:-1;102814:6:0;;101155:1673;-1:-1:-1;;;;;;;101155:1673:0:o;86111:382::-;-1:-1:-1;;;;;86191:16:0;;86183:61;;;;-1:-1:-1;;;86183:61:0;;16038:2:1;86183:61:0;;;16020:21:1;;;16057:18;;;16050:30;16116:34;16096:18;;;16089:62;16168:18;;86183:61:0;16010:182:1;86183:61:0;84198:4;84222:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84222:16:0;:30;86255:58;;;;-1:-1:-1;;;86255:58:0;;12558:2:1;86255:58:0;;;12540:21:1;12597:2;12577:18;;;12570:30;12636;12616:18;;;12609:58;12684:18;;86255:58:0;12530:178:1;86255:58:0;86326:45;86355:1;86359:2;86363:7;86326:20;:45::i;:::-;-1:-1:-1;;;;;86384:13:0;;;;;;:9;:13;;;;;:18;;86401:1;;86384:13;:18;;86401:1;;86384:18;:::i;:::-;;;;-1:-1:-1;;86413:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;86413:21:0;-1:-1:-1;;;;;86413:21:0;;;;;;;;86452:33;;86413:16;;;86452:33;;86413:16;;86452:33;86111:382;;:::o;104396:637::-;104491:7;104541:20;;;:9;:20;;;;;;;;104516:45;;;;;;;;;;;;;;;;;;;;;104491:7;;104516:45;;;;104541:20;;104516:45;104491:7;;104516:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104576:7;:13;;;:23;;;104603:1;104576:28;104572:65;;;104613:13;;;:24;;104396:637;-1:-1:-1;;104396:637:0:o;104572:65::-;104652:7;:13;;;:23;;;104679:1;104652:28;104648:377;;;104697:9;104709:51;104728:7;:13;;;104743:7;:16;;;104709:18;:51::i;:::-;104933:13;;;;:24;;104908:22;;;;;104697:63;;-1:-1:-1;104843:133:0;;104697:63;;104908:49;;;:::i;:::-;104843:18;:133::i;:::-;104799:13;;;;:24;:177;;;;:::i;104648:377::-;105001:13;;;:24;;104396:637;-1:-1:-1;;104396:637:0:o;104648:377::-;104396:637;;;;:::o;83505:315::-;83662:28;83672:4;83678:2;83682:7;83662:9;:28::i;:::-;83709:48;83732:4;83738:2;83742:7;83751:5;83709:22;:48::i;:::-;83701:111;;;;-1:-1:-1;;;83701:111:0;;;;;;;:::i;100256:100::-;100308:13;100341:7;100334:14;;;;;:::i;74170:723::-;74226:13;74447:10;74443:53;;-1:-1:-1;;74474:10:0;;;;;;;;;;;;-1:-1:-1;;;74474:10:0;;;;;74170:723::o;74443:53::-;74521:5;74506:12;74562:78;74569:9;;74562:78;;74595:8;;;;:::i;:::-;;-1:-1:-1;74618:10:0;;-1:-1:-1;74626:2:0;74618:10;;:::i;:::-;;;74562:78;;;74650:19;74682:6;74672:17;;;;;;-1:-1:-1;;;74672:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74672:17:0;;74650:39;;74700:154;74707:10;;74700:154;;74734:11;74744:1;74734:11;;:::i;:::-;;-1:-1:-1;74803:10:0;74811:2;74803:5;:10;:::i;:::-;74790:24;;:2;:24;:::i;:::-;74777:39;;74760:6;74767;74760:14;;;;;;-1:-1:-1;;;74760:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;74760:56:0;;;;;;;;-1:-1:-1;74831:11:0;74840:2;74831:11;;:::i;:::-;;;74700:154;;49632:132;49690:14;49726:30;49751:1;49754;49726:24;:30::i;93967:589::-;-1:-1:-1;;;;;94173:18:0;;94169:187;;94208:40;94240:7;95383:10;:17;;95356:24;;;;:15;:24;;;;;:44;;;95411:24;;;;;;;;;;;;95279:164;94208:40;94169:187;;;94278:2;-1:-1:-1;;;;;94270:10:0;:4;-1:-1:-1;;;;;94270:10:0;;94266:90;;94297:47;94330:4;94336:7;94297:32;:47::i;:::-;-1:-1:-1;;;;;94370:16:0;;94366:183;;94403:45;94440:7;94403:36;:45::i;94366:183::-;94476:4;-1:-1:-1;;;;;94470:10:0;:2;-1:-1:-1;;;;;94470:10:0;;94466:83;;94497:40;94525:2;94529:7;94497:27;:40::i;103133:224::-;103265:10;;103236:57;;-1:-1:-1;;103253:10:0;7632:2:1;7628:15;7624:53;103236:57:0;;;7612:66:1;7694:12;;;7687:28;;;;103277:15:0;7731:12:1;;;7724:28;103170:7:0;;;;7768:12:1;;103236:57:0;;;-1:-1:-1;;103236:57:0;;;;;;;;;103226:68;;103236:57;103226:68;;;;103316:10;:12;;103226:68;;-1:-1:-1;103204:101:0;103316:12;;;:::i;:::-;;;;-1:-1:-1;103346:3:0;;103133:224;-1:-1:-1;;103133:224:0:o;102853:272::-;102894:7;102914:9;102938:3;102926:9;:7;:9::i;:::-;:15;;;;:::i;:::-;102914:27;;102952:9;102976:3;102964:9;:7;:9::i;:::-;:15;;;;:::i;:::-;102952:27;;102990:9;103014:3;103002:9;:7;:9::i;:::-;:15;;;;:::i;:::-;102990:27;;103098:2;103093:1;:7;;103087:1;103082;:6;;103077:1;:12;:24;103070:31;;;;;102853:272;:::o;31873:129::-;31931:14;31967:27;31982:1;29346:4;31992:1;31967:14;:27::i;88854:799::-;89009:4;-1:-1:-1;;;;;89030:13:0;;65996:20;66044:8;89026:620;;89066:72;;-1:-1:-1;;;89066:72:0;;-1:-1:-1;;;;;89066:36:0;;;;;:72;;73717:10;;89117:4;;89123:7;;89132:5;;89066:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89066:72:0;;;;;;;;-1:-1:-1;;89066:72:0;;;;;;;;;;;;:::i;:::-;;;89062:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89308:13:0;;89304:272;;89351:60;;-1:-1:-1;;;89351:60:0;;;;;;;:::i;89304:272::-;89526:6;89520:13;89511:6;89507:2;89503:15;89496:38;89062:529;-1:-1:-1;;;;;;89189:51:0;-1:-1:-1;;;89189:51:0;;-1:-1:-1;89182:58:0;;89026:620;-1:-1:-1;89630:4:0;88854:799;;;;;;:::o;22769:1188::-;22840:14;;;-1:-1:-1;;22959:1:0;22956;22949:20;22999:1;22996;22992:9;22983:18;;23051:5;23047:2;23044:13;23036:5;23032:2;23028:14;23024:34;23015:43;;;6411:4;23085:5;:14;23081:94;;23123:40;;-1:-1:-1;;;23123:40:0;;;;;21569:25:1;;;21542:18;;23123:40:0;21524:76:1;23081:94:0;23187:17;23215:19;23295:5;23292:1;23289;23282:19;23269:32;-1:-1:-1;;23344:18:0;23330:33;;23390:10;23386:157;;23473:11;6411:4;23456:5;:13;23455:29;23446:38;;23503:13;;;;;;23386:157;23799:11;23670:21;;;23666:39;23747:20;;;;23736:32;;;-1:-1:-1;;;23732:84:0;23637:202;;;;23862:13;23611:283;23589:350;;-1:-1:-1;23564:386:0;;;;:::o;96070:988::-;96336:22;96386:1;96361:22;96378:4;96361:16;:22::i;:::-;:26;;;;:::i;:::-;96398:18;96419:26;;;:17;:26;;;;;;96336:51;;-1:-1:-1;96552:28:0;;;96548:328;;-1:-1:-1;;;;;96619:18:0;;96597:19;96619:18;;;:12;:18;;;;;;;;:34;;;;;;;;;96670:30;;;;;;:44;;;96787:30;;:17;:30;;;;;:43;;;96548:328;-1:-1:-1;96972:26:0;;;;:17;:26;;;;;;;;96965:33;;;-1:-1:-1;;;;;97016:18:0;;;;;:12;:18;;;;;:34;;;;;;;97009:41;96070:988::o;97353:1079::-;97631:10;:17;97606:22;;97631:21;;97651:1;;97631:21;:::i;:::-;97663:18;97684:24;;;:15;:24;;;;;;98057:10;:26;;97606:46;;-1:-1:-1;97684:24:0;;97606:46;;98057:26;;;;-1:-1:-1;;;98057:26:0;;;;;;;;;;;;;;;;;98035:48;;98121:11;98096:10;98107;98096:22;;;;;;-1:-1:-1;;;98096:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;98201:28;;;:15;:28;;;;;;;:41;;;98373:24;;;;;98366:31;98408:10;:16;;;;;-1:-1:-1;;;98408:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;97353:1079;;;;:::o;94857:221::-;94942:14;94959:20;94976:2;94959:16;:20::i;:::-;-1:-1:-1;;;;;94990:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;95035:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;94857:221:0:o;17553:4067::-;17669:14;;;-1:-1:-1;;18165:1:0;18162;18155:20;18205:1;18202;18198:9;18189:18;;18257:5;18253:2;18250:13;18242:5;18238:2;18234:14;18230:34;18221:43;;;18351:5;18360:1;18351:10;18347:143;;;18424:11;18416:5;:19;;;-1:-1:-1;;;18416:19:0;;;;;;;;;;18407:28;;18465:13;;;;18347:143;18600:11;18591:5;:20;18587:103;;18635:43;;-1:-1:-1;;;18635:43:0;;;;;22058:25:1;;;22099:18;;;22092:34;;;22031:18;;18635:43:0;22013:119:1;18587:103:0;18932:17;19058:11;19055:1;19052;19045:25;20496:1;20477;19615;19600:12;;:16;;19585:32;;19726:25;;;;20477:15;;;20476:21;;20733;;;20729:25;;20718:36;20803:21;;;20799:25;;20788:36;20874:21;;;20870:25;;20859:36;20945:21;;;20941:25;;20930:36;21016:21;;;21012:25;;21001:36;21088:21;;;21084:25;;;21073:36;19567:15;19998;;;19994:29;;;19990:37;;;19167:20;;;19156:32;;;20120:15;;;;19211:21;;19833:19;;;;20111:24;;;;21558:15;;17553:4067;-1:-1:-1;;;;17553:4067:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:2;;177:1;174;167:12;111:2;63:124;;;:::o;192:196::-;251:6;304:2;292:9;283:7;279:23;275:32;272:2;;;325:6;317;310:22;272:2;353:29;372:9;353:29;:::i;393:270::-;461:6;469;522:2;510:9;501:7;497:23;493:32;490:2;;;543:6;535;528:22;490:2;571:29;590:9;571:29;:::i;:::-;561:39;;619:38;653:2;642:9;638:18;619:38;:::i;:::-;609:48;;480:183;;;;;:::o;668:338::-;745:6;753;761;814:2;802:9;793:7;789:23;785:32;782:2;;;835:6;827;820:22;782:2;863:29;882:9;863:29;:::i;:::-;853:39;;911:38;945:2;934:9;930:18;911:38;:::i;:::-;901:48;;996:2;985:9;981:18;968:32;958:42;;772:234;;;;;:::o;1011:1183::-;1106:6;1114;1122;1130;1183:3;1171:9;1162:7;1158:23;1154:33;1151:2;;;1205:6;1197;1190:22;1151:2;1233:29;1252:9;1233:29;:::i;:::-;1223:39;;1281:38;1315:2;1304:9;1300:18;1281:38;:::i;:::-;1271:48;;1366:2;1355:9;1351:18;1338:32;1328:42;;1421:2;1410:9;1406:18;1393:32;1444:18;1485:2;1477:6;1474:14;1471:2;;;1506:6;1498;1491:22;1471:2;1549:6;1538:9;1534:22;1524:32;;1594:7;1587:4;1583:2;1579:13;1575:27;1565:2;;1621:6;1613;1606:22;1565:2;1662;1649:16;1684:2;1680;1677:10;1674:2;;;1690:18;;:::i;:::-;1765:2;1759:9;1733:2;1819:13;;-1:-1:-1;;1815:22:1;;;1839:2;1811:31;1807:40;1795:53;;;1863:18;;;1883:22;;;1860:46;1857:2;;;1909:18;;:::i;:::-;1949:10;1945:2;1938:22;1984:2;1976:6;1969:18;2024:7;2019:2;2014;2010;2006:11;2002:20;1999:33;1996:2;;;2050:6;2042;2035:22;1996:2;2111;2106;2102;2098:11;2093:2;2085:6;2081:15;2068:46;2134:15;;;2151:2;2130:24;2123:40;;;;1141:1053;;;;-1:-1:-1;1141:1053:1;;-1:-1:-1;;;;1141:1053:1:o;2199:325::-;2264:6;2272;2325:2;2313:9;2304:7;2300:23;2296:32;2293:2;;;2346:6;2338;2331:22;2293:2;2374:29;2393:9;2374:29;:::i;:::-;2364:39;;2453:2;2442:9;2438:18;2425:32;2466:28;2488:5;2466:28;:::i;:::-;2513:5;2503:15;;;2283:241;;;;;:::o;2529:264::-;2597:6;2605;2658:2;2646:9;2637:7;2633:23;2629:32;2626:2;;;2679:6;2671;2664:22;2626:2;2707:29;2726:9;2707:29;:::i;:::-;2697:39;2783:2;2768:18;;;;2755:32;;-1:-1:-1;;;2616:177:1:o;2798:251::-;2854:6;2907:2;2895:9;2886:7;2882:23;2878:32;2875:2;;;2928:6;2920;2913:22;2875:2;2972:9;2959:23;2991:28;3013:5;2991:28;:::i;3054:255::-;3112:6;3165:2;3153:9;3144:7;3140:23;3136:32;3133:2;;;3186:6;3178;3171:22;3133:2;3230:9;3217:23;3249:30;3273:5;3249:30;:::i;3314:259::-;3383:6;3436:2;3424:9;3415:7;3411:23;3407:32;3404:2;;;3457:6;3449;3442:22;3404:2;3494:9;3488:16;3513:30;3537:5;3513:30;:::i;3578:642::-;3649:6;3657;3710:2;3698:9;3689:7;3685:23;3681:32;3678:2;;;3731:6;3723;3716:22;3678:2;3776:9;3763:23;3805:18;3846:2;3838:6;3835:14;3832:2;;;3867:6;3859;3852:22;3832:2;3910:6;3899:9;3895:22;3885:32;;3955:7;3948:4;3944:2;3940:13;3936:27;3926:2;;3982:6;3974;3967:22;3926:2;4027;4014:16;4053:2;4045:6;4042:14;4039:2;;;4074:6;4066;4059:22;4039:2;4124:7;4119:2;4110:6;4106:2;4102:15;4098:24;4095:37;4092:2;;;4150:6;4142;4135:22;4092:2;4186;4178:11;;;;;4208:6;;-1:-1:-1;3668:552:1;;-1:-1:-1;;;;3668:552:1:o;4225:415::-;4309:6;4362:2;4350:9;4341:7;4337:23;4333:32;4330:2;;;4383:6;4375;4368:22;4330:2;4428:9;4415:23;4461:18;4453:6;4450:30;4447:2;;;4498:6;4490;4483:22;4447:2;4526:22;;4582:3;4564:16;;;4560:26;4557:2;;;4604:6;4596;4589:22;4645:190;4704:6;4757:2;4745:9;4736:7;4732:23;4728:32;4725:2;;;4778:6;4770;4763:22;4725:2;-1:-1:-1;4806:23:1;;4715:120;-1:-1:-1;4715:120:1:o;4840:264::-;4908:6;4916;4969:2;4957:9;4948:7;4944:23;4940:32;4937:2;;;4990:6;4982;4975:22;4937:2;5031:9;5018:23;5008:33;;5060:38;5094:2;5083:9;5079:18;5060:38;:::i;5109:479::-;5198:6;5206;5259:2;5247:9;5238:7;5234:23;5230:32;5227:2;;;5280:6;5272;5265:22;5227:2;5321:9;5308:23;5298:33;;5382:2;5371:9;5367:18;5354:32;5409:18;5401:6;5398:30;5395:2;;;5446:6;5438;5431:22;5395:2;5474:22;;5530:3;5512:16;;;5508:26;5505:2;;;5552:6;5544;5537:22;5593:357;5688:6;5696;5740:9;5731:7;5727:23;5770:3;5766:2;5762:12;5759:2;;;5792:6;5784;5777:22;5759:2;5820:23;;;-1:-1:-1;5877:2:1;-1:-1:-1;;5859:16:1;;5855:25;5852:2;;;5898:6;5890;5883:22;5852:2;;5941;5930:9;5926:18;5916:28;;5707:243;;;;;:::o;5955:258::-;6023:6;6031;6084:2;6072:9;6063:7;6059:23;6055:32;6052:2;;;6105:6;6097;6090:22;6052:2;-1:-1:-1;;6133:23:1;;;6203:2;6188:18;;;6175:32;;-1:-1:-1;6042:171:1:o;6218:289::-;6275:6;6328:2;6316:9;6307:7;6303:23;6299:32;6296:2;;;6349:6;6341;6334:22;6296:2;6393:9;6380:23;6443:4;6436:5;6432:16;6425:5;6422:27;6412:2;;6468:6;6460;6453:22;6512:437;6565:3;6603:5;6597:12;6630:6;6625:3;6618:19;6656:4;6685:2;6680:3;6676:12;6669:19;;6722:2;6715:5;6711:14;6743:3;6755:169;6769:6;6766:1;6763:13;6755:169;;;6830:13;;6818:26;;6864:12;;;;6899:15;;;;6791:1;6784:9;6755:169;;;-1:-1:-1;6940:3:1;;6573:376;-1:-1:-1;;;;;6573:376:1:o;6954:257::-;6995:3;7033:5;7027:12;7060:6;7055:3;7048:19;7076:63;7132:6;7125:4;7120:3;7116:14;7109:4;7102:5;7098:16;7076:63;:::i;:::-;7193:2;7172:15;-1:-1:-1;;7168:29:1;7159:39;;;;7200:4;7155:50;;7003:208;-1:-1:-1;;7003:208:1:o;7791:470::-;7970:3;8008:6;8002:13;8024:53;8070:6;8065:3;8058:4;8050:6;8046:17;8024:53;:::i;:::-;8140:13;;8099:16;;;;8162:57;8140:13;8099:16;8196:4;8184:17;;8162:57;:::i;:::-;8235:20;;7978:283;-1:-1:-1;;;;7978:283:1:o;8474:488::-;-1:-1:-1;;;;;8743:15:1;;;8725:34;;8795:15;;8790:2;8775:18;;8768:43;8842:2;8827:18;;8820:34;;;8890:3;8885:2;8870:18;;8863:31;;;8668:4;;8911:45;;8936:19;;8928:6;8911:45;:::i;:::-;8903:53;8677:285;-1:-1:-1;;;;;;8677:285:1:o;8967:261::-;9146:2;9135:9;9128:21;9109:4;9166:56;9218:2;9207:9;9203:18;9195:6;9166:56;:::i;9852:219::-;10001:2;9990:9;9983:21;9964:4;10021:44;10061:2;10050:9;10046:18;10038:6;10021:44;:::i;10076:398::-;10278:2;10260:21;;;10317:2;10297:18;;;10290:30;10356:34;10351:2;10336:18;;10329:62;-1:-1:-1;;;10422:2:1;10407:18;;10400:32;10464:3;10449:19;;10250:224::o;11241:414::-;11443:2;11425:21;;;11482:2;11462:18;;;11455:30;11521:34;11516:2;11501:18;;11494:62;-1:-1:-1;;;11587:2:1;11572:18;;11565:48;11645:3;11630:19;;11415:240::o;18182:413::-;18384:2;18366:21;;;18423:2;18403:18;;;18396:30;18462:34;18457:2;18442:18;;18435:62;-1:-1:-1;;;18528:2:1;18513:18;;18506:47;18585:3;18570:19;;18356:239::o;20013:1152::-;20143:4;20172:2;20201;20190:9;20183:21;20246:6;20240:13;20235:2;20224:9;20220:18;20213:41;20301:2;20293:6;20289:15;20283:22;20341:4;20336:2;20325:9;20321:18;20314:32;20369:63;20427:3;20416:9;20412:19;20398:12;20369:63;:::i;:::-;20481:2;20469:15;;20463:22;-1:-1:-1;;20551:22:1;;;20547:31;;20542:2;20527:18;;20520:59;20628:21;;20658:22;;;20734:23;;;;-1:-1:-1;20775:4:1;;20504:7;;20696:15;;;;20788:185;20802:6;20799:1;20796:13;20788:185;;;20877:13;;20870:21;20863:29;20851:42;;20948:15;;;;20824:1;20817:9;;;;;20913:12;;;;20788:185;;;20792:3;21022:2;21014:6;21010:15;21004:22;20982:44;;21089:2;21077:9;21072:3;21068:19;21064:28;21057:4;21046:9;21042:20;21035:58;21110:49;21155:3;21139:14;21110:49;:::i;:::-;21102:57;20152:1013;-1:-1:-1;;;;;;;;20152:1013:1:o;21170:248::-;7291:12;;7279:25;;7353:4;7342:16;;;7336:23;7320:14;;;7313:47;7409:4;7398:16;;;7392:23;7376:14;;;7369:47;21354:2;21339:18;;21366:46;7269:153;22137:391;22390:25;;;22446:2;22431:18;;22424:34;;;22377:3;22362:19;;22467:55;22518:2;22503:18;;22495:6;7291:12;;7279:25;;7353:4;7342:16;;;7336:23;7320:14;;;7313:47;7409:4;7398:16;;;7392:23;7376:14;;7369:47;7269:153;22722:544;22802:4;22808:6;22868:11;22855:25;22962:2;22958:7;22947:8;22931:14;22927:29;22923:43;22903:18;22899:68;22889:2;;22984:4;22978;22971:18;22889:2;23014:33;;23066:20;;;-1:-1:-1;23109:18:1;23098:30;;23095:2;;;23144:4;23138;23131:18;23095:2;23180:4;23168:17;;-1:-1:-1;23231:1:1;23227:14;;;23211;23207:35;23197:46;;23194:2;;;23256:1;23253;23246:12;23194:2;22819:447;;;;;:::o;23411:128::-;23451:3;23482:1;23478:6;23475:1;23472:13;23469:2;;;23488:18;;:::i;:::-;-1:-1:-1;23524:9:1;;23459:80::o;23544:120::-;23584:1;23610;23600:2;;23615:18;;:::i;:::-;-1:-1:-1;23649:9:1;;23590:74::o;23669:168::-;23709:7;23775:1;23771;23767:6;23763:14;23760:1;23757:21;23752:1;23745:9;23738:17;23734:45;23731:2;;;23782:18;;:::i;:::-;-1:-1:-1;23822:9:1;;23721:116::o;23842:125::-;23882:4;23910:1;23907;23904:8;23901:2;;;23915:18;;:::i;:::-;-1:-1:-1;23952:9:1;;23891:76::o;23972:144::-;24032:78;24050:3;24043:5;24040:14;24032:78;;;24106:1;24092:16;;24077:1;24066:13;24032:78;;;24022:94;;:::o;24121:1351::-;-1:-1:-1;;;24237:3:1;24234:29;24231:2;;;24266:18;;:::i;:::-;24315:4;24309:11;24342:3;24336:4;24329:17;24366:6;24361:3;24358:15;24355:2;;;24406:4;24403:1;24396:15;24449:4;24446:1;24436:18;24512:2;24507:3;24503:12;24500:1;24496:20;24490:4;24486:31;24549:2;24544:3;24540:12;24582:2;24575:10;24565:2;;24631:1;24627:6;24677:2;24664:11;24660:20;24750:2;24744:9;24739:2;24733;24727:4;24723:13;24720:1;24716:21;24712:30;24708:46;24704:2;24697:58;;;24565:2;;24782:73;24849:2;24841:6;24837:15;24834:1;24830:23;24824:4;24820:34;24807:11;24782:73;:::i;:::-;;;24355:2;-1:-1:-1;23326:4:1;23345:17;;;23395:4;23379:21;;24888:5;;23326:4;25035:431;25049:3;25046:1;25043:10;25035:431;;;25095:95;25157:32;25182:6;25157:32;:::i;:::-;32549:11;;32636:3;32590:1;32586:14;;;32621:19;;;32673:9;;32665:18;;;32711:13;;32704:21;32689:37;;32685:48;32662:72;32649:86;;32529:212;25095:95;25225:2;25217:6;25213:15;25203:25;;25251:1;25301:2;25286:13;25282:22;25265:39;;25338:2;25323:13;25320:21;25317:2;;;25422:20;;;;25389:1;;-1:-1:-1;25317:2:1;-1:-1:-1;25068:1:1;25061:9;25035:431;;;25039:3;;;;24221:1251;;;:::o;25477:1269::-;-1:-1:-1;;;25631:3:1;25628:29;25625:2;;;25660:18;;:::i;:::-;25709:4;25703:11;25736:3;25730:4;25723:17;25760:6;25755:3;25752:15;25749:2;;;-1:-1:-1;;;;;25817:1:1;25867:14;;;25859:23;;25856:2;;;25885:18;;:::i;:::-;25937:2;25932:3;25929:11;25925:2;25921:20;25918:2;;;25944:18;;:::i;:::-;25984:1;25977:15;;;26030:4;26017:18;;26120:12;;;26110:23;;;-1:-1:-1;26068:15:1;;;26058:26;26146:211;26164:2;26157:5;26154:13;26146:211;;;33030:1;33017:15;;33030:1;26328:14;;;33017:15;26190:1;26183:5;26179:13;26170:22;;26146:211;;;26150:3;;;25749:2;-1:-1:-1;23326:4:1;23345:17;;;23395:4;23379:21;;26390:5;;26494:246;26508:3;26505:1;26502:10;26494:246;;;32866:19;;32853:33;;32940:2;32929:14;;32916:28;32912:1;32902:12;;32895:50;26680:2;26668:15;;;;;26728:1;26711:19;;;;;26527:1;26520:9;26494:246;;;26498:3;;;25615:1131;;;:::o;26751:770::-;-1:-1:-1;;;26873:3:1;26870:29;26867:2;;;26902:18;;:::i;:::-;26951:4;26945:11;26978:3;26972:4;26965:17;27002:6;26997:3;26994:15;26991:2;;;27042:4;27039:1;27032:15;27085:4;27082:1;27072:18;27103:59;27154:6;27148:4;27144:17;27138:3;27132:4;27128:14;27103:59;:::i;:::-;;26991:2;;27195:5;27219:4;27216:1;27209:15;27243:4;27288:2;27285:1;27275:16;27309:1;27319:196;27333:3;27330:1;27327:10;27319:196;;;27399:20;;27379:41;;27443:15;;;;27503:1;27486:19;;;;27345:9;27319:196;;27526:258;27598:1;27608:113;27622:6;27619:1;27616:13;27608:113;;;27698:11;;;27692:18;27679:11;;;27672:39;27644:2;27637:10;27608:113;;;27739:6;27736:1;27733:13;27730:2;;;-1:-1:-1;;27774:1:1;27756:16;;27749:27;27579:205::o;28061:380::-;28140:1;28136:12;;;;28183;;;28204:2;;28258:4;28250:6;28246:17;28236:27;;28204:2;28311;28303:6;28300:14;28280:18;28277:38;28274:2;;;28357:10;28352:3;28348:20;28345:1;28338:31;28392:4;28389:1;28382:15;28420:4;28417:1;28410:15;28446:135;28485:3;-1:-1:-1;;28506:17:1;;28503:2;;;28526:18;;:::i;:::-;-1:-1:-1;28573:1:1;28562:13;;28493:88::o;28586:175::-;28623:3;28667:4;28660:5;28656:16;28696:4;28687:7;28684:17;28681:2;;;28704:18;;:::i;:::-;28753:1;28740:15;;28631:130;-1:-1:-1;;28631:130:1:o;28766:112::-;28798:1;28824;28814:2;;28829:18;;:::i;:::-;-1:-1:-1;28863:9:1;;28804:74::o;28883:127::-;28944:10;28939:3;28935:20;28932:1;28925:31;28975:4;28972:1;28965:15;28999:4;28996:1;28989:15;29015:127;29076:10;29071:3;29067:20;29064:1;29057:31;29107:4;29104:1;29097:15;29131:4;29128:1;29121:15;29147:127;29208:10;29203:3;29199:20;29196:1;29189:31;29239:4;29236:1;29229:15;29263:4;29260:1;29253:15;29279:170;29321:11;29373:3;29360:17;29386:28;29408:5;29386:28;:::i;29454:1157::-;29626:5;29613:19;29711:2;29707:7;29699:5;29683:14;29679:26;29675:40;29655:18;29651:65;29641:2;;29730:1;29727;29720:12;29641:2;29755:30;;29808:18;;29849;29838:30;;29835:2;;;29881:1;29878;29871:12;29835:2;29918:4;29912;29908:15;29894:29;;29974:6;29971:1;29967:14;29951;29947:35;29939:6;29935:48;29932:2;;;29996:1;29993;29986:12;29932:2;30009:128;30130:6;30122;30116:4;30009:128;:::i;:::-;;;30180:69;30243:4;30236:5;30232:16;30225:5;30180:69;:::i;:::-;30258:116;30360:13;30347:11;30343:1;30337:4;30333:12;30258:116;:::i;:::-;-1:-1:-1;;30428:2:1;30417:14;;30404:28;30400:1;30390:12;;30383:50;30487:2;30476:14;;30463:28;30459:1;30449:12;;30442:50;30600:3;30589:15;;27912:19;30585:1;30575:12;;27899:33;27975:14;;;27962:28;27948:12;;;27941:50;28034:14;;;28021:28;28007:12;;;28000:50;24022:94;;:::o;30616:1541::-;30767:5;30754:19;30748:4;30741:33;30793:1;30831:2;30825:4;30821:13;30853:2;30898:67;30961:2;30954:5;30950:14;30943:5;30898:67;:::i;:::-;-1:-1:-1;;;30980:13:1;30977:39;30974:2;;;31019:18;;:::i;:::-;31068:10;31062:17;31107:13;31095:10;31088:33;31151:6;31136:13;31133:25;31130:2;;;31191:10;31188:1;31181:21;31240:2;31237:1;31227:16;31256:69;31317:6;31311:4;31307:17;31291:13;31285:4;31281:24;31256:69;:::i;:::-;;31130:2;-1:-1:-1;31385:1:1;31378:21;;;31427:16;;;;31471:208;31485:13;31482:1;31479:20;31471:208;;;31562:20;;31542:41;;31649:20;;;;31606:15;;;;31507:10;;31471:208;;;31475:3;;;;;;31724:67;31787:2;31780:5;31776:14;31769:5;31724:67;:::i;:::-;31800:112;31898:13;31883;31879:1;31873:4;31869:12;31800:112;:::i;:::-;;;31957:67;32020:2;32013:5;32009:14;32002:5;31957:67;:::i;:::-;32033:118;32137:13;32122;32118:1;32112:4;32108:12;32033:118;:::i;33039:::-;33125:5;33118:13;33111:21;33104:5;33101:32;33091:2;;33147:1;33144;33137:12;33162:131;-1:-1:-1;;;;;;33236:32:1;;33226:43;;33216:2;;33283:1;33280;33273:12

Swarm Source

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