Live language feedback
diff --git a/website/package-lock.json b/website/package-lock.json
index fe03e14575..3b8220e509 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -32,6 +32,7 @@
         "eslint-plugin-simple-import-sort": "^8.0.0",
         "focus-visible": "^5.2.0",
         "framer-motion": "^6.5.1",
+        "lande": "^1.0.10",
         "lucide-react": "^0.105.0",
         "next": "13.0.6",
         "next-auth": "^4.18.6",
@@ -26611,6 +26612,14 @@
         "node": ">= 8"
       }
     },
+    "node_modules/lande": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/lande/-/lande-1.0.10.tgz",
+      "integrity": "sha512-yT52DQh+UV2pEp08jOYrA4drDv0DbjpiRyZYgl25ak9G2cVR2AimzrqkYQWrD9a7Ud+qkAcaiDDoNH9DXfHPmw==",
+      "dependencies": {
+        "toygrad": "^2.6.0"
+      }
+    },
     "node_modules/language-subtag-registry": {
       "version": "0.3.22",
       "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz",
@@ -36420,6 +36429,11 @@
         "node": ">=0.8"
       }
     },
+    "node_modules/toygrad": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/toygrad/-/toygrad-2.6.0.tgz",
+      "integrity": "sha512-g4zBmlSbvzOE5FOILxYkAybTSxijKLkj1WoNqVGnbMcWDyj4wWQ+eYSr3ik7XOpIgMq/7eBcPRTJX3DM2E0YMg=="
+    },
     "node_modules/tr46": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -58708,6 +58722,14 @@
       "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
       "dev": true
     },
+    "lande": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/lande/-/lande-1.0.10.tgz",
+      "integrity": "sha512-yT52DQh+UV2pEp08jOYrA4drDv0DbjpiRyZYgl25ak9G2cVR2AimzrqkYQWrD9a7Ud+qkAcaiDDoNH9DXfHPmw==",
+      "requires": {
+        "toygrad": "^2.6.0"
+      }
+    },
     "language-subtag-registry": {
       "version": "0.3.22",
       "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz",
@@ -65936,6 +65958,11 @@
         "punycode": "^2.1.1"
       }
     },
+    "toygrad": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/toygrad/-/toygrad-2.6.0.tgz",
+      "integrity": "sha512-g4zBmlSbvzOE5FOILxYkAybTSxijKLkj1WoNqVGnbMcWDyj4wWQ+eYSr3ik7XOpIgMq/7eBcPRTJX3DM2E0YMg=="
+    },
     "tr46": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
diff --git a/website/package.json b/website/package.json
index c68b15371b..7ab3f3d850 100644
--- a/website/package.json
+++ b/website/package.json
@@ -50,6 +50,7 @@
     "eslint-plugin-simple-import-sort": "^8.0.0",
     "focus-visible": "^5.2.0",
     "framer-motion": "^6.5.1",
+    "lande": "^1.0.10",
     "lucide-react": "^0.105.0",
     "next": "13.0.6",
     "next-auth": "^4.18.6",
