diff --git a/.eslintrc.js b/.eslintrc.js
index 39fa533ba8c0e0d2773bd8d5721ce49b395ce7d8..2cbc020ed844954fee7f93bfafc07509dd6a9352 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,4 +1,12 @@
 module.exports = {
+  plugins: [
+    '@typescript-eslint',
+    'react',
+    'react-hooks',
+    'jest',
+    'jsx-a11y',
+    '@eslint-react/eslint-plugin',
+  ],
   extends: [
     'eslint:recommended',
     'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
@@ -15,6 +23,8 @@ module.exports = {
         'plugin:@typescript-eslint/recommended',
         // Stylistic rule configurations, for consistent and predictable syntax usage
         'plugin:@typescript-eslint/stylistic-type-checked',
+        // Eslint React plugin
+        'plugin:@eslint-react/recommended-legacy',
       ],
       files: ['**/*.{ts,tsx}'],
       parserOptions: {
@@ -61,6 +71,13 @@ module.exports = {
         // Note: you must disable the base rule as it can report incorrect errors
         'require-await': 'off',
         '@typescript-eslint/require-await': 'error',
+
+        // disable recommandations
+        '@eslint-react/hooks-extra/no-redundant-custom-hook': 0, // great rule but should not be run in tests files
+        '@eslint-react/hooks-extra/no-direct-set-state-in-use-effect': 0, // to enable in another MR will have a lot of impact
+        '@eslint-react/dom/no-dangerously-set-innerhtml': 0, // used for for injecting html tags
+        '@eslint-react/no-array-index-key': 0,
+        '@eslint-react/no-unused-class-component-members': 0, // disabled for ".d.ts" files
       },
     },
     {
@@ -71,7 +88,6 @@ module.exports = {
       },
     },
   ],
-  plugins: ['@typescript-eslint', 'react', 'react-hooks', 'jest', 'jsx-a11y'],
   parser: '@typescript-eslint/parser', // Specifies the ESLint parser
   parserOptions: {
     ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
diff --git a/package.json b/package.json
index d3b262b585fd322aa9ab7792726ebea7ba43934e..3ff8e0532fc5d2cc90b8f34d84a623517d0eab76 100644
--- a/package.json
+++ b/package.json
@@ -80,6 +80,7 @@
   },
   "devDependencies": {
     "@babel/preset-typescript": "^7.7.4",
+    "@eslint-react/eslint-plugin": "^1.14.3",
     "@testing-library/dom": "^9.3.3",
     "@testing-library/jest-dom": "^6.4.2",
     "@testing-library/react": "^14.3.0",
diff --git a/src/components/Challenge/ChallengeCard/ChallengeCard.tsx b/src/components/Challenge/ChallengeCard/ChallengeCard.tsx
index 70d193f59831201cc7d75240731a9bc15e23223e..004413f1484d92596ecb4dc5248103cff31444df 100644
--- a/src/components/Challenge/ChallengeCard/ChallengeCard.tsx
+++ b/src/components/Challenge/ChallengeCard/ChallengeCard.tsx
@@ -46,6 +46,7 @@ const ChallengeCard = ({
 
   return (
     <button
+      type="button"
       aria-label={t('challenge.card.goto')}
       onClick={() => moveToSlide(index)}
       className={indexSlider === index ? 'slide active' : 'slide inactive'}
diff --git a/src/components/Challenge/ChallengeCard/__snapshots__/ChallengeCard.spec.tsx.snap b/src/components/Challenge/ChallengeCard/__snapshots__/ChallengeCard.spec.tsx.snap
index 2500a582f326dd82eda13780f8013d711a194b2a..32fa2966106a328f1e420f8dd02226d97fd08af1 100644
--- a/src/components/Challenge/ChallengeCard/__snapshots__/ChallengeCard.spec.tsx.snap
+++ b/src/components/Challenge/ChallengeCard/__snapshots__/ChallengeCard.spec.tsx.snap
@@ -6,6 +6,7 @@ exports[`ChallengeCard component should be rendered correctly 1`] = `
     aria-label="challenge.card.goto"
     class="slide active"
     style="min-width: 200px; max-width: 200px; min-height: 400px; background: none; padding: 0px;"
+    type="button"
   >
     <div
       class="cardContent cardDone"
diff --git a/src/components/Ecogesture/EcogestureTabsView.tsx b/src/components/Ecogesture/EcogestureTabsView.tsx
index 69e2658d60b8600a2f92c48a51b1b7bf290987b3..7b1ba5cb8c9ec07d7db39e18382d885e42c97532 100644
--- a/src/components/Ecogesture/EcogestureTabsView.tsx
+++ b/src/components/Ecogesture/EcogestureTabsView.tsx
@@ -51,7 +51,7 @@ const EcogestureTabsView = () => {
   const { profile, profileEcogesture, profileType } = useAppSelector(
     state => state.ecolyo
   )
-  const [tabValue, setTabValue] = useState<EcogestureTab>(
+  const [tabValue, setTabValue] = useState<EcogestureTab>(() =>
     tab ? parseInt(tab) : EcogestureTab.OBJECTIVE
   )
   const [isLoading, setIsLoading] = useState<boolean>(true)
diff --git a/src/components/Options/ExportData/Modals/exportLoadingModal.tsx b/src/components/Options/ExportData/Modals/exportLoadingModal.tsx
index 3daa53c4a523cd26888830a95702506b1327607b..1f0f560992bb6d6d792ed8f8b2249627942ee36c 100644
--- a/src/components/Options/ExportData/Modals/exportLoadingModal.tsx
+++ b/src/components/Options/ExportData/Modals/exportLoadingModal.tsx
@@ -65,11 +65,11 @@ const ExportLoadingModal = ({
       fluidType: FluidType
     ): Promise<ExportDataRow> => {
       const dataRow: ExportDataRow = {}
-      const fluidName = getFluidName(fluidType)
+      const FLUIDNAME = getFluidName(fluidType).toUpperCase()
       dataRow[t('export.month')] = formatTwoDigits(dataload.date.month)
       dataRow[t('export.year')] = dataload.date.year
       dataRow[
-        `${t('export.consumption')} (${t('FLUID.' + fluidName + '.UNIT')})`
+        `${t('export.consumption')} (${t('FLUID.' + FLUIDNAME + '.UNIT')})`
       ] = dataload.value
       if (fluidType === FluidType.ELECTRICITY) {
         const emas = new EnedisMonthlyAnalysisDataService(client)
@@ -137,6 +137,7 @@ const ExportLoadingModal = ({
   useEffect(() => {
     let subscribed = true
     const date = new Date()
+    let timeout: ReturnType<typeof setTimeout>
 
     const exportData = async (): Promise<void> => {
       try {
@@ -147,14 +148,15 @@ const ExportLoadingModal = ({
             exportDataSheets.push(exportDataFluid)
           }
         }
-        await new Promise(r => setTimeout(r, 2000))
-        if (subscribed) {
-          exportToXlsx(
-            exportDataSheets,
-            'ecolyo_data_' + date.toLocaleDateString()
-          )
-          handleDone()
-        }
+        timeout = setTimeout(() => {
+          if (subscribed) {
+            exportToXlsx(
+              exportDataSheets,
+              'ecolyo_data_' + date.toLocaleDateString()
+            )
+            handleDone()
+          }
+        }, 2000)
       } catch (e) {
         Sentry.captureException(e)
         handleDone(e)
@@ -166,6 +168,7 @@ const ExportLoadingModal = ({
     }
     return () => {
       subscribed = false
+      clearTimeout(timeout)
     }
   }, [getExportDataSheet, handleDone, open, selectedFluids])
 
diff --git a/src/components/Options/MatomoOptOut/MatomoOptOut.tsx b/src/components/Options/MatomoOptOut/MatomoOptOut.tsx
index e1a6ab75cc19abb47fc44331caaf141b080b2b6c..c787a17476fde71ce606d87dda3bdb04e489dd9b 100644
--- a/src/components/Options/MatomoOptOut/MatomoOptOut.tsx
+++ b/src/components/Options/MatomoOptOut/MatomoOptOut.tsx
@@ -15,6 +15,7 @@ const MatomoOptOut = () => {
           {t('matomo.matomo_title')}
         </div>
         <iframe
+          sandbox="allow-popups allow-scripts"
           title="opt-out"
           style={{ height: '250px' }}
           className="matomo-content"
diff --git a/src/components/Options/MatomoOptOut/__snapshots__/MatomoOptOut.spec.tsx.snap b/src/components/Options/MatomoOptOut/__snapshots__/MatomoOptOut.spec.tsx.snap
index f9b02a664fa3d91d7e805b657ecf85d19f39ec3e..0c8a9df6b85b5593437e86d378b766fc46b093ca 100644
--- a/src/components/Options/MatomoOptOut/__snapshots__/MatomoOptOut.spec.tsx.snap
+++ b/src/components/Options/MatomoOptOut/__snapshots__/MatomoOptOut.spec.tsx.snap
@@ -15,6 +15,7 @@ exports[`MatomoOptOut component should be rendered correctly 1`] = `
       </div>
       <iframe
         class="matomo-content"
+        sandbox="allow-popups allow-scripts"
         src="http://localhost:9800/index.php?module=CoreAdminHome&action=optOut&language=fr&backgroundColor=121212&fontColor=e0e0e0&fontSize=&fontFamily=sans-serif"
         style="height: 250px;"
         title="opt-out"
diff --git a/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap b/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
index 135c90533a5d6542b27fd3bc6861a129656661a8..493580dda04352001b7b0a3620b31a1b525b66fe 100644
--- a/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
+++ b/src/components/Options/__snapshots__/OptionsView.spec.tsx.snap
@@ -378,6 +378,7 @@ exports[`OptionsView component should be rendered correctly 1`] = `
           </div>
           <iframe
             class="matomo-content"
+            sandbox="allow-popups allow-scripts"
             src="http://localhost:9800/index.php?module=CoreAdminHome&action=optOut&language=fr&backgroundColor=121212&fontColor=e0e0e0&fontSize=&fontFamily=sans-serif"
             style="height: 250px;"
             title="opt-out"
diff --git a/src/components/ProfileType/ProfileTypeFormDateSelection/ProfileTypeFormDateSelection.tsx b/src/components/ProfileType/ProfileTypeFormDateSelection/ProfileTypeFormDateSelection.tsx
index f528554105915c1051c0c6254a21ddfc2fc4626a..20eacbf8817c589113da15c9166d469722e6971b 100644
--- a/src/components/ProfileType/ProfileTypeFormDateSelection/ProfileTypeFormDateSelection.tsx
+++ b/src/components/ProfileType/ProfileTypeFormDateSelection/ProfileTypeFormDateSelection.tsx
@@ -30,14 +30,14 @@ const ProfileTypeFormDateSelection = ({
 }: ProfileTypeFormDateSelectionProps) => {
   const { t } = useI18n()
   const [selectedYear, setSelectedYear] = useState<number>(DateTime.now().year)
-  const [selectedMonth, setSelectedMonth] = useState<SelectionMonth>({
+  const [selectedMonth, setSelectedMonth] = useState<SelectionMonth>(() => ({
     label: DateTime.now().toLocaleString({ month: 'long' }),
     value: formatTwoDigits(DateTime.now().month), // Date.getMonth starts at 0
-  })
+  }))
   const buildISODate = (year: string, month: string) =>
     DateTime.fromISO(`${year}-${month}-01`)
 
-  const [answer, setAnswer] = useState<ProfileTypeValues>(
+  const [answer, setAnswer] = useState<ProfileTypeValues>(() =>
     buildISODate(selectedYear.toString(), selectedMonth.value)
   )
 
diff --git a/src/components/SkipLink/SkipLink.tsx b/src/components/SkipLink/SkipLink.tsx
index 1f1942d343563da5b5700a1923ed40ea9c63c4aa..a12d6807b38ae2bc6256d4584954271a9efa0a77 100644
--- a/src/components/SkipLink/SkipLink.tsx
+++ b/src/components/SkipLink/SkipLink.tsx
@@ -14,7 +14,7 @@ const SkipLink = () => {
   }
 
   return (
-    <button className="skip-link" onClick={handleSkip}>
+    <button type="button" className="skip-link" onClick={handleSkip}>
       {t('common.accessibility.skip_link')}
     </button>
   )
diff --git a/yarn.lock b/yarn.lock
index b19e55b91b3a60058da447e507a38f13a67565fc..22a4af88c750201b2c56d66f1baa45fd78e74c18 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1840,6 +1840,108 @@
   resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005"
   integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==
 
+"@eslint-react/ast@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/ast/-/ast-1.14.3.tgz#06db032754df5e37fb015e98803e9dba7bb2fffd"
+  integrity sha512-JU0619vNfl0RaqbsyyEfLJWKupJOmf5JmHt4sCAD6Y1LCW80Pi0ZbBXeCUTdCR36mA8IJxm9PoLFliQyDYj6uw==
+  dependencies:
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/typescript-estree" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    birecord "^0.1.1"
+    string-ts "^2.2.0"
+    ts-pattern "^5.4.0"
+
+"@eslint-react/core@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/core/-/core-1.14.3.tgz#8affe9aaa1ca95b786668e329d9fe64dd59218dd"
+  integrity sha512-1T/Zubn9PSwJHNN+4SnXXPb6ZjL1ILl9hN2pkPClh8IyBoCTM+u/BHTfxI3aVF5I8yWLNDaiG7nkaxmxoBEOfQ==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    birecord "^0.1.1"
+    short-unique-id "^5.2.0"
+    ts-pattern "^5.4.0"
+
+"@eslint-react/eslint-plugin@^1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/eslint-plugin/-/eslint-plugin-1.14.3.tgz#a146de41173c7b20564ee6656448219c2ca3efb3"
+  integrity sha512-U06zO3F56RAYXI0ZKTEpdwyWllV+muvi2gdC1SLARwk4AOmLAV8ke+iHW5EXBfNkCJQ3SgKRan4tpQqqwfEsMA==
+  dependencies:
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    eslint-plugin-react-debug "1.14.3"
+    eslint-plugin-react-dom "1.14.3"
+    eslint-plugin-react-hooks-extra "1.14.3"
+    eslint-plugin-react-naming-convention "1.14.3"
+    eslint-plugin-react-web-api "1.14.3"
+    eslint-plugin-react-x "1.14.3"
+
+"@eslint-react/jsx@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/jsx/-/jsx-1.14.3.tgz#276d8ac6a962c999dc28362cb3a326df3200b38a"
+  integrity sha512-LJqS63/S8koDJNIqKZ/yLuFvVk4RiK7K3emjUFx+UXHrIdKwFDMpFkksVVbxqeMX70E+toMXgMepABE0pA54ag==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    ts-pattern "^5.4.0"
+
+"@eslint-react/shared@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/shared/-/shared-1.14.3.tgz#0a0cd1dd166f95298b5e6a52bfdcb17291d8ac13"
+  integrity sha512-GP+mjNZBGXq2CuwyVTE2+74K3tBixxNeaG3ho3ovpQ7e8NlTD3TOZk5vZyOJaeRqaOJoJa54PURe12Qt6loCdw==
+  dependencies:
+    "@eslint-react/tools" "1.14.3"
+    "@typescript-eslint/utils" "^8.7.0"
+    picomatch "^4.0.2"
+
+"@eslint-react/tools@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/tools/-/tools-1.14.3.tgz#c97c04f99ad34f457a7a57c6b53f4f493df52dc6"
+  integrity sha512-NtewO4fWxzGtVCjAhD6NG4FwLev5Xq87KWpW92brPF+AvTzkr04abt3/14CpojJlW9L9SMK6FsX9tFVP7ZBqJQ==
+
+"@eslint-react/types@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/types/-/types-1.14.3.tgz#75ed99a2df818ee0430e33522da1e457df7c8f07"
+  integrity sha512-Hi3rBCX0pAxoQs3MQYX/rt4Fxdz97U0pTjSQsm03dGUBb/BEVgrVK9SEZkCqpfPZ7NXrVhuiYudoJRUylNZyCw==
+  dependencies:
+    "@eslint-react/tools" "1.14.3"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+
+"@eslint-react/var@1.14.3":
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/@eslint-react/var/-/var-1.14.3.tgz#116f9db4ed8972635781dbf73e61d6400b30c548"
+  integrity sha512-APJJVSyrDrvJn3t4qXBg1XpWMxmW5AEym56a9/ILzLtgOWFsDj6gJCy4o2g5UB2AZqtfS6YS5IfU5B1G/wYtiw==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    ts-pattern "^5.4.0"
+
 "@eslint/eslintrc@^0.4.3":
   version "0.4.3"
   resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
@@ -3378,6 +3480,14 @@
     "@typescript-eslint/types" "6.7.4"
     "@typescript-eslint/visitor-keys" "6.7.4"
 
+"@typescript-eslint/scope-manager@8.8.1", "@typescript-eslint/scope-manager@^8.7.0":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz#b4bea1c0785aaebfe3c4ab059edaea1c4977e7ff"
+  integrity sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==
+  dependencies:
+    "@typescript-eslint/types" "8.8.1"
+    "@typescript-eslint/visitor-keys" "8.8.1"
+
 "@typescript-eslint/type-utils@6.7.4":
   version "6.7.4"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz#847cd3b59baf948984499be3e0a12ff07373e321"
@@ -3388,6 +3498,16 @@
     debug "^4.3.4"
     ts-api-utils "^1.0.1"
 
+"@typescript-eslint/type-utils@^8.0.0", "@typescript-eslint/type-utils@^8.7.0":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz#31f59ec46e93a02b409fb4d406a368a59fad306e"
+  integrity sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==
+  dependencies:
+    "@typescript-eslint/typescript-estree" "8.8.1"
+    "@typescript-eslint/utils" "8.8.1"
+    debug "^4.3.4"
+    ts-api-utils "^1.3.0"
+
 "@typescript-eslint/types@5.62.0":
   version "5.62.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
@@ -3408,6 +3528,11 @@
   resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.7.4.tgz#5d358484d2be986980c039de68e9f1eb62ea7897"
   integrity sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==
 
+"@typescript-eslint/types@8.8.1", "@typescript-eslint/types@^8.7.0":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.8.1.tgz#ebe85e0fa4a8e32a24a56adadf060103bef13bd1"
+  integrity sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==
+
 "@typescript-eslint/typescript-estree@5.62.0":
   version "5.62.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b"
@@ -3462,6 +3587,20 @@
     semver "^7.5.4"
     ts-api-utils "^1.0.1"
 
+"@typescript-eslint/typescript-estree@8.8.1", "@typescript-eslint/typescript-estree@^8.7.0":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz#34649f4e28d32ee49152193bc7dedc0e78e5d1ec"
+  integrity sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==
+  dependencies:
+    "@typescript-eslint/types" "8.8.1"
+    "@typescript-eslint/visitor-keys" "8.8.1"
+    debug "^4.3.4"
+    fast-glob "^3.3.2"
+    is-glob "^4.0.3"
+    minimatch "^9.0.4"
+    semver "^7.6.0"
+    ts-api-utils "^1.3.0"
+
 "@typescript-eslint/utils@6.7.4":
   version "6.7.4"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.7.4.tgz#2236f72b10e38277ee05ef06142522e1de470ff2"
@@ -3475,6 +3614,16 @@
     "@typescript-eslint/typescript-estree" "6.7.4"
     semver "^7.5.4"
 
+"@typescript-eslint/utils@8.8.1", "@typescript-eslint/utils@^8.7.0":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.8.1.tgz#9e29480fbfa264c26946253daa72181f9f053c9d"
+  integrity sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==
+  dependencies:
+    "@eslint-community/eslint-utils" "^4.4.0"
+    "@typescript-eslint/scope-manager" "8.8.1"
+    "@typescript-eslint/types" "8.8.1"
+    "@typescript-eslint/typescript-estree" "8.8.1"
+
 "@typescript-eslint/utils@^5.10.0":
   version "5.62.0"
   resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86"
@@ -3521,6 +3670,14 @@
     "@typescript-eslint/types" "6.7.4"
     eslint-visitor-keys "^3.4.1"
 
+"@typescript-eslint/visitor-keys@8.8.1":
+  version "8.8.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz#0fb1280f381149fc345dfde29f7542ff4e587fc5"
+  integrity sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==
+  dependencies:
+    "@typescript-eslint/types" "8.8.1"
+    eslint-visitor-keys "^3.4.3"
+
 "@webassemblyjs/ast@1.9.0":
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
@@ -4593,6 +4750,11 @@ bindings@^1.5.0:
   dependencies:
     file-uri-to-path "1.0.0"
 
+birecord@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/birecord/-/birecord-0.1.1.tgz#abc07c8187bf24fb1e0055cd9feb18b30e477a03"
+  integrity sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==
+
 bl@^2.0.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5"
@@ -8017,6 +8179,60 @@ eslint-plugin-prettier@^5.0.0:
     prettier-linter-helpers "^1.0.0"
     synckit "^0.9.1"
 
+eslint-plugin-react-debug@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-debug/-/eslint-plugin-react-debug-1.14.3.tgz#9f47fe2d5717bda21734770d5703b9912f8f406b"
+  integrity sha512-qEsGT5LGFtYR1Hs9nqfrCqgE8MxrTe5VA7LO7Old8epgHgpgOGIuSIdIKYu7dxlEFGAXFB3JLW7ieYJYcgobbQ==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    string-ts "^2.2.0"
+    ts-pattern "^5.4.0"
+
+eslint-plugin-react-dom@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-dom/-/eslint-plugin-react-dom-1.14.3.tgz#2a5a477d71941ac8ed875fad84ae6d35eb688333"
+  integrity sha512-tVA7RQI6Jxomeqrckqi/y1gEmcdI29b268p7K8WjRUWNUDXbZR6vEyaLBqzI8+ykO1HsK8+QhOKUHgUKHjOZBQ==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    ts-pattern "^5.4.0"
+
+eslint-plugin-react-hooks-extra@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks-extra/-/eslint-plugin-react-hooks-extra-1.14.3.tgz#42d31698e593429155fcee9df8c08619f48c1854"
+  integrity sha512-G6mFfYiKgKbGJOUlmvcsN+n0hNiRGa9pNenv4hSlbm3TJFmlrLG+cHvOa9xe88AvaLJHfF5obgF8X/zhSekIfA==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    ts-pattern "^5.4.0"
+
 eslint-plugin-react-hooks@2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.3.0.tgz#53e073961f1f5ccf8dd19558036c1fac8c29d99a"
@@ -8032,6 +8248,60 @@ eslint-plugin-react-hooks@^4.6.0:
   resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
   integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
 
+eslint-plugin-react-naming-convention@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-naming-convention/-/eslint-plugin-react-naming-convention-1.14.3.tgz#cac4c869473a0a2cb3a11b3066d3c5cef9811eef"
+  integrity sha512-qj7XpwYQAKNCTloWA9vPNYDRMsiLa5H/jlF3mH17Is+j/pLH97NRG9CQXbh6kEdLbBFSsHwTDvyP22+CPVZhiA==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    ts-pattern "^5.4.0"
+
+eslint-plugin-react-web-api@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-web-api/-/eslint-plugin-react-web-api-1.14.3.tgz#dcc381ab0a73b3d0ef59e55aafeca4d8a601b0b6"
+  integrity sha512-1G/WIUe+ZIPW8px1lmn7ib5fy6LcuwoHDsnq9G92iE8MFXYPA0Pry0ZKaB2lAsjP8rUROv1L9B457QjyCpro2g==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    birecord "^0.1.1"
+    ts-pattern "^5.4.0"
+
+eslint-plugin-react-x@1.14.3:
+  version "1.14.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react-x/-/eslint-plugin-react-x-1.14.3.tgz#f9b63817e2e5075d747acf9a80867a0c0e67e945"
+  integrity sha512-VKyF4v1kWp9P6vI7JDJfonmny0HOQiS5v/rMLyldK9UC8k+efJN7dUtLE2Kt7TfxggE5gf+v4rsDB2Opvt5Tvg==
+  dependencies:
+    "@eslint-react/ast" "1.14.3"
+    "@eslint-react/core" "1.14.3"
+    "@eslint-react/jsx" "1.14.3"
+    "@eslint-react/shared" "1.14.3"
+    "@eslint-react/tools" "1.14.3"
+    "@eslint-react/types" "1.14.3"
+    "@eslint-react/var" "1.14.3"
+    "@typescript-eslint/scope-manager" "^8.7.0"
+    "@typescript-eslint/type-utils" "^8.7.0"
+    "@typescript-eslint/types" "^8.7.0"
+    "@typescript-eslint/utils" "^8.7.0"
+    is-immutable-type "5.0.0"
+    ts-pattern "^5.4.0"
+
 eslint-plugin-react@7.14.3:
   version "7.14.3"
   resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz#911030dd7e98ba49e1b2208599571846a66bdf13"
@@ -8682,6 +8952,17 @@ fast-glob@^3.2.9:
     merge2 "^1.3.0"
     micromatch "^4.0.4"
 
+fast-glob@^3.3.2:
+  version "3.3.2"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
+  integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
+  dependencies:
+    "@nodelib/fs.stat" "^2.0.2"
+    "@nodelib/fs.walk" "^1.2.3"
+    glob-parent "^5.1.2"
+    merge2 "^1.3.0"
+    micromatch "^4.0.4"
+
 fast-json-stable-stringify@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
@@ -10463,6 +10744,15 @@ is-hexadecimal@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
   integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
 
+is-immutable-type@5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/is-immutable-type/-/is-immutable-type-5.0.0.tgz#2325dfa548f8c7f33a0a8926f2603ec9c2ab839f"
+  integrity sha512-mcvHasqbRBWJznuPqqHRKiJgYAz60sZ0mvO3bN70JbkuK7ksfmgc489aKZYxMEjIbRvyOseaTjaRZLRF/xFeRA==
+  dependencies:
+    "@typescript-eslint/type-utils" "^8.0.0"
+    ts-api-utils "^1.3.0"
+    ts-declaration-location "^1.0.4"
+
 is-in-browser@^1.0.2, is-in-browser@^1.1.3:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835"
@@ -12254,6 +12544,20 @@ minimatch@9.0.3:
   dependencies:
     brace-expansion "^2.0.1"
 
+minimatch@^10.0.0:
+  version "10.0.1"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b"
+  integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==
+  dependencies:
+    brace-expansion "^2.0.1"
+
+minimatch@^9.0.4:
+  version "9.0.5"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
+  integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
+  dependencies:
+    brace-expansion "^2.0.1"
+
 minimist-options@4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619"
@@ -13807,6 +14111,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
   integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
 
+picomatch@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
+  integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
+
 pify@^2.0.0, pify@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -15664,6 +15973,11 @@ semver@^7.3.6, semver@^7.5.4:
   dependencies:
     lru-cache "^6.0.0"
 
+semver@^7.6.0:
+  version "7.6.3"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
+  integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
+
 send@0.18.0:
   version "0.18.0"
   resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@@ -15860,6 +16174,11 @@ shellwords@^0.1.1:
   resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
   integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
 
+short-unique-id@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/short-unique-id/-/short-unique-id-5.2.0.tgz#a7e0668e0a8998d3151f27a36cf046055b1f270b"
+  integrity sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==
+
 side-channel@^1.0.4:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2"
@@ -16301,6 +16620,11 @@ string-length@^4.0.1:
     char-regex "^1.0.2"
     strip-ansi "^6.0.0"
 
+string-ts@^2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/string-ts/-/string-ts-2.2.0.tgz#46573f475f90f9b43c50cd01c9a603c83426bd25"
+  integrity sha512-VTP0LLZo4Jp9Gz5IiDVMS9WyLx/3IeYh0PXUn0NdPqusUFNgkHPWiEdbB9TU2Iv3myUskraD5WtYEdHUrQEIlQ==
+
 string-width@^1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -17062,6 +17386,23 @@ ts-api-utils@^1.0.1:
   resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331"
   integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==
 
+ts-api-utils@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
+  integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==
+
+ts-declaration-location@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/ts-declaration-location/-/ts-declaration-location-1.0.4.tgz#60c64133202ec5d171fdf0395f70f786f92f14c0"
+  integrity sha512-r4JoxYhKULbZuH81Pjrp9OEG5St7XWk7zXwGkLKhmVcjiBVHTJXV5wK6dEa9JKW5QGSTW6b1lOjxAKp8R1SQhg==
+  dependencies:
+    minimatch "^10.0.0"
+
+ts-pattern@^5.4.0:
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/ts-pattern/-/ts-pattern-5.4.0.tgz#efbe74d1ffbb63b80298dbc89b6ec442eab095fa"
+  integrity sha512-hgfOMfjlrARCnYtGD/xEAkFHDXuSyuqjzFSltyQCbN689uNvoQL20TVN2XFcLMjfNuwSsQGU+xtH6MrjIwhwUg==
+
 tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"