{
    "env": {
        "browser": true,
        "es6": true,
        "node": true,
        "jest/globals": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "prettier"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint",
        "jest",
        "react",
        "react-hooks"
    ],
    "settings": {
        "react": {
            "version": "16.8.6"
        }
    },
    "globals": {
        "Hammer": true,
        "Ya": true
    },
    "overrides": [
        {
            "files": [
                "**/*.ts",
                "**/*.tsx"
            ],
            "rules": {
                "no-dupe-class-members": "off"
            }
        },
        {
            "files": [
                "**/*.js"
            ],
            "rules": {
                "@typescript-eslint/explicit-function-return-type": "off"
            }
        }
    ],
    "rules": {
        "no-prototype-builtins": "off",
        "@typescript-eslint/indent": "off",
        "@typescript-eslint/no-var-requires": "off",
        "@typescript-eslint/camelcase": "off",
        "@typescript-eslint/no-use-before-define": "off",
        "@typescript-eslint/no-explicit-any": "off",
        "@typescript-eslint/no-empty-interface": "off",
        "@typescript-eslint/explicit-member-accessibility": "off",
        "@typescript-eslint/explicit-function-return-type": [
            "error",
            {
                "allowExpressions": true,
                "allowTypedFunctionExpressions": true
            }
        ],
        "@typescript-eslint/interface-name-prefix": [
            "error",
            "always"
        ],
        "@typescript-eslint/semi": [
            "error"
        ],
        // TODO: Включить при переходе на eslint 5
        //"no-async-promise-executor": [
        //    "error"
        //],
        "@typescript-eslint/no-unused-vars": "error",
        "@typescript-eslint/no-object-literal-type-assertion": "off",
        "react-hooks/exhaustive-deps": "error",
        "no-undef": "error",
        "no-return-assign": [
            "off"
        ],
        "no-sequences": "off",
        "no-unused-vars": "off", // используем @typescript-eslint/no-unused-vars
        "no-console": "error",
        "no-await-in-loop": [
            "off"
        ],
        "no-template-curly-in-string": [
            "error"
        ],
        "valid-jsdoc": "off",
        "array-callback-return": [
            "error"
        ],
        "block-scoped-var": [
            "error"
        ],
        "curly": [
            "error",
            "all"
        ],
        "dot-location": [
            "error",
            "property"
        ],
        "dot-notation": [
            "error"
        ],
        "eqeqeq": [
            "error",
            "always"
        ],
        "guard-for-in": [
            "error"
        ],
        // TODO: Включить при переходе на eslint 5
        //"max-classes-per-file": [
        //    "error",
        //    1
        //],
        "no-alert": [
            "error"
        ],
        "no-caller": [
            "error"
        ],
        "no-div-regex": [
            "error"
        ],
        "no-else-return": [
            "error",
            {
                "allowElseIf": false
            }
        ],
        "no-eval": [
            "error"
        ],
        "no-extend-native": [
            "error"
        ],
        "no-extra-bind": [
            "error"
        ],
        "no-fallthrough": [
            "error"
        ],
        "no-floating-decimal": [
            "error"
        ],
        "no-implicit-coercion": [
            "error"
        ],
        "no-implied-eval": [
            "error"
        ],
        // TODO: Включить при переходе на eslint 5
        //"no-invalid-this": [
        //    "error"
        //],
        "no-iterator": [
            "error"
        ],
        "no-irregular-whitespace": [
            "error",
            {
                "skipComments": true,
                "skipStrings": true,
                "skipTemplates": true
            }
        ],
        "no-lone-blocks": [
            "error"
        ],
        "no-loop-func": [
            "error"
        ],
        "no-multi-spaces": [
            "error"
        ],
        "no-multi-str": [
            "error"
        ],
        "no-new-func": [
            "error"
        ],
        "no-new-wrappers": [
            "error"
        ],
        "no-octal-escape": [
            "error"
        ],
        "no-proto": [
            "error"
        ],
        "no-redeclare": [
            "error",
            {
                "builtinGlobals": true
            }
        ],
        "no-return-await": [
            "error"
        ],
        "no-script-url": [
            "error"
        ],
        "no-self-assign": [
            "error"
        ],
        "no-self-compare": [
            "error"
        ],
        "no-throw-literal": [
            "error"
        ],
        "no-unmodified-loop-condition": [
            "error"
        ],
        "no-unused-expressions": "off",
        "no-useless-call": [
            "error"
        ],
        "no-useless-concat": [
            "error"
        ],
        "no-void": [
            "error"
        ],
        "no-with": [
            "error"
        ],
        "radix": [
            "error",
            "always"
        ],
        "require-await": [
            "error"
        ],
        "wrap-iife": [
            "error",
            "inside"
        ],
        "yoda": [
            "error"
        ],
        "no-label-var": [
            "error"
        ],
        "no-shadow": [
            "error",
            {
                "hoist": "all"
            }
        ],
        "no-shadow-restricted-names": [
            "error"
        ],
        "no-undef-init": [
            "error"
        ],
        "no-use-before-define": [
            "error",
            {
                "variables": true,
                "functions": false,
                "classes": true
            }
        ],
        "no-path-concat": [
            "error"
        ],
        /* Stylistic */
        "array-bracket-newline": [
            "error",
            "consistent"
        ],
        "array-bracket-spacing": [
            "error",
            "never"
        ],
        "block-spacing": [
            "error"
        ],
        "comma-spacing": [
            "error",
            {
                "before": false,
                "after": true
            }
        ],
        "comma-style": [
            "error",
            "last"
        ],
        "computed-property-spacing": [
            "error",
            "never"
        ],
        "consistent-this": [
            "error",
            "_this"
        ],
        "eol-last": [
            "error",
            "always"
        ],
        "func-call-spacing": [
            "error",
            "never"
        ],
        "jsx-quotes": [
            "error",
            "prefer-double"
        ],
        "key-spacing": [
            "error",
            {
                "beforeColon": false,
                "afterColon": true,
                "mode": "strict"
            }
        ],
        "keyword-spacing": [
            "error",
            {
                "before": true,
                "after": true
            }
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "lines-between-class-members": [
            "error",
            "always",
            {
                "exceptAfterSingleLine": true
            }
        ],
        "new-cap": [
            "error",
            {
                "newIsCap": true,
                "capIsNew": true,
                "properties": false,
                "capIsNewExceptions": [
                    "B",
                    "PHONE_INPUT_MASK",
                    "RUSSIAN_PHONE_INPUT_MASK",
                    "Loadable"
                ]
            }
        ],
        "new-parens": [
            "error"
        ],
        "no-array-constructor": [
            "error"
        ],
        "no-bitwise": [
            "error"
        ],
        "no-lonely-if": [
            "error"
        ],
        "no-multiple-empty-lines": [
            "error",
            {
                "max": 2,
                "maxEOF": 1,
                "maxBOF": 0
            }
        ],
        "no-new-object": [
            "error"
        ],
        "no-tabs": [
            "error"
        ],
        "no-trailing-spaces": [
            "error"
        ],
        "no-unneeded-ternary": [
            "error",
            {
                "defaultAssignment": false
            }
        ],
        "no-whitespace-before-property": [
            "error"
        ],
        "object-curly-newline": [
            "error",
            {
                "consistent": true
            }
        ],
        "one-var": [
            "error",
            "never"
        ],
        "operator-assignment": [
            "error",
            "always"
        ],
        "padding-line-between-statements": [
            "error",
            {
                "blankLine": "always",
                "prev": "*",
                "next": "return"
            },
            {
                "blankLine": "always",
                "prev": "block-like",
                "next": "*"
            },
            {
                "blankLine": "always",
                "prev": "*",
                "next": "block-like"
            },
            {
                "blankLine": "always",
                "prev": "*",
                "next": "case"
            },
            {
                "blankLine": "never",
                "prev": "case",
                "next": "case"
            },
            {
                "blankLine": "always",
                "prev": "block-like",
                "next": "case"
            },
            {
                "blankLine": "never",
                "prev": "break",
                "next": "case"
            },
            {
                "blankLine": "always",
                "prev": "*",
                "next": "default"
            },
            {
                "blankLine": "always",
                "prev": "function",
                "next": "*"
            },
            {
                "blankLine": "always",
                "prev": "*",
                "next": "function"
            },
            {
                "blankLine": "always",
                "prev": "export",
                "next": "*"
            },
            {
                "blankLine": "any",
                "prev": "*",
                "next": "export"
            },
            {
                "blankLine": "always",
                "prev": "import",
                "next": "*"
            },
            {
                "blankLine": "any",
                "prev": "import",
                "next": "import"
            },
            {
                "blankLine": "always",
                "prev": [
                    "const",
                    "let",
                    "var"
                ],
                "next": "*"
            },
            {
                "blankLine": "any",
                "prev": [
                    "const",
                    "let",
                    "var"
                ],
                "next": [
                    "const",
                    "let",
                    "var"
                ]
            }
        ],
        "quote-props": [
            "error",
            "as-needed"
        ],
        "semi": "off", // используем @typescript-eslint/semi
        "semi-spacing": [
            "error",
            {
                "before": false,
                "after": true
            }
        ],
        "semi-style": [
            "error",
            "last"
        ],
        "space-before-blocks": [
            "error"
        ],
        "space-in-parens": [
            "error",
            "never"
        ],
        "space-infix-ops": [
            "error"
        ],
        "space-unary-ops": [
            "error"
        ],
        "spaced-comment": [
            "error"
        ],
        "switch-colon-spacing": [
            "error",
            {
                "after": true,
                "before": false
            }
        ],
        "template-tag-spacing": [
            "error",
            "never"
        ],
        "unicode-bom": [
            "error"
        ],
        /* ECMAScript 6 */
        "arrow-spacing": [
            "error",
            {
                "before": true,
                "after": true
            }
        ],
        "generator-star-spacing": [
            "error",
            {
                "before": true,
                "after": false
            }
        ],
        "no-duplicate-imports": [
            "error",
            {
                "includeExports": true
            }
        ],
        "no-useless-computed-key": [
            "error"
        ],
        "no-useless-rename": [
            "error"
        ],
        "no-var": [
            "error"
        ],
        "object-shorthand": [
            "error",
            "always"
        ],
        "prefer-arrow-callback": [
            "error"
        ],
        "prefer-const": [
            "error"
        ],
        "prefer-rest-params": [
            "error"
        ],
        "prefer-spread": [
            "error"
        ],
        "prefer-template": [
            "error"
        ],
        "rest-spread-spacing": [
            "error",
            "never"
        ],
        "template-curly-spacing": [
            "error"
        ],
        "yield-star-spacing": [
            "error",
            {
                "before": true,
                "after": false
            }
        ],
        /* Jest */
        // TODO: необходимо решить, что использовать (или забить)
        //"jest/consistent-test-it": [
        //    "error",
        //    { "fn": "test" }
        //],
        // TODO: почему-то не работает
        //"jest/expect-expect": [
        //    "error"
        //],
        "jest/no-disabled-tests": [
            "error"
        ],
        "jest/no-focused-tests": [
            "error"
        ],
        "jest/no-identical-title": [
            "error"
        ],
        "jest/no-jasmine-globals": [
            "error"
        ],
        "jest/no-jest-import": [
            "error"
        ],
        "jest/no-test-prefixes": [
            "error"
        ],
        // TODO: почему-то не работает
        //"jest/no-test-return-statement": [
        //    "error"
        //],
        "jest/valid-describe": [
            "error"
        ],
        "jest/valid-expect-in-promise": [
            "error"
        ],
        "jest/valid-expect": [
            "error"
        ],
        /* React */
        // TODO: плохо работает, если пропс устанавливается динамически (ex. <button type={type}>text</button>)
        //"react/button-has-type": [
        //    "error"
        //],
        "react/default-props-match-prop-types": [
            "error"
        ],
        "react/no-children-prop": [
            "error"
        ],
        "react/no-danger-with-children": [
            "error"
        ],
        "react/no-deprecated": [
            "warn"
        ],
        "react/no-direct-mutation-state": [
            "error"
        ],
        "react/no-find-dom-node": [
            "warn"
        ],
        "react/no-redundant-should-component-update": [
            "error"
        ],
        "react/no-render-return-value": [
            "error"
        ],
        "react/no-typos": [
            "error"
        ],
        "react/no-string-refs": [
            "error"
        ],
        "react/no-this-in-sfc": [
            "error"
        ],
        "react/no-unsafe": [
            "error"
        ],
        "react/no-unused-state": [
            "error"
        ],
        "react/no-will-update-set-state": [
            "error",
            "disallow-in-func"
        ],
        "react/prefer-es6-class": [
            "error",
            "always"
        ],
        "react/prop-types": [
            "off"
        ],
        "react/react-in-jsx-scope": [
            "error"
        ],
        "react/require-render-return": [
            "error"
        ],
        "react/self-closing-comp": [
            "error",
            {
                "component": true,
                "html": true
            }
        ],
        "react/sort-comp": [
            "error",
            {
                "order": [
                    "type-annotations",
                    "static-methods",
                    "instance-variables",
                    "lifecycle",
                    "/^on.+$/",
                    "/^handle.+$/",
                    "everything-else",
                    "render"
                ]
            }
        ],
        "react/style-prop-object": [
            "error"
        ],
        "react/void-dom-elements-no-children": [
            "error"
        ],
        "react/jsx-boolean-value": [
            "error",
            "never"
        ],
        "react/jsx-closing-bracket-location": [
            "error",
            "line-aligned"
        ],
        "react/jsx-closing-tag-location": [
            "error"
        ],
        "react/jsx-curly-spacing": [
            "error",
            {
                "when": "never"
            }
        ],
        "react/jsx-equals-spacing": [
            "error",
            "never"
        ],
        "react/jsx-first-prop-new-line": [
            "error",
            "multiline"
        ],
        "react/jsx-handler-names": [
            "error",
            {
                "eventHandlerPrefix": "on"
            }
        ],
        "react/jsx-key": [
            "error"
        ],
        "react/jsx-no-bind": [
            "error"
        ],
        "react/jsx-no-duplicate-props": [
            "error"
        ],
        "react/jsx-pascal-case": [
            "error"
        ],
        "react/jsx-uses-react": [
            "error"
        ],
        "react/jsx-uses-vars": [
            "error"
        ],
        "react/jsx-curly-brace-presence": [
            "error",
            {
                "props": "never",
                "children": "never"
            }
        ],
        "react/jsx-tag-spacing": [
            "error",
            {
                "closingSlash": "never",
                "beforeSelfClosing": "always",
                "afterOpening": "never",
                "beforeClosing": "never"
            }
        ]
    }
}