diff --git a/website/src/components/Survey/TrackedTextarea.tsx b/website/src/components/Survey/TrackedTextarea.tsx
index f408e168a0..196d2f1a60 100644
--- a/website/src/components/Survey/TrackedTextarea.tsx
+++ b/website/src/components/Survey/TrackedTextarea.tsx
@@ -1,4 +1,23 @@
-import { Progress, Stack, Textarea, TextareaProps, useColorModeValue } from "@chakra-ui/react";
+import {} from "@chakra-ui/react";
+import lande from "lande";
+import { LanguageAbbreviations } from "src/lib/iso6393";
+import { useCookies } from "react-cookie";
+import React from "react";
+import {
+  Progress,
+  Stack,
+  Textarea,
+  TextareaProps,
+  useColorModeValue,
+  Button,
+  Modal,
+  ModalBody,
+  ModalCloseButton,
+  ModalContent,
+  ModalHeader,
+  ModalOverlay,
+  useDisclosure,
+} from "@chakra-ui/react";
 
 interface TrackedTextboxProps {
   text: string;
@@ -11,10 +30,55 @@ interface TrackedTextboxProps {
   onTextChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
 }
 
+const killEvent = (e) => e.stopPropagation();
+
 export const TrackedTextarea = (props: TrackedTextboxProps) => {
+  const [wordLimitForLangDetection, setWordLimitForLangDetection] = React.useState(10);
   const backgroundColor = useColorModeValue("gray.100", "gray.900");
-
+  const [cookies] = useCookies(["NEXT_LOCALE"]);
   const wordCount = (props.text.match(/\w+/g) || []).length;
+  const { isOpen, onOpen, onClose } = useDisclosure();
+  const currentLanguage = cookies["NEXT_LOCALE"];
+
+  const closeTemporaryIgnoreLanguageDetection = () => {
+    setWordLimitForLangDetection(2 * wordCount);
+    onClose();
+  };
+
+  console.log("", wordCount, wordLimitForLangDetection);
+  if (wordCount > wordLimitForLangDetection) {
+    let mostProbableLanguage;
+    try {
+      mostProbableLanguage = LanguageAbbreviations[lande(props.text)[0][0]];
+    } catch (error) {
+      mostProbableLanguage = "";
+    }
+
+    /*const mostProbableLanguage = lande(props.text);*/
+    if (mostProbableLanguage !== currentLanguage) {
+      setTimeout(() => {
+        onOpen();
+      }, 200);
+
+      return (
+        <>
+          <Modal isOpen={isOpen} onClose={closeTemporaryIgnoreLanguageDetection} size="xl" scrollBehavior={"inside"}>
+            {/* we kill the event here to disable drag and drop, since it is in the same container */}
+            <ModalOverlay onMouseDown={killEvent}>
+              <ModalContent alignItems="center">
+                <ModalHeader>Switch Language?</ModalHeader>
+                <ModalCloseButton />
+                <ModalBody>
+                  Do you want to switch language? The detected language is <b>{mostProbableLanguage}</b>, whereas your
+                  chosen language is <b>{currentLanguage}</b>. The language can be changed on the top right.
+                </ModalBody>
+              </ModalContent>
+            </ModalOverlay>
+          </Modal>
+        </>
+      );
+    }
+  }
 
   let progressColor: string;
   switch (true) {
diff --git a/website/src/lib/iso6393.ts b/website/src/lib/iso6393.ts
new file mode 100644
index 0000000000..3720150a0a
--- /dev/null
+++ b/website/src/lib/iso6393.ts
@@ -0,0 +1,187 @@
+export const LanguageAbbreviations = {
+  aar: "aa",
+  abk: "ab",
+  afr: "af",
+  aka: "ak",
+  alb: "sq",
+  amh: "am",
+  ara: "ar",
+  arg: "an",
+  hye: "hy",
+  asm: "as",
+  ava: "av",
+  ave: "ae",
+  aym: "ay",
+  aze: "az",
+  bak: "ba",
+  bam: "bm",
+  eus: "eu",
+  bel: "be",
+  ben: "bn",
+  bih: "bh",
+  bis: "bi",
+  tib: "bo",
+  bos: "bs",
+  bre: "br",
+  bul: "bg",
+  mya: "my",
+  cat: "ca",
+  cze: "cs",
+  cha: "ch",
+  che: "ce",
+  zho: "zh",
+  chu: "cu",
+  chv: "cv",
+  cor: "kw",
+  cos: "co",
+  cre: "cr",
+  wel: "cy",
+  dan: "da",
+  ger: "de",
+  deu: "de",
+  div: "dv",
+  dut: "nl",
+  dzo: "dz",
+  gre: "el",
+  eng: "en",
+  epo: "eo",
+  est: "et",
+  ewe: "ee",
+  fao: "fo",
+  per: "fa",
+  fij: "fj",
+  fin: "fi",
+  fra: "fr",
+  fry: "fy",
+  ful: "ff",
+  geo: "ka",
+  gla: "gd",
+  gle: "ga",
+  glg: "gl",
+  glv: "gv",
+  grn: "gn",
+  guj: "gu",
+  hat: "ht",
+  hau: "ha",
+  heb: "he",
+  her: "hz",
+  hin: "hi",
+  hmo: "ho",
+  hrv: "hr",
+  hun: "hu",
+  ibo: "ig",
+  ice: "is",
+  ido: "io",
+  iii: "ii",
+  iku: "iu",
+  ile: "ie",
+  ina: "ia",
+  ind: "id",
+  ipk: "ik",
+  ita: "it",
+  jav: "jv",
+  jpn: "ja",
+  kal: "kl",
+  kan: "kn",
+  kas: "ks",
+  kau: "kr",
+  kaz: "kk",
+  khm: "km",
+  kik: "ki",
+  kin: "rw",
+  kir: "ky",
+  kom: "kv",
+  kon: "kg",
+  kor: "ko",
+  kua: "kj",
+  kur: "ku",
+  lao: "lo",
+  lat: "la",
+  lav: "lv",
+  lim: "li",
+  lin: "ln",
+  lit: "lt",
+  ltz: "lb",
+  lub: "lu",
+  lug: "lg",
+  mkd: "mk",
+  mah: "mh",
+  mal: "ml",
+  mri: "mi",
+  mar: "mr",
+  may: "ms",
+  mlg: "mg",
+  mlt: "mt",
+  mon: "mn",
+  nau: "na",
+  nav: "nv",
+  nbl: "nr",
+  nde: "nd",
+  ndo: "ng",
+  nep: "ne",
+  nno: "nn",
+  nob: "nb",
+  nor: "no",
+  nya: "ny",
+  oci: "oc",
+  oji: "oj",
+  ori: "or",
+  orm: "om",
+  oss: "os",
+  pan: "pa",
+  pli: "pi",
+  pol: "pl",
+  por: "pt",
+  pus: "ps",
+  que: "qu",
+  roh: "rm",
+  ron: "ro",
+  run: "rn",
+  rus: "ru",
+  sag: "sg",
+  san: "sa",
+  sin: "si",
+  slk: "sk",
+  slv: "sl",
+  sme: "se",
+  smo: "sm",
+  sna: "sn",
+  snd: "sd",
+  som: "so",
+  sot: "st",
+  spa: "es",
+  srd: "sc",
+  srp: "sr",
+  ssw: "ss",
+  sun: "su",
+  swa: "sw",
+  swe: "sv",
+  tah: "ty",
+  tam: "ta",
+  tat: "tt",
+  tel: "te",
+  tgk: "tg",
+  tgl: "tl",
+  tha: "th",
+  tir: "ti",
+  ton: "to",
+  tsn: "tn",
+  tso: "ts",
+  tuk: "tk",
+  tur: "tr",
+  twi: "tw",
+  uig: "ug",
+  ukr: "uk",
+  urd: "ur",
+  uzb: "uz",
+  ven: "ve",
+  vie: "vi",
+  vol: "vo",
+  wln: "wa",
+  wol: "wo",
+  xho: "xh",
+  yid: "yi",
+  yor: "yo",
+  zha: "za",
+  zul: "zu",
+};

This PR aims to resolve issue #997 , it uses the `lande` js library to detect the (most probable) language after 10 entered words in a TrackedTextarea and shows a Modal like for FullText view to remind the Prompter of changing to the language. After closing the dialog the word limit for detection is doubled (stored using a React state), the prompter can also disable language detection - stored as a cookie.
I had to include another file for conversion of ISO-639-3 language code conversion.