#!/bin/bash
################################################################################
#                                                                              #
#                         Linux System Setup Utility                           #
#        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        #
#                          For Debian based systems                            #
#                                                                              #
#                       (C)opyright bei Michael Gasbers                        #
#                             All rights reserved                              #
#                                                                              #
################################################################################
#                                                                              #
#  DIESE SOFTWARE WIRD OHNE MÄNGELGEWÄHR UND OHNE JEGLICHE AUSDRÜCKLICHE ODER  #
#  STILLSCHWEIGENDE GARANTIE ZUR VERFÜGUNG GESTELLT, EINSCHLIESSLICH UND OHNE  #
#  EINSCHRÄNKUNG JEGLICHER GARANTIE FÜR DIE GEBRAUCHSTAUGLICHKEIT ODER EIGNUNG #
#  FÜR EINEN BESTIMMTEN ZWECK. ALLE RISIKEN IN BEZUG AUF ERGEBNISSE UND        #
#  LEISTUNG DIESER SOFTWARE WERDEN VOLLSTÄNDIG VOM BENUTZER ÜBERNOMMEN!        #
#  --------------------------------------------------------------------------  #
#  THIS SOFTWARE IS PROVIDED "AS IS" WITH NO WARRANTIES WHAT SO EVER, WHETHER  #
#  EXPRESSED OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF       #
#  USABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ALL RISKS CONCERNING RESULTS #
#  AND PERFORMANCE OF THIS SOFTWARE ARE ASSUMED COMPLETELY BY THE USER!        #
#                                                                              #
################################################################################
#                                                                              #
#  Jegliche Form der Kopie, Veränderung und Verwendung dieses Skripts sowie    #
#  Teilen davon ist nur für rein private Zwecke erlaubt. Insbesondere eine     #
#  Nutzung und Verbreitung für kommerzielle Zwecke ist strengstens verboten!   #
#  --------------------------------------------------------------------------  #
#  Any form of copying, modification and use of this script and parts thereof  #
#  is only permitted for purely private purposes. In particular, any use and   #
#  distribution for commercial purposes is strictly prohibited!                #
#                                                                              #
################################################################################
#                                                                              #
#  Dies und andere Tools sind auch zu finden auf: https://github.com/migacode  #
#  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  #
#   Für Anregungen und Fragen zu diesem Tool bitte Kontakt mit uns aufnehmen   #
#   über https://migano.de oder per E-Mail an kontakt@migano.de. Danke.        #
#                                                                              #
################################################################################
# Letzte Änderung: 12.04.2026
VERSION="5.7.10"

################################################################################
#                                                                              #
#           Bei unzureichenden Zugriffsrechten mit sudo durchstarten           #
#                                                                              #
################################################################################
if [ $(id -u) -ne 0 ]; then
   sudo -kK
   sudo --preserve-env=XDG_SESSION_TYPE "$0" "$@"
   exit 0
fi

################################################################################
#                                                                              #
#                            Funktionen definieren                             #
#                                                                              #
################################################################################
#===============================================================================
# Ergänzung der Log-Datei durch die Ausgabe von Systemkommandos
#===============================================================================
function add_full_log {
  if [ ${OPTION_FLAG[logfull]} -eq 1 ] &&
     [ -s "$LOG_TEMP" ];
  then
    echo -e "Meldungen zur Aktion:" >> "$LOG_FILE"
    cat "$LOG_TEMP" >> "$LOG_FILE"
    echo -e "" >> "$LOG_FILE"
    remove_file "$LOG_TEMP"
  fi
}

#===============================================================================
# Abfrage aus welcher Quelle ein Paket installiert werden soll
# ------------------------------------------------------------------------------
# Parameter $1: Paketname
# Parameter $2: Liste der möglichen Installations-Arten (Quellen)
# ------------------------------------------------------------------------------
# Rückgabe: Ausgewählte Installations-Art (INSTALL_MODE)!
#===============================================================================
function ask_for_install_mode {
  INST_MODES="$2"
  e_and_l " ${light_yellow}$1${colors_off} ist von mehreren Quellen verfügbar:"
  a=1
  while [ $a -lt 7 ];
  do
    if [ $(echo "$INST_MODES" | grep -c -E "$a") -gt 0 ];
    then
      e_and_l -n "$PRE_SPACE [${bold_yellow}$a${colors_off}]"
      TMP_PKG_VERSION=""
      case $a in
        1) TMP_PKG_VERSION=$(get_pkg_apt_version  "$1" 0)    ;;
        2) TMP_PKG_VERSION=$(get_pkg_snap_version "$1" 0)    ;;
        3) TMP_PKG_VERSION=$(get_pkg_deb_version  "$1")      ;;
        4) TMP_PKG_VERSION=$(get_pkg_web_version  "$1")      ;;
        6) TMP_PKG_VERSION=$(get_pkg_flatpak_version "$1" 0) ;;
      esac
      if [ "$TMP_PKG_VERSION" != "" ];
      then
        TMP_PKG_VERSION=" Version ${light_yellow}$TMP_PKG_VERSION${colors_off}"
      fi
      case $a in
        1) e_and_l "$TMP_PKG_VERSION aus dem Repository"        ;;
        2) e_and_l "$TMP_PKG_VERSION als Snap"                  ;;
        3) e_and_l "$TMP_PKG_VERSION als externes Paket (.deb)" ;;
        4) e_and_l "$TMP_PKG_VERSION als ausführbare Datei(en)" ;;
        6) e_and_l "$TMP_PKG_VERSION als Flatpak"               ;;
      esac
    fi
    ((a+=1))
  done
  # ----------------------------------------------------------------------------
  # Warnung bei bereits installierten alternativen Paketen
  # ----------------------------------------------------------------------------
  if [ $SIMILAR_WARNING_SHOWN -eq 0 ] &&
     [ ${OPTION_FLAG[skipsims]} -eq 0 ];
  then
    SIMILAR_SEEN_LIST=("$1")
    SIMILAR_ALREADY_SEEN=0
    CHECK_SIM_PACK="${SIMILAR_PACK[$1]}"
    while [ "$CHECK_SIM_PACK" != "" ] &&
          [ $SIMILAR_ALREADY_SEEN -eq 0 ];
    do
      for seen in ${SIMILAR_SEEN_LIST[@]};
      do
        if [ "$seen" != "" ] &&
           [ "$CHECK_SIM_PACK" == "$seen" ];
        then
          SIMILAR_ALREADY_SEEN=1
          break
        fi
      done
      if [ $SIMILAR_ALREADY_SEEN -eq 0 ];
      then
        get_install_status "$CHECK_SIM_PACK"
        if [ $? -ne 0 ];
        then
          e_and_l "$PRE_SPACE $ACHTUNG_TAG:"
          e_and_l -n "$PRE_SPACE Alternative ${light_yellow}$CHECK_SIM_PACK${colors_off}"
          if [ "$PKG_VERSION" != "" ] &&
             [ "$PKG_VERSION" != "0" ];
          then
            e_and_l -n " ${light_magenta}$PKG_VERSION${colors_off}"
          fi
          e_and_l " ist bereits installiert!"
          ((SIMILAR_WARNING_SHOWN+=1))
        fi
      fi
      SIMILAR_SEEN_LIST+=($CHECK_SIM_PACK)
      CHECK_SIM_PACK="${SIMILAR_PACK[$CHECK_SIM_PACK]}"
    done
  fi
  # ----------------------------------------------------------------------------
  e_and_l "$PRE_SPACE Bitte auswählen, welche Version davon installiert werden soll,"
  e_and_l -n "$PRE_SPACE oder ${bold_yellow}0${colors_off} (oder N) eingeben um die Installation zu überspringen: "
  if [ ${OPTION_FLAG[notoall]} -eq 0 ];
  then
    NEW_INST_MODE=""
    while [ "$NEW_INST_MODE" == "" ] ||
          [ $(echo "$INST_MODES" | grep -c -E "$NEW_INST_MODE") -eq 0 ];
    do
      read -N 1 -r -s NEW_INST_MODE
      NEW_INST_MODE=$(echo $NEW_INST_MODE | sed 's/[^0-9nN]*//gi')
      if [ "$NEW_INST_MODE" == "n" ] ||
         [ "$NEW_INST_MODE" == "N" ];
         then
           NEW_INST_MODE="0"
         fi
    done
  else
    NEW_INST_MODE="0"
  fi
  e_and_l "$NEW_INST_MODE"
  if [ $NEW_INST_MODE -ne 0 ]; then e_and_l -n "$PRE_SPACE"; fi
  return "$NEW_INST_MODE"
}

#===============================================================================
# Einfache Ja/Nein-Abfrage mit Option zur Anzeige von Infos zu Programmpaketen
# Kann mit der Option force übersprungen werden, sofern nicht "TROTZDEM"
# angegeben ist, sprich bereits ein alternatives Paket dazu installiert ist!
# Diese Funktion wird nur zur Installation von Programmpaketen verwendet und
# durch die Option "notoall" automatisch übersprungen
# ------------------------------------------------------------------------------
# Parameter $1: Paketname
# Parameter $2: Option force für dieses Paket NICHT verwenden, auch wenn diese
#               global als Parameter aktiviert ist (0 = Nein, 1 = Ja), wichtig
#               falls z.B. eine vorherige Prüfung eine neue Nachfrage erfordert
# ------------------------------------------------------------------------------
# Rückgaben: 0 = false (Nein)
#            1 = true (Ja)
#===============================================================================
function ask_yes_no_info {
  PACKAGE_NAME="$1"
  USE_TROTZDEM=$2
  # --------------------------------------------------------------------------
  # Überspringen wenn Abfragen automatisch mit Nein beantwortet werden sollen
  # --------------------------------------------------------------------------
  if [ ${OPTION_FLAG[notoall]} -ne 1 ];
  then
    TROTZDEM=""
    # ------------------------------------------------------------------------
    # Wenn schon eine vorherige Prüfung eine Nachfrage erfordert, dann auch
    # die Option force durch Verwendung von "TROTZDEM" außer Kraft setzen ...
    # ------------------------------------------------------------------------
    if [ $USE_TROTZDEM -eq 1 ];
    then
      TROTZDEM=" trotzdem"
    else
      # ------------------------------------------------------------------------
      # .., sonst auf bereits installierte Alternativen prüfen, falls vorhanden
      # diese anzeigen und die Option force durch "TROTZDEM" außer Kraft setzen
      # ------------------------------------------------------------------------
      SIM_PACK_INSTALLED=0
      if [ $SIMILAR_WARNING_SHOWN -eq 0 ] &&
         [ ${OPTION_FLAG[skipsims]} -eq 0 ];
      then
        SIMILAR_SEEN_LIST=("$1")
        SIMILAR_ALREADY_SEEN=0
        CHECK_SIM_PACK="${SIMILAR_PACK[$1]}"
        while [ "$CHECK_SIM_PACK" != "" ] &&
              [ $SIMILAR_ALREADY_SEEN -eq 0 ];
        do
          for seen in ${SIMILAR_SEEN_LIST[@]};
          do
            if [ "$seen" != "" ] &&
               [ "$CHECK_SIM_PACK" == "$seen" ];
            then
              SIMILAR_ALREADY_SEEN=1
              break
            fi
          done
          if [ $SIMILAR_ALREADY_SEEN -eq 0 ];
          then
            get_install_status "$CHECK_SIM_PACK"
            if [ $? -ne 0 ];
            then
              if [ $SIM_PACK_INSTALLED -gt 0 ]; then e_and_l -n "$PRE_SPACE"; fi
              e_and_l " $ACHTUNG_TAG:"
              e_and_l -n "$PRE_SPACE Alternative ${light_yellow}$CHECK_SIM_PACK${colors_off}"
              if [ "$PKG_VERSION" != "" ] &&
                 [ "$PKG_VERSION" != "0" ];
              then
                e_and_l -n " ${light_magenta}$PKG_VERSION${colors_off}"
              fi
              e_and_l " ist bereits installiert!"
              copy_starter_to_desktop "$CHECK_SIM_PACK" "" 0
              ((SIM_PACK_INSTALLED+=1))
              ((SIMILAR_WARNING_SHOWN+=1))
            fi
          fi
          SIMILAR_SEEN_LIST+=($CHECK_SIM_PACK)
          CHECK_SIM_PACK="${SIMILAR_PACK[$CHECK_SIM_PACK]}"
        done
      fi
      if [ $SIM_PACK_INSTALLED -ne 0 ];
      then
        e_and_l -n "$PRE_SPACE"
        TROTZDEM=" trotzdem"
      fi
    fi
    # ------------------------------------------------------------------
    # Prüfen, ob eine Auto-Antwort zur Installation genutzt werden soll
    # ------------------------------------------------------------------
    CHECK_AUTO_ANSWER=""
    if [ ${OPTION_FLAG[autoyorn]} -eq 1 ] &&
       [ "$PACKAGE_NAME" != "" ];
    then
      CHECK_AUTO_ANSWER=$(echo ${AUTO_ANSWERS["pkg_$PACKAGE_NAME"]} | xargs)
    fi
    # -------------------------------------------------------------------------
    # Wenn es so gewollt ist (Option force) und nicht bereits ein alternatives
    # Programmpaket installiert ist (welches eventuell in Konflikt steht), und
    # auch keine Auto-Antwort zur Installation des Paketes vorhanden ist, dann
    # automatisch ein "Ja" (Installation ohne weitere Rückfrage) zurückgeben
    # -------------------------------------------------------------------------
    INPUT_OK=0
    if [ ${OPTION_FLAG[force]} -eq 1 ] &&
       [ "$TROTZDEM" == "" ] &&
       [ "$CHECK_AUTO_ANSWER" == "" ];
    then
      IYN_RESULT=1
    # -------------------------------------------------------------------------
    # ... sonst Abfrage durchführen ...
    # -------------------------------------------------------------------------
    else
      IYN_RESULT=0
      QUESTION_1="Programmpaket ${light_yellow}$PACKAGE_NAME${colors_off}"
      TMP_PKG_TYPE="$(inst_status_to_name $INSTALL_MODE)"
      case $INSTALL_MODE in
        1) TMP_PKG_VERSION=$(get_pkg_apt_version "$PACKAGE_NAME" 0)     ;;
        2) TMP_PKG_VERSION=$(get_pkg_snap_version "$PACKAGE_NAME" 0)    ;;
        3) TMP_PKG_VERSION=$(get_pkg_deb_version "$PACKAGE_NAME")       ;;
        4) TMP_PKG_VERSION=$(get_pkg_web_version "$PACKAGE_NAME")       ;;
        6) TMP_PKG_VERSION=$(get_pkg_flatpak_version "$PACKAGE_NAME" 0) ;;
      esac
      if [ "$TMP_PKG_VERSION" != "" ];
      then
        QUESTION_1+=" ${light_yellow}$TMP_PKG_VERSION${colors_off}"
      fi
      QUESTION_1+=" (${light_magenta}$TMP_PKG_TYPE${colors_off})"
      QUESTION_1+="$TROTZDEM installieren?"
      QUESTION_2="[${bold_yellow}j${colors_off}]a [${bold_yellow}"
      if [ "$TROTZDEM" != "" ];
      then
        QUESTION_2+="N"
      else
        QUESTION_2+="n"
      fi
      QUESTION_2+="${colors_off}]ein"
      # -----------------------------------------------
      # Parameter der Eingabe-Möglichkeiten definieren
      # -----------------------------------------------
      if [ $INSTALL_MODE -eq 1 ] || # apt
         [ $INSTALL_MODE -eq 2 ] || # snap
         [ $INSTALL_MODE -eq 6 ];   # flatpak
      then
        REG_CHARS="[^JjNnIi]*"
        QUESTION_2+=" [${bold_yellow}i${colors_off}]nfo"
      else
        REG_CHARS="[^JjNn]*"
      fi
      # -----------------------------------------------
      QUESTION_2+=":"
      e_and_l " $QUESTION_1"
      e_and_l -n "$PRE_SPACE $QUESTION_2 "
      # -----------------------------------------------------
      # Optional Antwort des vorherigen Durchlaufs verwenden
      # -----------------------------------------------------
      if [ ${OPTION_FLAG[autoyorn]} -eq 1 ] &&
         [ "$PACKAGE_NAME" != "" ];
      then
        ANSWER=$(echo ${AUTO_ANSWERS["pkg_$PACKAGE_NAME"]} | xargs)
        if [ "$ANSWER" == "j" ];
        then
          e_and_l ${dark_gray}$ANSWER${colors_off}
          IYN_RESULT=1
          INPUT_OK=1
        fi
        if [ "$ANSWER" == "n" ];
        then
          e_and_l ${dark_gray}$ANSWER${colors_off}
          IYN_RESULT=0
          INPUT_OK=1
        fi
      fi
      # -------------------------------------------------------------------
      # Wenn es keine Antwort aus dem vorherigen Durchlauf gibt, oder dies
      # nicht gewollt ist, dann erweiterte Ja/Nein-Abfrage durchführen
      # -------------------------------------------------------------------
      while [ $INPUT_OK -eq 0 ]
      do
        # -----------------
        # Eingabe-Schleife
        # -----------------
        ANSWER=""
        while [ "$ANSWER" == "" ];
        do
          read -N 1 -r -s ANSWER
          # Bei "Trotzdem"-Fragen gilt eine leere Eingabe als Nein
          if [ "$ANSWER" == $'\n' ] &&
             [ "$TROTZDEM" != "" ];
          then
            ANSWER="n"
          fi
          ANSWER=$(echo $ANSWER | sed "s/$REG_CHARS//g")
        done
        e_and_l "$ANSWER"
        # --------------
        # Info anzeigen
        # --------------
        if [ "$ANSWER" == "I" ] ||
           [ "$ANSWER" == "i" ];
        then
          echo -e "${light_yellow}"
          if [ $INSTALL_MODE -eq 1 ];
          then
            if [ "$APT_PKG_EXTENDED_NAME" != "" ];
            then
              PKG_TO_SHOW="$APT_PKG_EXTENDED_NAME"
            else
              PKG_TO_SHOW="$PACKAGE_NAME"
            fi
            apt show "$PKG_TO_SHOW" 2>/dev/null
          fi
          if [ $INSTALL_MODE -eq 2 ];
          then
            if [ $SNAP_ACTIVE -gt 0 ];
            then
              snap info "$PACKAGE_NAME" 2>/dev/null
            else
              echo -e "$PRE_SPACE Die Snap-Paketverwaltung ist nicht aktiv."
            fi
          fi
          if [ $INSTALL_MODE -eq 3 ] ||
             [ $INSTALL_MODE -eq 4 ];
          then
            echo -e "$PRE_SPACE Zu diesem Paket sind leider keine Informationen verfügbar."
          fi
          if [ $INSTALL_MODE -eq 6 ]; then flatpak remote-info flathub $(get_pkg_flatpak_reference ${PACKAGE_NAME} 0); fi
          echo -e "${colors_off}"
          e_and_l "$PRE_SPACE $QUESTION_1"
          e_and_l -n "$PRE_SPACE $QUESTION_2 "
        # -------------
        # Ja oder Nein
        # -------------
        else
          if [ "$ANSWER" != "N" ] &&
             [ "$ANSWER" != "n" ];
          then
            e_and_l -n "$PRE_SPACE"
            IYN_RESULT=1
          fi
          INPUT_OK=1
        fi
      done
    fi
    # --------------------------------------------------------------------------
    # Antwort speichern
    # --------------------------------------------------------------------------
    if [ $INPUT_OK -eq 1 ] &&
       [ "$PACKAGE_NAME" != "" ] &&
       [ "$ANSWER" != "" ];
    then
      ANSWER="$(echo -n "${ANSWER}" | tr '[:upper:]' '[:lower:]')"
      NEW_CONFIG_LINE="pkg_$PACKAGE_NAME:$ANSWER"
      if [ $(grep -c -E "pkg_$PACKAGE_NAME:" "$AUTO_ANSWER_FILE" 2>/dev/null) -gt 0 ];
      then
        # -------------------------------
        # Bestehende Konfig-Zeile ändern
        # -------------------------------
        sed -i -E "s/pkg_$PACKAGE_NAME:.*/$NEW_CONFIG_LINE/gi" "$AUTO_ANSWER_FILE" 2>/dev/null
      else
        # -----------------------------------------
        # Nicht vorhandene Konfig-Zeile hinzufügen
        # -----------------------------------------
        echo -e "$NEW_CONFIG_LINE" >> "$AUTO_ANSWER_FILE" 2>/dev/null
      fi
    fi
    # --------------------------------------------------------------------------
  else
    e_and_l " Programmpaket ${light_yellow}$PACKAGE_NAME${colors_off} installieren? [${bold_yellow}j${colors_off}]a oder [${bold_yellow}n${colors_off}]ein: ${light_magenta}n${colors_off}"
    IYN_RESULT=0
  fi
  return $IYN_RESULT
}

#===============================================================================
# Einfache Ja/Nein-Abfrage ohne jegliche Optionen
# ------------------------------------------------------------------------------
# HINWEIS: Diese Abfrage wird weder mit der Option "force" noch mit der Option
# "notoall" übersprungen, sondern erfordert immer eine Eingabe des Benutzers.
# ------------------------------------------------------------------------------
# Parameter $1: Text der Frage
# ------------------------------------------------------------------------------
# Rückgaben: 0 = false (Nein)
#            1 = true (Ja)
#===============================================================================
function ask_yes_or_no_pure {
  e_and_l -n "$1? [${bold_yellow}j${colors_off}]a, [${bold_yellow}n${colors_off}]ein: "
  IYN_RESULT=0
  # -----------------
  # Eingabe-Schleife
  # -----------------
  ANSWER=""
  while [ "$ANSWER" == "" ];
  do
    read -N 1 -r -s ANSWER
    ANSWER=$(echo $ANSWER | sed "s/[^JjNn]//gi")
  done
  e_and_l "$ANSWER"
  if [ "$ANSWER" == "J" ] ||
     [ "$ANSWER" == "j" ];
  then
    IYN_RESULT=1
  fi
  return $IYN_RESULT
}

#===============================================================================
# Einfache Ja/Nein-Abfrage mit optionaler Anzeige einer Text-Datei
# ------------------------------------------------------------------------------
# HINWEIS: Diese Abfrage wird mit der Option "force" NICHT übersprungen, mit
# der Option "notoall" allerdings schon.
# ------------------------------------------------------------------------------
# Parameter $1: Eindeutige ID zur Speicherung der Antwort
# Parameter $2: Text der Frage
# Parameter $3: Datei zur Anzeige weiterer Infos (optional)
# Parameter $4: Antwort-Vorgabe / Default (optional)
# ------------------------------------------------------------------------------
# Rückgaben: 0 = false (Nein)
#            1 = true (Ja)
#===============================================================================
function ask_yes_or_no_plus {
  QUEST_ID="$1"
  QUESTION="$2"
  FILE_TO_SHOW="$3"
  DEFAULT_ANSWER="$4"
  QUESTION+="? [${bold_yellow}"
  if [ "$DEFAULT_ANSWER" == "J" ] || [ "$DEFAULT_ANSWER" == "j" ];
  then
    QUESTION+="J"
  else
    QUESTION+="j"
  fi
  QUESTION+="${colors_off}]a, [${bold_yellow}"
  if [ "$DEFAULT_ANSWER" == "N" ] || [ "$DEFAULT_ANSWER" == "n" ];
  then
    QUESTION+="N"
  else
    QUESTION+="n"
  fi
  QUESTION+="${colors_off}]ein"
  if [ "$FILE_TO_SHOW" != "" ];
  then
    QUESTION+=", [${bold_yellow}a${colors_off}]nzeigen"
    REG_CHARS="[^JjNnAa]*"
  else
    REG_CHARS="[^JjNn]*"
  fi
  # ----------------------------------------------------------------------------
  # Überspringen wenn Abfragen automatisch mit Nein beantwortet werden sollen
  # ----------------------------------------------------------------------------
  if [ ${OPTION_FLAG[notoall]} -ne 1 ];
  then
    e_and_l -n "$QUESTION: "
    IYN_RESULT=0
    INPUT_OK=0
    # -----------------------------------------------------
    # Optional Antwort des vorherigen Durchlaufs verwenden
    # -----------------------------------------------------
    if [ ${OPTION_FLAG[autoyorn]} -eq 1 ] &&
       [ "$QUEST_ID" != "" ];
    then
      ANSWER=$(echo ${AUTO_ANSWERS["$QUEST_ID"]} | xargs)
      if [ "$ANSWER" == "j" ];
      then
        e_and_l ${dark_gray}$ANSWER${colors_off}
        IYN_RESULT=1
        INPUT_OK=1
      fi
      if [ "$ANSWER" == "n" ];
      then
        e_and_l ${dark_gray}$ANSWER${colors_off}
        IYN_RESULT=0
        INPUT_OK=1
      fi
    fi
    # -------------------------------------------------------------------
    # Wenn es keine Antwort aus dem vorherigen Durchlauf gibt, oder dies
    # nicht gewollt ist, dann erweiterte Ja/Nein-Abfrage durchführen
    # -------------------------------------------------------------------
    while [ $INPUT_OK -eq 0 ]
    do
      # -----------------
      # Eingabe-Schleife
      # -----------------
      ANSWER=""
      while [ "$ANSWER" == "" ];
      do
        read -N 1 -r -s ANSWER
        if [ "$ANSWER" == $'\n' ]; then ANSWER="$DEFAULT_ANSWER"; fi
        ANSWER=$(echo $ANSWER | sed "s/$REG_CHARS//g")
      done
      e_and_l "$ANSWER"
      # ---
      # Ja
      # ---
      if [ "$ANSWER" == "J" ] ||
         [ "$ANSWER" == "j" ];
      then
        IYN_RESULT=1
        INPUT_OK=1
      fi
      # -----
      # Nein
      # -----
      if [ "$ANSWER" == "N" ] ||
         [ "$ANSWER" == "n" ];
      then
        INPUT_OK=1
      fi
      # ---------------
      # Datei anzeigen
      # ---------------
      if [ "$FILE_TO_SHOW" != "" ];
      then
        if [ "$ANSWER" == "A" ] ||
           [ "$ANSWER" == "a" ];
        then
          echo -e "${light_yellow}"
          more "$FILE_TO_SHOW"
          echo -e "${colors_off}"
        fi
      fi
      # ------------------------------------------------
      # Wenn eine Datei angezeigt wurde erneut abfragen
      # ------------------------------------------------
      if [ $INPUT_OK -eq 0 ];
      then
        if [ "$FILE_TO_SHOW" != "" ];
        then
          e_and_l -n "$QUESTION: "
        fi
      fi
    done
    # --------------------------------------------------------------------------
    # Antwort speichern
    # --------------------------------------------------------------------------
    if [ $INPUT_OK -eq 1 ] &&
       [ "$QUEST_ID" != "" ] &&
       [ "$ANSWER" != "" ];
    then
      ANSWER="$(echo -n "${ANSWER}" | tr '[:upper:]' '[:lower:]')"
      NEW_CONFIG_LINE="$QUEST_ID:$ANSWER"
      if [ $(grep -c -E "$QUEST_ID:" "$AUTO_ANSWER_FILE" 2>/dev/null) -gt 0 ];
      then
        # -------------------------------
        # Bestehende Konfig-Zeile ändern
        # -------------------------------
        sed -i -E "s/$QUEST_ID:.*/$NEW_CONFIG_LINE/gi" "$AUTO_ANSWER_FILE" 2>/dev/null
      else
        # -----------------------------------------
        # Nicht vorhandene Konfig-Zeile hinzufügen
        # -----------------------------------------
        echo -e "$NEW_CONFIG_LINE" >> "$AUTO_ANSWER_FILE" 2>/dev/null
      fi
    fi
    # --------------------------------------------------------------------------
  else
    e_and_l "$2? [${bold_yellow}j${colors_off}]a oder [${bold_yellow}n${colors_off}]ein: ${light_magenta}n${colors_off}"
    IYN_RESULT=0
  fi
  return $IYN_RESULT
}

#===============================================================================
# Einträge für die EFI-System-Partition auf Fehler prüfen
#===============================================================================
function check_esp_errors {
  get_esp_uuids
  ESP_ERROR_LIST=""
  # ---------------------------------------
  # In der fstab ist keine ESP eingetragen
  # ---------------------------------------
  if [ "$uuid_efi_fstab" == "" ];
  then
    ESP_ERROR_LIST+="1"
  fi
  # ----------------------------------------------------------------
  # Die in der fstab eingetragene UUID für die ESP ist nicht gleich
  # der UUID der tatsächlich auf dem Laufwerk befindlichen ESP
  # ----------------------------------------------------------------
  if [ "$uuid_efi_fstab" != "" ] &&
     [ "$uuid_efi_system" != "" ] &&
     [ "$uuid_efi_fstab" != "$uuid_efi_system" ];
  then
    ESP_ERROR_LIST+="2"
  fi
  # --------------------------------------------------------------------
  # Die ESP in der fstab mit Mountpunkt /boot/efi ist nicht eingehangen
  # --------------------------------------------------------------------
  if [ $(cat "$ETC_FSTAB" 2>/dev/null | grep -c -i -E "^\s*[^#]*\s*[a-z0-9\=\-]*(\s|\t)+/boot/efi") -gt 0 ] &&
     [ $(mount 2>/dev/null | grep -c -i -E "$efi_system_partition.*/boot/efi") -eq 0 ];
  then
    ESP_ERROR_LIST+="3"
  fi
  # ------------------------------------------------------------------
  # In der fstab ist eine andere UUID für die ESP eingetragen als die
  # UUID der Partition, auf der aktuell tatsächlich /boot/efi liegt
  # ------------------------------------------------------------------
  if [ "$uuid_efi_mount" != "" ] &&
     [ "$uuid_efi_fstab" != "" ] &&
     [ "$uuid_efi_mount" != "$uuid_efi_fstab" ];
  then
    ESP_ERROR_LIST+="4"
  fi
  # ------------------------------------------------------------------
  # Die UUID der Partition, auf der aktuell tatsächlich /boot/efi liegt
  # ist nicht die UUID der auf dem System-Laufwerk befindlichen ESP
  # ------------------------------------------------------------------
  if [ "$uuid_efi_mount" != "" ] &&
     [ "$uuid_efi_system" != "" ] &&
     [ "$uuid_efi_mount" != "$uuid_efi_system" ];
  then
    ESP_ERROR_LIST+="5"
  fi
  echo -e -n "$ESP_ERROR_LIST"
}

# ==============================================================================
# Ausgewählte Optionen auf Konflikte prüfen
# ==============================================================================
function check_options {
  MENU_INFO_TEXT=""
  MENU_ERROR_TEXT=""
  # -------------------------------
  # Anzahl ausgewählter Kategorien
  # -------------------------------
  ANZ_KATEGORIES=0
  for k in ${KAT_KEY_LIST[@]};
  do
    if [ ${KATEGORIE_FLAG[$k]} -eq 1 ];
    then
      ((ANZ_KATEGORIES+=1))
    fi
  done
  # --------------------
  # noinfo und infoonly
  # --------------------
  if [ ${OPTION_FLAG[infoonly]} -eq 1 ];
  then
    if [ ${OPTION_FLAG[noinfo]} -eq 1 ];
    then
      MENU_ERROR_TEXT="\Z1\ZbFEHLER!\Zn\nDie Optionen \Z1noinfo\Z0 und \Z1infoonly\Z0 können nicht gemeinsam angewendet werden."
    else
      MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nBei Verwendung der Option \Z4infoonly\Z0 werden keine weiteren Aktionen durchgeführt!"
    fi
  else
    # ----------------
    # dload und dsave
    # ----------------
    if [ ${OPTION_FLAG[dload]} -eq 1 ] &&
       [ ${OPTION_FLAG[dsave]} -eq 1 ];
    then
      MENU_ERROR_TEXT="\Z1\ZbFEHLER!\Zn\nDie Aktionen \Z1dload\Z0 und \Z1dsave\Z0 können nicht gemeinsam durchgeführt werden."
    fi
    # --------------------------------
    # snapcont, snapkill und snapstop
    # --------------------------------
    if [[ ${OPTION_FLAG[snapcont]} -eq 1 && ${OPTION_FLAG[snapkill]} -eq 1 ]] ||
       [[ ${OPTION_FLAG[snapcont]} -eq 1 && ${OPTION_FLAG[snapstop]} -eq 1 ]] ||
       [[ ${OPTION_FLAG[snapkill]} -eq 1 && ${OPTION_FLAG[snapstop]} -eq 1 ]];
    then
      MENU_ERROR_TEXT="\Z1\ZbFEHLER!\Zn\nDie Aktionen \Z1snapcont\Z0, \Z1snapkill\Z0 und \Z1snapstop\Z0 können nicht gemeinsam durchgeführt werden."
    fi
    # -------------------------
    # listonly ohne Kategorien
    # -------------------------
    if [ ${OPTION_FLAG[listonly]} -eq 1 ];
    then
      if [ $ANZ_KATEGORIES -eq 0 ];
      then
        MENU_ERROR_TEXT="\Z1\ZbFEHLER!\Zn\nDie Option \Z1listonly\Z0 wurde ausgewählt, aber keine Pakete (Kategorie) zur Auflistung."
      else
        if [ ${OPTION_FLAG[status]} -eq 1 ];
        then
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nDurch die Option \Z4listonly\Z0 wird der Paketstatus (Option \Z4status\Z0) nicht angezeigt."
        else
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nBei Verwendung der Option \Z4listonly\Z0 werden keine weiteren Aktionen durchgeführt!"
        fi
      fi
    else
      # =========================================================
      # Konflikte bei Einstellungen zur Installation von Paketen
      # =========================================================
      if [ ${OPTION_FLAG[status]} -eq 0 ];
      then
        # ------------------
        # "Fremde" Desktops
        # ------------------
        if [[ ${KATEGORIE_FLAG[gx]} -eq 1 && "$DESKTOP_ENVIRONMENT" != "GNOME" ]] ||
           [[ ${KATEGORIE_FLAG[lx]} -eq 1 && "$DESKTOP_ENVIRONMENT" != "LXDE" ]]  ||
           [[ ${KATEGORIE_FLAG[mx]} -eq 1 && "$DESKTOP_ENVIRONMENT" != "MATE" ]]  ||
           [[ ${KATEGORIE_FLAG[xf]} -eq 1 && "$DESKTOP_ENVIRONMENT" != "XFCE" ]]  ||
           [[ ${KATEGORIE_FLAG[mt]} -eq 1 && $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -eq 0 ]] ||
           [[ ${KATEGORIE_FLAG[ci]} -eq 1 && "$DESKTOP_ENVIRONMENT" != "Cinnamon" ]];
        then
          MENU_INFO_TEXT="\Z1\ZbWarnung\Zn\nEs wurden Tool-Pakete ausgewählt, die nicht für diesen Desktop vorgesehen sind."
        fi
        # -------------------------------
        # Sich überlagernde Optionen
        # (notoall -> autoyorn -> force)
        # -------------------------------
        if [ ${OPTION_FLAG[notoall]} -eq 1 ];
        then
          if [ ${OPTION_FLAG[autoyorn]} -eq 1 ];
          then
            MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nOption \Z4notoall\Z0 überlagert Option \Z4autoyorn\Z0,\nso dass alle Abfragen mit (N)ein beantwortet werden."
          fi
          if [ ${OPTION_FLAG[force]} -eq 1 ];
          then
            MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nOption \Z4notoall\Z0 überlagert Option \Z4force\Z0,\nso dass keine Pakete installiert werden."
          fi
        fi
        if [ ${OPTION_FLAG[autoyorn]} -eq 1 ] &&
           [ ${OPTION_FLAG[force]} -eq 1 ];
        then
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nOption \Z4autoyorn\Z0 überlagert Option \Z4force\Z0,\nso dass eventuell nicht alle Pakete installiert werden."
        fi
        # ----------------------------------------------------
        # Ausgewählte aber nicht installierte Paketverwaltung
        # ----------------------------------------------------
        if [ ${OPTION_FLAG[priosnap]} -eq 1 ] &&
           [ ${OPTION_FLAG[addsnap]} -eq 0 ];
        then
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nSnap-Pakete sollen bevorzugt werden, aber die Option \Z4addsnap\Z0 ist nicht ausgewählt.\nSo werden \Zbkeine\Z0 Snap-Pakete installiert!"
        fi
        if [ ${OPTION_FLAG[prioflat]} -eq 1 ] &&
           [ ${OPTION_FLAG[addflat]} -eq 0 ];
        then
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nFlatpaks sollen bevorzugt werden, aber die Option \Z4addflat\Z0 ist nicht ausgewählt.\nSo werden \Zbkeine\Z0 Flatpak-Pakete installiert!"
        fi
        # ------------------------------------------------------
        # Forcierte Installation von Paketen mit gleichzeitigem
        # Ignorieren der ähnlichen und gleichen Pakete
        # ------------------------------------------------------
        if [ ${OPTION_FLAG[force]} -eq 1 ] &&
            [ ${OPTION_FLAG[skipsims]} -eq 1 ];
        then
          MENU_INFO_TEXT="\Z5\ZbAchtung\Zn\nDurch die Kombination \Z4force\Z0 und \Z4skipsims\Z0 wird nicht auf ähnliche Pakete geprüft, was zu mehrfacher Installation gleicher Pakete aus verschiedenen Quellen führen kann."
        fi
      fi
    fi # Ende listonly
  fi # Ende infoonly
}

#===============================================================================
# Prüfung, ob ein Programmpaket auf Raspberry Pi übersprungen werden soll
# Rückgaben: 0 = false (nicht überspringen)
#            1 = true (überspringen)
#===============================================================================
function check_skip_raspi {
  SKIP_RASPI=0
  # -------------------------------------------------------
  # Auf dem Raspberry Pi wegzulassende Pakete überspringen
  # -------------------------------------------------------
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    for not_on_pi in ${NOT_ON_RASPBERRY[@]};
    do
      if [ "$1" == "$not_on_pi" ];
      then
        SKIP_RASPI=1
        break
      fi
    done
  fi
  # -----------------------------------------------
  # Auf Pi OS wegzulassende Pakete überspringen
  # -----------------------------------------------
  if [ $IS_PIOS -gt 0 ] && [ $SKIP_RASPI -eq 0 ];
  then
    for not_on_pi in ${NOT_ON_PIOS[@]};
    do
      if [ "$1" == "$not_on_pi" ];
      then
        SKIP_RASPI=1
        break
      fi
    done
  fi
  # -------------------------------------------------------
  return $SKIP_RASPI
}

#===============================================================================
# Verifizierung der Existenz einer downloadbaren Datei im Internet
# Rückgaben: 0 = OK (URL existiert)
#            1 = Fehler (URL existiert nicht)
#===============================================================================
function check_url_file {
  wget --spider "$1" &>/dev/null
  return $?
}

#===============================================================================
# Prüfung ob ein Paket mindestens in einer Versionsnummer (nur die ersten
# zwei Zahlen) installiert oder im Repository (APT) verfügbar ist
#===============================================================================
function chk_min_apt_pkg_version {
  THE_TEST_MAIN_VERSION=$(echo ${2} | cut -d '.' -f 1 | xargs)
  THE_TEST_SUB_VERSION=$(echo ${2} | cut -d '.' -f 2 | xargs)
  THE_TEST_VALUE=$(((${THE_TEST_MAIN_VERSION:0:2}*100)+${THE_TEST_SUB_VERSION:0:2}))
  # ---------------------------------
  # Erst installierte Version prüfen
  # ---------------------------------
  THE_PKG_VERSION=$(get_pkg_apt_version "$1" 1)
  # -------------------------------
  # Dann verfügbare Version prüfen
  # -------------------------------
  if [ "$THE_PKG_VERSION" == "" ];
  then
    THE_PKG_VERSION=$(get_pkg_apt_version "$1" 0)
  fi
  if [ "$THE_PKG_VERSION" != "" ];
  then
    THE_PKG_MAIN_VERSION=$(echo $THE_PKG_VERSION | cut -d '.' -f 1 | xargs)
    THE_PKG_SUB_VERSION=$(echo $THE_PKG_VERSION | cut -d '.' -f 2 | xargs)
    THE_VERSION_VALUE=$(((${THE_PKG_MAIN_VERSION:0:2}*100)+${THE_PKG_SUB_VERSION:0:2}))
    if [ $THE_VERSION_VALUE -lt $THE_TEST_VALUE ];
    then
      # ---------------------------------------------
      # Die installierte oder verfügbare Version ist
      # kleiner als die gefragte Version (Warnung)
      # ---------------------------------------------
      CHK_MIN_RESULT=1
    else
      # ----------------------------------------------
      # Die installierte oder verfügbare Version ist
      # größer oder gleich der gefragten Version (Ok)
      # ----------------------------------------------
      CHK_MIN_RESULT=0
    fi
  else
    # ---------------------------------------------
    # Die installierte oder verfügbare Version ist
    # nicht ermittelbar (Fehler)
    # ---------------------------------------------
    CHK_MIN_RESULT=-1
  fi
  return $CHK_MIN_RESULT
}

#===============================================================================
# Aufräumen bei Programmende
#===============================================================================
function clean_on_exit {
  remove_file "$LOG_TEMP"
  if [ "$DOWNLOAD_DIR" != "" ] &&
     [ "$DOWNLOAD_DIR" != "/" ] &&
     [ "$DOWNLOAD_DIR" != "/tmp" ] &&
     [ -d "$DOWNLOAD_DIR" ];
  then
    # --------------------------------------------------------
    # Wenn gewünscht alle Dateien im Download-Ordner löschen
    # (dabei eigene Logs und zu erhaltende Listen auslassen)
    # --------------------------------------------------------
    if [ ${OPTION_FLAG[cleantmp]} -eq 1 ];
    then
      remove_file "$FLATPAK_INSTALLED_PKG_LIST"
      remove_file "$SNAP_INSTALLED_PKG_LIST"
      remove_file "$SNAP_SNAPSHOT_LIST"
      find "$DOWNLOAD_DIR" -type f -not -name "${LOG_FILE##*/}" -and -not -iregex ".*\.list$" -and -not -iregex ".*\.save$" -delete 2>/dev/null
      find "$DOWNLOAD_DIR" -type f -size 0 -delete 2>/dev/null
    fi
    # -------------------------------------------------------
    # Alle verbliebenen Dateien dem Benutzer zu eigen machen
    # -------------------------------------------------------
    chown -R "$USER_USERNAME:$USER_USERNAME" "$DOWNLOAD_DIR" &>/dev/null
    # ----------------------------------------------------------------
    # Download-Ordner ganz löschen wenn keine Dateien mehr darin sind
    # ----------------------------------------------------------------
    if [ $(ls -A "$DOWNLOAD_DIR" | wc -w) -eq 0 ];
    then
      rmdir "$DOWNLOAD_DIR" &>/dev/null
    fi
  fi
  setterm -cursor on 2>/dev/null
}

#===============================================================================
# Bereinigung einer Paketversion auf ihre ersten drei Teile
#===============================================================================
function clean_pkg_version {
  echo -e -n $(echo "$1" | \
  awk '{print $1}' | \
  sed -E "s/^(.*:)*(.*)/\2/" | \
  sed -E "s/[^0-9\.]/./g" | \
  sed -E "s/\.\.*/./g" | \
  sed -E "s/^\.//" | \
  sed -E "s/\.$//" | \
  sed -E "s/([0-9]*\.*[0-9]*\.*[0-9]*\.*[0-9]*).*/\1/" | \
  sed -E "s/\.$//" | \
  xargs 2>/dev/null)
}

#===============================================================================
# Bereinigung des Repo nach nicht erfolgreicher Installation
# (Löschen der Datei mit den Quell-Angaben um System-Updates nicht zu stören)
#===============================================================================
function clear_repo {
  REPO_FILE="$1"
  # --------------------------
  # Durch uns angelegte Datei
  # --------------------------
  LOCAL_REPO_FILE="$APT_SOURCES_LIST_DIR/$REPO_FILE.list"
  remove_file "$LOCAL_REPO_FILE"
  # ------------------------------------------------------------
  # Soweit bekannt durch das Paket/PPA selbst angelegte Dateien
  # ------------------------------------------------------------
  LOCAL_REPO_FILE=${PPA_REPO_SRC["$REPO_FILE"]}
  if [ "$LOCAL_REPO_FILE" != "" ];
  then
    # -----------------------------------------------------------
    # ACHTUNG: NICHT mit remove_file und OHNE Anführungszeichen,
    # damit mit * gelöscht werden kann
    # -----------------------------------------------------------
    rm -f $APT_SOURCES_LIST_DIR/$LOCAL_REPO_FILE &>/dev/null
  fi
}

#===============================================================================
# Bereinigt einen Text von Steuerzeichen und sonstigen nicht druckbaren Zeichen
#===============================================================================
function clear_text {
  # -------------------------------------------
  # Alle Steuerzeichen und Farbcodes entfernen
  # -------------------------------------------
  NEW_TEXT="$(echo -e "$1" | tr -dc '[:print:][:space:]\n\säöüÄÖÜß' | sed -E "s/\[[0-9]+;[0-9]+m//gi" | sed -E "s/\[0m//gi")"
  # ---------------------------------
  # Fehler und Warnungen hervorheben
  # ---------------------------------
  NEW_TEXT=${NEW_TEXT//error/ERROR}
  NEW_TEXT=${NEW_TEXT//Fehler/FEHLER}
  NEW_TEXT=${NEW_TEXT// nicht / NICHT }
  NEW_TEXT=${NEW_TEXT//Warnung/WARNUNG}
  echo -e -n "$NEW_TEXT"
}

# ==============================================================================
# Farb-Code zu einem Farb-Index erzeugen
# ==============================================================================
function color_idx_code {
  col_idx=$1
  # 0 .. 7 sind normal
  if [ $col_idx -lt 8 ];
  then
    COLOR_CODE="3$col_idx"
  # 8 .. 15 sind hell
  else
    COLOR_CODE="9$((col_idx-8))"
  fi
  echo -e -n '\033[0;'"$COLOR_CODE"'m'
}

# ==============================================================================
# Farbe (Index) durch den Benutzer auswählen lassen
# ==============================================================================
function color_select {
  COLOR_QUEST="$1"
  echo -e "$HALF_MINUS_LINE"
  echo -e " Farbe für ${light_yellow}$COLOR_QUEST${colors_off} auswählen,"
  echo -e " folgende Farben stehen zur Verfügung:"
  MAX_COL_IDX=${#ANSI_COLOR_NAMES[@]}
  i=0
  while [ $i -lt $MAX_COL_IDX ];
  do
    color_code="$(color_idx_code $i)"
    echo -e -n " "
    if [ $i -lt 10 ]; then echo -e -n " "; fi
    echo -e "[${bold_yellow}$i${colors_off}] ${color_code}${ANSI_COLOR_NAMES[$i]}${colors_off}"
    ((i+=1))
  done
  NEW_COLOR=-1
  while [ $NEW_COLOR -lt 0 ] ||
        [ $NEW_COLOR -ge $MAX_COL_IDX ];
  do
    echo -e -n " Bitte Farbcode [${bold_white}Nummer${colors_off}] eingeben: "
    read -r NEW_COLOR
    NEW_COLOR=$(echo ${NEW_COLOR} | sed -E "s/[^0-9]*//gi" | xargs 2>/dev/null)
    if [ "$NEW_COLOR" == "" ];
    then
      NEW_COLOR=-1
    fi
  done
  return $NEW_COLOR
}

#===============================================================================
# Kopieren einer Liste von Startern
#===============================================================================
function copy_starter_list {
  # ---------------------------------
  # Ergebnisliste in Array umwandeln
  # ---------------------------------
  IFS=$'\n' FILE_LIST_ARRAY=(${SEARCH_STARTER_RESULT})
  IFS=' '
  # ---------------------------------------------
  # Wenn Dateien gefunden wurden, diese kopieren
  # ---------------------------------------------
  if [ ${#FILE_LIST_ARRAY[@]} -gt 0 ];
  then
    for desktop_starter in ${FILE_LIST_ARRAY[@]};
    do
      DESKTOP_STARTER_NAME="${desktop_starter##*/}"
      DESKTOP_STARTER_NAME="${DESKTOP_STARTER_NAME/.desktop/}"
      REJECT_THIS=0
      # ---------------------------------------------------------------
      # Individuell (in dieser Kategorie) auszulassende Starter prüfen
      # (Auf grundsätzlich auszulassende Starter wird zudem in
      #  copy_starter_to_desktop geprüft)
      # ---------------------------------------------------------------
      if [ ${#EXCLUDE_STARTER_LIST[@]} -gt 0 ];
      then
        for reject_file in ${EXCLUDE_STARTER_LIST[@]};
        do
          if [ "$DESKTOP_STARTER_NAME" != "" ] &&
             [ "$DESKTOP_STARTER_NAME" == "$reject_file" ];
          then
            REJECT_THIS=1
            break
          fi
        done
      fi
      # -------------------------------------
      # Auszulassende Dateien nicht kopieren
      # -------------------------------------
      if [ $REJECT_THIS -eq 0 ];
      then
        copy_starter_to_desktop "$desktop_starter" "" 0
      fi
    done
  fi
  e_and_l "$OK_TAG"
  e_and_l " - Es wurden ${bold_green}$NEW_STARTER_COUNTER${colors_off} neue Starter erstellt"
  ((ALL_STARTER_COUNTER+=NEW_STARTER_COUNTER))
}

#===============================================================================
# Erstellung von Startern (Desktop-Symbole) mittels Kopie der Menü-Einträge ;)
# ------------------------------------------------------------------------------
# Parameter $1: Wird bei Aufruf ein Dateiname mit festem Pfad übergeben
#               (erstes Zeichen ein /), dann wird diese Datei als Quelle
#               verwendet und kopiert, ansonsten ist $1 der Paketname,
#               zu welchem zuvor erst noch passende Starter gesucht werden
# Parameter $2: Zielordner - wenn nicht angegeben, wird dieser anhand der
#               aktuellen Kategorie ermittelt und ggf. angelegt
# Parameter $3: Nur nach exakt dem in $1 angegebenen Dateinamen suchen (1)
#               oder auch nach ähnlichen Namen und zudem auch nach Vorkommen
#               des Strings in $1 in allen .desktop-Dateien (0)
# ------------------------------------------------------------------------------
# Rückgaben: 0 = OK, Starter erstellt
#            1 = KEIN Starter erstellt
#===============================================================================
function copy_starter_to_desktop {
  # --------------------------------------------------------------------------
  # Ohne Auswahl einer gültigen Option keinen Starter auf dem Desktop anlegen
  # --------------------------------------------------------------------------
  if [ ${OPTION_FLAG[addstart]} -ne 1 ];
  then
    return 1
  fi

  # ----------------------------------------------
  # Zielordner verwenden wenn angegeben, ansonsten
  # den Zielordner anhand der Kategorie ermitteln
  # ----------------------------------------------
  if [ "$2" != "" ];
  then
    STARTER_TARGET_DIR="$2"
  else
    STARTER_TARGET_DIR="$DESKTOP_STARTER_DIR/${KAT_SHORT_NAME%% (*}"
  fi

  SEARCH_EXACT_NAME=$3

  COPY_DESKTOP_STARTER_RESULT=1

  if [ "$DESKTOP_DIR" != "" ];
  then

    # ------------------------------------------------------
    # Kategorien mit Programmpaketen ohne Starter auslassen
    # ------------------------------------------------------
    if [ "$CURRENT_CATEGORY" != "a" ] &&
       [ "$CURRENT_CATEGORY" != "d" ] &&
       [ "$CURRENT_CATEGORY" != "f" ] &&
       [ "$CURRENT_CATEGORY" != "u" ] &&
       [ "$CURRENT_CATEGORY" != "x" ] &&
       [ "$CURRENT_CATEGORY" != "xx" ];
    then

      # -------------------------------------------------------------------
      # Hauptordner "Neue Starter" erstellen (nicht mit GNOME, dort werden
      # die Starter ohne Ordnerstruktur direkt auf dem Desktop angelegt)
      # -------------------------------------------------------------------
      if [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
      then
        if [ ! -d "$DESKTOP_STARTER_DIR" ];
        then
          mkdir -p "$DESKTOP_STARTER_DIR" &>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$DESKTOP_STARTER_DIR" &>/dev/null
            chmod -R 0755 "$DESKTOP_STARTER_DIR" &>/dev/null
          fi
        fi
      fi

      # ------------------------------------------------
      # Nur weitermachen wenn der Hauptordner existiert
      # ------------------------------------------------
      if [ -d "$DESKTOP_STARTER_DIR" ];
      then

        # ---------------------------------------------------------------
        # Unterordner für aktuelle Kategorie erstellen (nicht mit GNOME)
        # ---------------------------------------------------------------
        if [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
        then
          # ---------------------------------------------------------
          # Wenn es den Zielordner noch nicht gibt, diesen erstellen
          # ---------------------------------------------------------
          if [ ! -d "$STARTER_TARGET_DIR" ];
          then
            mkdir -p "$STARTER_TARGET_DIR" &>/dev/null
            if [ $? -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "$STARTER_TARGET_DIR" &>/dev/null
              chmod -R 0755 "$STARTER_TARGET_DIR" &>/dev/null
            else
              STARTER_TARGET_DIR="$DESKTOP_STARTER_DIR"
            fi
          fi

        else
          STARTER_TARGET_DIR="$DESKTOP_STARTER_DIR"
        fi

        # ------------------------------------------------
        # Nur weitermachen wenn der Ziel-Ordner existiert
        # ------------------------------------------------
        if [ -d "$STARTER_TARGET_DIR" ];
        then

          # -----------------------------------------------------------------
          # Wenn der erste Parameter kein vorgegebener Pfad ist, dann ist
          # dieser ein Paketname, zu dem passende Starter zu suchen sind ...
          # -----------------------------------------------------------------
          if [ "${1:0:1}" != "/" ];
          then

            if [ $SEARCH_EXACT_NAME -eq 1 ];
            then
              SEARCH_NAME="$1"
            else
              SEARCH_NAME=$(probe_starter_name "$1")
            fi
            SEARCH_RESULT_ALL=()

            # ---------------------------------------
            # 1. Dateiname entspricht dem Paketnamen
            # ---------------------------------------
            # 1.1. Datei mit Paketnamen im Raspi-Ordner suchen
            if [ -d "/usr/share/raspi-ui-overrides/applications" ];
            then
              SEARCH_RESULT_TMP=$(find "/usr/share/raspi-ui-overrides/applications" -iname "$SEARCH_NAME".desktop -print 2>/dev/null)
              # echo -e "1.1: $SEARCH_RESULT_TMP"
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
            fi

            # 1.2. Datei mit Paketnamen im Benutzer-Ordner suchen
            SEARCH_RESULT_TMP=$(find "$STARTMENU_DIR/" -iname "$SEARCH_NAME".desktop -print 2>/dev/null)
            # echo -e "1.2: $SEARCH_RESULT_TMP"
            if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi

            # 1.3. Datei mit Paketnamen im System-Ordner suchen
            SEARCH_RESULT_TMP=$(find "$GLOBAL_STARTER_DIR" -iname "$SEARCH_NAME".desktop -print 2>/dev/null)
            # echo -e "1.3: $SEARCH_RESULT_TMP"
            if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi

            # 1.4. Datei mit Paketnamen im Snap-Ordner suchen
            if [ -d "/var/lib/snapd/desktop/applications" ];
            then
              SEARCH_RESULT_TMP=$(find /var/lib/snapd/desktop/applications -iname "$SEARCH_NAME".desktop -print 2>/dev/null)
              # echo -e "1.4: $SEARCH_RESULT_TMP"
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
            fi

            if [ $SEARCH_EXACT_NAME -ne 1 ];
            then

              # --------------------------------
              # 2. Paketname kommt in Datei vor
              # --------------------------------
              # 2.1. Auftreten des Paketnamens innerhalb der Dateien im Benutzer-Ordner suchen
              SEARCH_RESULT_TMP=$(grep -i -l -o -r -E "^(exec|name|icon|comment)\s*=\s*(/usr/bin/)*\b$SEARCH_NAME\b" "$STARTMENU_DIR/"* 2>/dev/null)
              # echo -e "2.1: $SEARCH_RESULT_TMP"
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi

              # 2.2. Auftreten des Paketnamens innerhalb der Dateien im System-Ordner suchen
              SEARCH_RESULT_TMP=$(grep -i -l -o -r -E "^(exec|name|icon|comment)\s*=\s*(/usr/bin/)*\b$SEARCH_NAME\b" "$GLOBAL_STARTER_DIR/"* 2>/dev/null)
              # echo -e "2.2: $SEARCH_RESULT_TMP"
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi

              # 2.3. Auftreten des Paketnamens innerhalb der Dateien im System-Ordner suchen
              # echo -e "2.3: $SEARCH_RESULT_TMP"
              SEARCH_RESULT_TMP=$(grep -i -l -o -r -E "(X-Ubuntu-Gettext-Domain)=\b$SEARCH_NAME\b" "$GLOBAL_STARTER_DIR/"* 2>/dev/null)
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi

              # 2.4. Auftreten des Paketnamens innerhalb der Dateien im Snap-Ordner suchen
              if [ -d "/var/lib/snapd/desktop/applications" ];
              then
                # Bei Snaps liegen die Starter nicht alle in einem separaten Ordner, sondern
                # zusammen mit diversen Binärdateien unter einem Pfad. Daher wird dem grep hier
                # ein find vorangestellt, um nur die .desktop-Dateien durchsuchen zu müssen.
                SEARCH_RESULT_TMP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -exec grep -i -l -o -E "^(exec|name|icon|comment)\s*=\s*(/usr/bin/)*\b$SEARCH_NAME\b" {} \;)
                # echo -e "2.4.1: $SEARCH_RESULT_TMP"
                if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
                SEARCH_RESULT_TMP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -exec grep -i -l -o -E "(X-SnapInstanceName)=\b$SEARCH_NAME\b" {} \;)
                # echo -e "2.4.2: $SEARCH_RESULT_TMP"
                if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
              fi

              # 2.5. Auftreten des Paketnamens innerhalb der Dateien im Flatpak-Ordner suchen
              if [ -d "/var/lib/flatpak/app" ];
              then
                # Bei Flatpaks heißen die Starter wie der Referenz-Text der Pakete.
                # Blöderweise gibt es davon gleich mehrere, von denen aber nicht alle
                # funktionieren, weil diese nur den Paketnamen ohne den erforderlichen
                # vollständigen Aufruf per flatpak-Kommando beinhalten!
                THE_FLATPAK_REF_STRING=$(get_pkg_flatpak_reference ${SEARCH_NAME} 1)
                if [ "$THE_FLATPAK_REF_STRING" != "" ];
                then
                  # Bei Flatpaks liegen die Starter nicht alle in einem separaten Ordner, sondern
                  # zusammen mit diversen Binärdateien unter einem Pfad. Daher wird dem grep hier
                  # ein find vorangestellt, um nur die .desktop-Dateien durchsuchen zu müssen.
                  SEARCH_RESULT_TMP=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -exec grep -i -l -o -E "^\s*exec\s*=\s*(/usr/bin/flatpak)(.)*$THE_FLATPAK_REF_STRING" {} \;)
                  # echo -e "2.5: $SEARCH_RESULT_TMP"
                  if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
                fi
              fi

            fi

            # ------------------------------------------------------------------
            # 3. Dateinamen aus vordefinierter Liste PKG_STARTER_LIST verwenden
            # ------------------------------------------------------------------
            tmp_list=${PKG_STARTER_LIST[$SEARCH_NAME]};
            if [ "$tmp_list" != "" ];
            then
              SEARCH_RESULT_TMP=""
              for starter_file in ${tmp_list[@]};
              do
                full_starter_file_path="$GLOBAL_STARTER_DIR/$starter_file.desktop"
                if [ -s "$full_starter_file_path" ];
                then
                  SEARCH_RESULT_TMP+=$full_starter_file_path
                  SEARCH_RESULT_TMP+=$'\n'
                fi
              done
              # echo -e "3: $SEARCH_RESULT_TMP"
              if [ "$SEARCH_RESULT_TMP" != "" ]; then SEARCH_RESULT_ALL+=$'\n'"$SEARCH_RESULT_TMP"; fi
            fi

            # ------------------------------------------------------------------
            # Ergebnisliste in Array umwandeln
            # ------------------------------------------------------------------
            IFS=$'\n' STARTER_LIST_ARRAY=(${SEARCH_RESULT_ALL})
            IFS=' '

          # --------------------------------------------------------------------
          # ... sonst, wenn mit Aufruf eines vorgegebenen Pfads (zwecks Nutzung
          # dieser Funktion angegeben in einer Liste mit nur einem Eintrag)
          # --------------------------------------------------------------------
          else

            IFS=$'\n' STARTER_LIST_ARRAY=(${1})
            IFS=' '
            SEARCH_NAME=$(probe_starter_name "$(echo ${STARTER_LIST_ARRAY[0]##*/} | sed -E "s/\.desktop$//i")" | sed -E "s/org\.gnome\./gnome-/i" | tr '[:upper:]' '[:lower:]')

          fi

          # --------------------------------------------------------------------
          # Wenn Dateien gefunden wurden, diese kopieren
          # --------------------------------------------------------------------
          if [ ${#STARTER_LIST_ARRAY[@]} -gt 0 ];
          then

            # -------------------------------------
            # Extra-Ordner prüfen und ggf. anlegen
            # -------------------------------------
            if [ "${PKG_STARTER_XDIR[$SEARCH_NAME]}" != "" ];
            then
              STARTER_TARGET_DIR+="/${PKG_STARTER_XDIR[$SEARCH_NAME]}"
              if [ ! -d "$STARTER_TARGET_DIR" ];
              then
                ORG_STARTER_TARGET_DIR="$STARTER_TARGET_DIR"
                mkdir -p "$STARTER_TARGET_DIR" &>/dev/null
                if [ $? -eq 0 ];
                then
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$STARTER_TARGET_DIR" &>/dev/null
                  chmod -R 0755 "$STARTER_TARGET_DIR" &>/dev/null
                else
                  STARTER_TARGET_DIR="$ORG_STARTER_TARGET_DIR"
                fi
              fi
            fi

            # ------------------------------------------------
            # Zusätzliche Unterordner prüfen und ggf. anlegen
            # ------------------------------------------------
            if [ ${OPTION_FLAG[csubdirs]} -eq 1 ];
            then
              for sub_folder in ${GAME_DIR_CAT_LIST[@]};
              do
                for paket_for_folder in ${GAME_DIR_SUB_LIST[$sub_folder]};
                do
                  if [ "$paket_for_folder" == "$SEARCH_NAME" ];
                  then
                    STARTER_TARGET_DIR+="/${GAME_DIR_SUB_NAME[$sub_folder]}"
                    if [ ! -d "$STARTER_TARGET_DIR" ];
                    then
                      ORG_STARTER_TARGET_DIR="$STARTER_TARGET_DIR"
                      mkdir -p "$STARTER_TARGET_DIR" &>/dev/null
                      if [ $? -eq 0 ];
                      then
                        chown -R "$USER_USERNAME:$USER_USERNAME" "$STARTER_TARGET_DIR" &>/dev/null
                        chmod -R 0755 "$STARTER_TARGET_DIR" &>/dev/null
                      else
                        STARTER_TARGET_DIR="$ORG_STARTER_TARGET_DIR"
                      fi
                    fi
                    break
                  fi
                done
              done
            fi

            # --------------------------------------------
            # Alle gefundenen Starter prüfen und kopieren
            # --------------------------------------------
            for desktop_file in ${STARTER_LIST_ARRAY[@]};
            do
              # -------------------------------------------
              # Nur existierende .desktop-Dateien kopieren
              # -------------------------------------------
              if [ -f "$desktop_file" ] &&
                 [ "${desktop_file:(-8):8}" == ".desktop" ];
              then
                FILE_BASE_NAME="${desktop_file##*/}"
                # -----------------------------------------
                # Nur nicht auszulassende Dateien kopieren
                # -----------------------------------------
                REJECT_THIS=0
                for reject_file in ${REJECT_STARTER[@]};
                do
                  if [ $(echo -n "$FILE_BASE_NAME" | grep -i -c -E "$reject_file") -gt 0 ];
                  then
                    REJECT_THIS=1
                    break
                  fi
                done
                if [ $REJECT_THIS -eq 0 ];
                then
                  # -------------------------------------------------------
                  # Nur nicht in Datei als auszublendende Starter anzeigen
                  # -------------------------------------------------------
                  SKIP_THIS_STARTER=0
                  NO_DISPLAY_TXT="\s*NoDisplay\s*=\s*true"
                  NOTSHOWIN_TXT="\s*NotShowIn\s*=(.*)$DESKTOP_ENVIRONMENT\;"
                  if [ $(grep -i -c -E "$NO_DISPLAY_TXT" "$desktop_file") -gt 0 ] ||
                     [ $(grep -i -c -E "$NOTSHOWIN_TXT" "$desktop_file") -gt 0 ];
                  then
                    SKIP_THIS_STARTER=1
                  fi
                  FORCE_THIS=0
                  for force_pkg_file in ${FORCE_STARTER[@]};
                  do
                    if [ "$force_pkg_file" == "$1" ];
                    then
                      FORCE_THIS=1
                      break
                    fi
                  done
                  ONLYSHOWIN_TXT="\s*OnlyShowIn\s*=(.*)$DESKTOP_ENVIRONMENT\;"
                  if [ $FORCE_THIS -eq 1 ] ||                                             # Bei force immer, ansonsten
                     [ $(echo -n "$desktop_file" | grep -i -c -E "overrides" ) -gt 0 ] || # auch wenn "Override" enthalten
                     [ $(grep -i -c -E "$ONLYSHOWIN_TXT" "$desktop_file") -gt 0 ];        # auch wenn "OnlyShowIn=DESKTOP" enthalten
                  then
                    SKIP_THIS_STARTER=0
                  fi
                  if [ $SKIP_THIS_STARTER -eq 0 ];
                  then
                    # ---------------------------------------------------------
                    # Programmaufruf des Starters zwecks Vergleich extrahieren
                    # ---------------------------------------------------------
                    ORG_STARTER_EXEC="$(grep -i -E "^\s*exec\s*=" "$desktop_file" | tr '[:upper:]' '[:lower:]' | xargs 2>/dev/null)"
                    # --------------------------------------------------------
                    # Wenn es den zu erstellenden Starter schon gibt, dann
                    # prüfen ob dieser den selben Programmaufruf beinhaltet.
                    # So können Starter von gleichen Paketen in verschiedenen
                    # Versionen erkannt werden, obwohl ihre Starter-Dateien
                    # den selben Namen haben ;)
                    # --------------------------------------------------------
                    TARGET_FILE_NAME="$STARTER_TARGET_DIR/$FILE_BASE_NAME"
                    EQUAL_STARTER_FOUND=0
                    if [ -s "$TARGET_FILE_NAME" ];
                    then
                      # ------------------------------------------------------
                      # Wenn nicht identisch, neuen Dateinamen ermitteln. Dazu
                      # solange dem Namen eine aufsteigende Nummer hinzufügen,
                      # bis es eine Datei mit dem Namen nicht gibt, oder diese
                      # Datei wiederum den gleichen Programmaufruf beinhaltet.
                      # In Letzterem Fall wird die Suche abgebrochen und der
                      # Starter nachfolgend nicht kopiert, weil es ja bereits
                      # einen adäquaten Starter in dem Zielverzeichnis gibt ;)
                      # ------------------------------------------------------
                      TRY_STARTER_EXEC="$(grep -i -E "^\s*exec\s*=" "$TARGET_FILE_NAME" | tr '[:upper:]' '[:lower:]' | xargs 2>/dev/null)"
                      if [ "$TRY_STARTER_EXEC" == "$ORG_STARTER_EXEC" ];
                      then
                        EQUAL_STARTER_FOUND=1
                      fi
                      if [ $EQUAL_STARTER_FOUND -eq 0 ];
                      then
                        FILE_EXT_NR=2
                        while [ -s "$TARGET_FILE_NAME" ] &&
                              [ $EQUAL_STARTER_FOUND -eq 0 ];
                        do
                          TRY_FILE_NAME="$(echo ${FILE_BASE_NAME} | sed -E "s/\.desktop$/_$FILE_EXT_NR.desktop/i")"
                          TARGET_FILE_NAME="$STARTER_TARGET_DIR/$TRY_FILE_NAME"
                          if [ -s "$TARGET_FILE_NAME" ];
                          then
                            TRY_STARTER_EXEC="$(grep -i -E "^\s*exec\s*=" "$TARGET_FILE_NAME" | tr '[:upper:]' '[:lower:]' | xargs 2>/dev/null)"
                            if [ "$TRY_STARTER_EXEC" == "$ORG_STARTER_EXEC" ];
                            then
                              EQUAL_STARTER_FOUND=1
                            fi
                          fi
                          ((FILE_EXT_NR+=1))
                        done
                      else
                        EQUAL_STARTER_FOUND=1
                      fi
                    fi
                    # ---------------------------------------------
                    # Starter kopieren wenn es ihn noch nicht gibt
                    # ---------------------------------------------
                    if [ ! -s "$TARGET_FILE_NAME" ] &&
                       [ $EQUAL_STARTER_FOUND -eq 0 ];
                    then
                      cp -f "$desktop_file" "$TARGET_FILE_NAME" &>/dev/null
                      if [ $? -eq 0 ];
                      then
                        do_log "$PRE_SPACE Starter für $SEARCH_NAME angelegt: $TARGET_FILE_NAME"
                        ((NEW_STARTER_COUNTER+=1))
                        # -------------------------------------------------
                        # Sicherheitshalber nochmals Zugriffsrechte setzen
                        # -------------------------------------------------
                        chown -R "$USER_USERNAME:$USER_USERNAME" "$TARGET_FILE_NAME" &>/dev/null
                        chmod -R 0755 "$TARGET_FILE_NAME" &>/dev/null
                        COPY_DESKTOP_STARTER_RESULT=0
                      else
                        do_log "$PRE_SPACE $ERROR_TAG beim Kopieren des Starters für $SEARCH_NAME nach $TARGET_FILE_NAME"
                      fi
                    fi
                    make_starter_trusted "$TARGET_FILE_NAME"
                    # ------------------------------------------------------
                    # Icon (Bilddatei) mit identischem Namen des Starters herunterladen
                    # Achtung: Nicht nur EIN ".desktop" am Ende, da es Starter wie den
                    # von Telegram gibt, die warum auch immer ZWEI .desktop am Ende haben
                    # ------------------------------------------------------
                    FILE_PURE_NAME="$(echo ${FILE_BASE_NAME} | sed 's/.desktop//gi')"
                    download_icon_file "$FILE_PURE_NAME" 0
                    # ------------------------------------------------------
                    # Icon mit identischem Namen des Pakets herunterladen
                    # ------------------------------------------------------
                    if [ "$FILE_PURE_NAME" != "$1" ];
                    then
                      download_icon_file "$1" 0
                    fi
                    # --------------------------------------------------------
                    # Wenn das im Starter angegebene Icon nicht existiert,
                    # oder nicht im Such-Pfad zu finden ist (kommt bspw.
                    # bei Flatpaks auf Ubuntu vor - warum wohl ...), aber
                    # ein dazu passendes (heruntergeladenes) Icon existiert,
                    # dann dieses Icon im kopierten Starter eintragen.
                    # --------------------------------------------------------
                    ORG_ICON="$(grep -i -E "^\s*Icon\s*=" "$TARGET_FILE_NAME" | head -n 1 | cut -d"=" -f 2 | xargs 2>/dev/null)"
                    # --------------------------------------
                    # Im Starter referenziertes Icon suchen
                    # --------------------------------------
                    ICON_FOUND=0
                    if [ "$ORG_ICON" != "" ];
                    then
                      # ------------------------------------------------------
                      # Mit (absoluten) Pfadangaben konkrete Datei prüfen ...
                      # ------------------------------------------------------
                      if [ $(echo ${ORG_ICON} | grep -i -c -E "\/") -gt 0 ];
                      then
                        if [ -s "$ORG_ICON" ]; then ICON_FOUND=1; fi
                      # ------------------------------------------------------
                      # ... sonst Icon (Bilddatei) in Standard-Ordnern suchen
                      # ------------------------------------------------------
                      else
                        # --------------
                        # Pixmap-Ordner
                        # --------------
                        if [ $(find "$PKG_IPIX_DIR" -iname "$ORG_ICON.png" -or -iname "$ORG_ICON.svg" 2>/dev/null | wc -l) -gt 0 ];
                        then
                          ICON_FOUND=2
                        else
                          # ------------------------
                          # Alle System-Icon-Ordner
                          # ------------------------
                          if [ $(find "$PKG_ICON_DIR" -iname "$ORG_ICON.png" -or -iname "$ORG_ICON.svg" 2>/dev/null | wc -l) -gt 0 ];
                          then
                            ICON_FOUND=3
                          else
                            # --------------------
                            # Alle Flatpak-Ordner
                            # --------------------
                            if [ $(find /var/lib/flatpak/app/ -iname "$ORG_ICON.png" -or -iname "$ORG_ICON.svg" 2>/dev/null | wc -l) -gt 0 ];
                            then
                              ICON_FOUND=4
                            fi
                          fi
                        fi
                      fi
                    fi
                    # ------------------------------------------------------
                    # Wenn das im Starter referenzierte Icon nicht gefunden
                    # wurde, prüfen ob es in dem Pixmap-Ordner ein anderes
                    # dazu passendes Icon gibt
                    # ------------------------------------------------------
                    if [ $ICON_FOUND -eq 0 ];
                    then
                      NEW_ICON_ENTRY=""
                      # ----------------------------------
                      # Datei mit Namen der Starter-Datei
                      # ----------------------------------
                      TEST_ICON="$PKG_IPIX_DIR/$FILE_PURE_NAME.png"
                      if [ -s "$TEST_ICON" ];
                      then
                        NEW_ICON_ENTRY="$TEST_ICON"
                      else
                        # -----------------------------------
                        # Datei mit Namen des Programmpakets
                        # -----------------------------------
                        TEST_ICON="$PKG_IPIX_DIR/$1.png"
                        if [ -s "$TEST_ICON" ];
                        then
                          NEW_ICON_ENTRY="$TEST_ICON"
                        fi
                      fi
                      # -----------------------------------------
                      # Wenn ein anderes passendes Icon gefunden
                      # wurde, dann dieses im Starter eintragen
                      # -----------------------------------------
                      if [ "$NEW_ICON_ENTRY" != "" ];
                      then
                        # Hinweis: Da in dem Pfadnamen ein / vorkommen kann,
                        # wird statt dessen | als Seperator verwendet, weil
                        # dieses zeichen in Pfadnamen nicht vorkommen kann ;)
                        sed -i -E "s|Icon=${ORG_ICON}|Icon=${NEW_ICON_ENTRY}|gi" "$TARGET_FILE_NAME" 2>/dev/null
                      fi
                    fi
                  fi # SKIP_THIS_STARTER
                fi # Ende REJECT_THIS
              fi # Ende "Endung .desktop"
            done
          fi
        fi
      fi
    fi
  fi
  return $COPY_DESKTOP_STARTER_RESULT
}

#===============================================================================
# Erstellung einer Autostart-Datei
#===============================================================================
function create_autostart_file {
  if [ ! -d "$USER_CONFIG_DIR/autostart" ];
  then
    mkdir -p "$USER_CONFIG_DIR/autostart" &>/dev/null
    chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_CONFIG_DIR/autostart" &>/dev/null
  fi
  echo -e "[Desktop Entry]" > "$1" 2>/dev/null
  echo -e "Type=Application" >> "$1" 2>/dev/null
  echo -e "Name=$2" >> "$1" 2>/dev/null
  echo -e "Comment=$3" >> "$1" 2>/dev/null
  echo -e "Exec=$4" >> "$1" 2>/dev/null
  echo -e "Icon=$5" >> "$1" 2>/dev/null
  echo -e "Terminal=false" >> "$1" 2>/dev/null
  echo -e "NoDisplay=false" >> "$1" 2>/dev/null
  echo -e "Hidden=false" >> "$1" 2>/dev/null
  echo -e "X-GNOME-Autostart-enabled=true" >> "$1" 2>/dev/null
  echo -e "X-MATE-Autostart-enabled=true" >> "$1" 2>/dev/null
  chown -R "$USER_USERNAME:$USER_USERNAME" "$1" &>/dev/null
  chmod -R 0644 "$1" &>/dev/null
  return $?
}

#===============================================================================
# Erstellung einer Backup-Datei
# - erstmalig vom Original (.save), wenn es die Backup-Datei noch nicht gibt
# - rollierend als neues Backup (.bak), wenn es die Backup-Datei schon gibt
# ACHTUNG: Leere Dateien werden nicht berücksichtigt und nicht kopiert!
#===============================================================================
function create_backup_file {
  FILE_TO_BACKUP="$1"
  if [ -s "$FILE_TO_BACKUP" ];
  then
    if [ ! -s "$FILE_TO_BACKUP.save" ];
    then
      cp -f "$FILE_TO_BACKUP" "$FILE_TO_BACKUP.save" &>/dev/null
    else
      cp -f "$FILE_TO_BACKUP" "$FILE_TO_BACKUP.bak" &>/dev/null
    fi
  fi
}

#===============================================================================
# Liste der Pakete einer Kategorie erstellen und dabei automatisch
# zu ergänzende Pakete hinzufügen
#===============================================================================
function create_cat_pkg_list {
  TMP_LIST="${KATEGORIE_PKGS[$k]}"
  for p in ${TMP_LIST[@]};
  do
    ADDITIONAL_PACKS="${AUTO_ADD_PKGS[$p]}"
    if [ "$ADDITIONAL_PACKS" != "" ];
    then
      if [ "${AUTO_ADD_PPOS[$p]}" != "true" ];
      then
        # --------------------------------------------
        # Zusätzliche Pakete NACH Basispaket einfügen
        # --------------------------------------------
        TMP_LIST=$(echo " $TMP_LIST " | sed -E "s/ $p / $p $ADDITIONAL_PACKS /")
      else
        # -------------------------------------------
        # Zusätzliche Pakete VOR Basispaket einfügen
        # -------------------------------------------
        TMP_LIST=$(echo " $TMP_LIST " | sed -E "s/ $p / $ADDITIONAL_PACKS $p /")
      fi
    fi
  done
  # -------------------------------------------
  # Tabelle aus der Liste der Pakete erstellen
  # -------------------------------------------
  CAT_PKG_LIST=(${TMP_LIST})
  CURRENT_CATEGORY="$k"
  KAT_SHORT_NAME="${KATEGORIE_TEXT[$CURRENT_CATEGORY]}"
}

#===============================================================================
# Kommandozeilen-Aufruf mit Parametern erstellen
#===============================================================================
function create_command_line {
  COMMAND_LINE_STRING=""
  # ----------------------------------------------------------------------------
  # Individuelle Liste
  # ----------------------------------------------------------------------------
  if [ $USE_ILIST_FILE -eq 1 ];
  then
    COMMAND_LINE_STRING+=" instlist \"$INST_LIST_FILE\""
  fi
  # ----------------------------------------------------------------------------
  # Individuelles Paket
  # ----------------------------------------------------------------------------
  if [ "$INST_ONLY_PKG" != "" ];
  then
    COMMAND_LINE_STRING+=" instonly $INST_ONLY_PKG"
  # ----------------------------------------------------------------------------
  # Kategorien
  # ----------------------------------------------------------------------------
  else
    # --------------------
    # Standard-Kategorien
    # --------------------
    skipped_found=0
    for i in ${KAT_KEYS_STD[@]};
    do
      if [ ${KATEGORIE_FLAG[$i]} -eq 1 ];
      then
        CMD_KAT_PART+=" +"
        CMD_KAT_PART+="$(echo ${i} | tr A-Z a-z)"
      else
        ((skipped_found+=1))
      fi
    done
    # -----------------------------------------
    # Wenn alle Standard-Kategorien ausgewählt
    # wurden, dann Liste durch "all" ersetzen
    # -----------------------------------------
    if [ $skipped_found -eq 0 ];
    then
      CMD_KAT_PART=" all"
    fi
    COMMAND_LINE_STRING+="$CMD_KAT_PART"
    # -------------------------------
    # Zusätzliche Desktop-Kategorien
    # -------------------------------
    for i in ${KAT_KEYS_ADD[@]};
    do
      if [ ${KATEGORIE_FLAG[$i]} -eq 1 ];
      then
        COMMAND_LINE_STRING+=" +"
        COMMAND_LINE_STRING+="$(echo ${i} | tr A-Z a-z)"
      fi
    done
  fi
  # ----------------------------------------------------------------------------
  # Optionen
  # ----------------------------------------------------------------------------
  for i in ${OPTION_LIST[@]};
  do
    if [ ${OPTION_FLAG[$i]} -eq 1 ] &&
       [ "$i" != "instlist" ] &&
       [ "$i" != "instonly" ] &&
       [ "$i" != "skippkgs" ] &&
       [ "$i" != "remove" ];
    then
      COMMAND_LINE_STRING+=" $(echo ${i} | tr A-Z a-z)"
    fi
  done
  # ----------------------------------------------------------------------------
  # Skip-Liste
  # ----------------------------------------------------------------------------
  if [ ${#SKIP_LIST[@]} -ne 0 ];
  then
    i=0
    for skip_this_pkg in ${SKIP_LIST[@]};
    do
      if [ $i -eq 0 ] &&
         [ "$skip_this_pkg" != "" ];
      then
        COMMAND_LINE_STRING+=" skippkgs"
      fi
      COMMAND_LINE_STRING+=" $skip_this_pkg"
      ((i+=1))
    done
  fi
  # ----------------------------------------------------------------------------
  # Paket entfernen
  # ----------------------------------------------------------------------------
  if [ "$REMOVE_PKG_NAME" != "" ];
  then
    COMMAND_LINE_STRING+=" remove $REMOVE_PKG_NAME"
  fi
  # ----------------------------------------------------------------------------
  COMMAND_LINE_STRING="$(echo ${COMMAND_LINE_STRING} | xargs)"
}

#===============================================================================
# Schreibt einen Text nur in die Log-Datei
#===============================================================================
function do_log {
  if [ ${OPTION_FLAG[log]} -eq 1 ];
  then
    if [ "$1" == "-n" ];
    then
      TEXT_TO_LOG="$2"
      NEWLINE=''
    else
      TEXT_TO_LOG="$1"
      NEWLINE=$'\n'
    fi
    LOG_TEXT=$(clear_text "$TEXT_TO_LOG")
    echo -e -n "$LOG_TEXT$NEWLINE" >> "$LOG_FILE"
  fi
}

#===============================================================================
# Löschen einer Liste von Ordnern und Dateien
# --------------------------------------------
# Parameter $1: Datei mit Liste der zu löschenden Dateien und Ordner
# Parameter $2: Warnhinweis anzeigen (1) oder nicht (0)
#===============================================================================
function do_remove_items {
  REMOVE_ITEM_LIST="$1"
  SHOW_WARNING=$2
  if [ -s "$REMOVE_ITEM_LIST" ];
  then
    chown -R "$USER_USERNAME:$USER_USERNAME" "$REMOVE_ITEM_LIST" &>/dev/null
    chmod -R 0664 "$REMOVE_ITEM_LIST" &>/dev/null
    declare -A REMOVE_ITEM_TABLE
    REMOVE_TABLE_IDX=0
    while read item_path;
    do
      if [ "$item_path" != "" ] &&
         [ "$item_path" != "$USER_HOME_DIR" ];
      then
        e_and_l " - ${light_cyan}$item_path${colors_off}"
        REMOVE_ITEM_TABLE[$REMOVE_TABLE_IDX]="$item_path"
        ((REMOVE_TABLE_IDX+=1))
      fi
    done < "$REMOVE_ITEM_LIST"
    if [ $REMOVE_TABLE_IDX -gt 0 ];
    then
      if [ $SHOW_WARNING -eq 1 ];
      then
        e_and_l " ------------------------------------------------------------------------------"
        e_and_l " $ACHTUNG_TAG: Die gefunden Dateien können aufgrund der stark erweiterten Suche"
        e_and_l " eventuell auch zu anderen, ähnlich lautenden Programmpaketen, oder auch zu"
        e_and_l " benötigten Systemkomponenten gehören! Daher vor dem Löschen alle gefundenen"
        e_and_l " Einträge sorgfältig auf ihre Zugehörigkeit prüfen! Im Zweifel mit Option [1]"
        e_and_l " nicht bekannte Einträge überspringen, oder die Aktion abbrechen und mit Hilfe"
        e_and_l " der dabei gespeicherten Liste alle Dateien später prüfen und manuell löschen!"
        e_and_l " ------------------------------------------------------------------------------"
      fi
      e_and_l " Zum Löschen dieser Ordner und Dateien stehen folgende Optionen zur Verfügung:"
      e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen und Liste als Datei speichern"
      e_and_l " [${bold_yellow}1${colors_off}] Jede/n Datei/Ordner einzeln jeweils mit Abfrage Löschen"
      e_and_l " [${bold_yellow}2${colors_off}] Alle Ordner und Dateien ohne einzelne Abfragen löschen"
      user_choice_012
      REMOVE_ITEMS_ACTION=$?
      # ----------------------------------------------
      # Sicherheitsabfrage zur Auswahl aller Elemente
      # ----------------------------------------------
      if [ $REMOVE_ITEMS_ACTION -eq 2 ];
      then
        e_and_l " Hast Du die Liste ganz genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Wirklich ${bold_red}alle${colors_off} vorstehenden Ordner und Dateien löschen" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REMOVE_ITEMS_ACTION=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      else
        echo -e ""
      fi
      # ----------------------------------------------
      if [ $REMOVE_ITEMS_ACTION -gt 0 ];
      then
        echo -e -n "" > "$LOG_TEMP"
        i=0
        e_and_l "$HALF_MINUS_LINE"
        while [ $i -lt $REMOVE_TABLE_IDX ];
        do
          item_path="${REMOVE_ITEM_TABLE[$i]}"
          if [ "$item_path" != "" ] &&
             [ "$item_path" != "$USER_HOME_DIR" ];
          then
            DO_REMOVE_ITEM=1
            # ------------------
            # Einzelbestätigung
            # ------------------
            if [ $REMOVE_ITEMS_ACTION -eq 1 ];
            then
              e_and_l " ${light_cyan}$item_path${colors_off}"
              if [ -d "$item_path" ];
              then
                SHOW_FILE_TYPE="Diesen Ordner"
              else
                SHOW_FILE_TYPE="Diese Datei"
              fi
              ask_yes_or_no_plus "" " $SHOW_FILE_TYPE Löschen" "" "n"
              if [ $? -eq 0 ];
              then
                DO_REMOVE_ITEM=0
              fi
            fi
            # ----------------
            # Element Löschen
            # ----------------
            if [ $DO_REMOVE_ITEM -eq 1 ];
            then
              e_and_l -n " Lösche ${light_yellow}$item_path${colors_off} ... "
              rm -f -r "$item_path" &>>"$LOG_TEMP"
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
          ((i+=1))
        done
        remove_file "$REMOVE_ITEM_LIST"
        add_full_log
      else
        e_and_l "$HALF_MINUS_LINE"
        e_and_l " $HINWEIS_TAG: Die Liste der zuvor gefundenen Ordner und Dateien ist gespeichert in:"
        e_and_l " ${light_yellow}$REMOVE_ITEM_LIST${colors_off}"
      fi
    else
      remove_file "$REMOVE_ITEM_LIST"
      e_and_l " $NOTHING_FOUND_TEXT ... $OK_TAG"
    fi
  else
    remove_file "$REMOVE_ITEM_LIST"
    e_and_l " $NOTHING_FOUND_TEXT ... $OK_TAG"
  fi
}

#===============================================================================
# Reaktivierung einer Liste von Komponenten (Ordner und Dateien)
#===============================================================================
function do_revive_items {
  if [ -s "$DEACTIVATED_ITEMS_LIST" ];
  then
    e_and_l " Es wurden folgende ${bold_yellow}$(cat $DEACTIVATED_ITEMS_LIST | wc -l)${colors_off} deaktivierten Komponenten gefunden:"
    chown -R "$USER_USERNAME:$USER_USERNAME" "$DEACTIVATED_ITEMS_LIST" &>/dev/null
    chmod -R 0664 "$DEACTIVATED_ITEMS_LIST" &>/dev/null
    declare -A REVIVE_ITEM_TABLE
    REVIVE_TABLE_IDX=0
    while read item_path;
    do
      if [ "$item_path" != "" ] &&
         [ "$item_path" != "$USER_HOME_DIR" ];
      then
        e_and_l " - ${light_cyan}${item_path/.deactivated/}${colors_off}"
        REVIVE_ITEM_TABLE[$REVIVE_TABLE_IDX]="$item_path"
        ((REVIVE_TABLE_IDX+=1))
      fi
    done < "$DEACTIVATED_ITEMS_LIST"
    if [ $REVIVE_TABLE_IDX -gt 0 ];
    then
      e_and_l " Zur ${bold_white}Reaktivierung${colors_off} dieser Komponenten stehen folgende Optionen zur Verfügung:"
      e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts reaktivieren und Liste als Datei speichern"
      e_and_l " [${bold_yellow}1${colors_off}] Jede Komponente einzeln jeweils mit Abfrage reaktivieren"
      e_and_l " [${bold_yellow}2${colors_off}] Alle Komponenten ohne einzelne Abfragen reaktivieren"
      user_choice_012
      REVIVE_ITEMS_ACTION=$?
      # ----------------------------------------------
      # Sicherheitsabfrage zur Auswahl aller Elemente
      # ----------------------------------------------
      if [ $REVIVE_ITEMS_ACTION -eq 2 ];
      then
        e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt reaktiviert wird?"
        ask_yes_or_no_plus "" " Wirklich ${bold_red}alle${colors_off} vorstehenden Komponenten reaktivieren" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REVIVE_ITEMS_ACTION=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------
      if [ $REVIVE_ITEMS_ACTION -gt 0 ];
      then
        echo -e -n "" > "$LOG_TEMP"
        i=0
        e_and_l "$HALF_MINUS_LINE"
        while [ $i -lt $REVIVE_TABLE_IDX ];
        do
          item_path="${REVIVE_ITEM_TABLE[$i]}"
          config_file_old_name=${item_path/.deactivated/}
          if [ "$item_path" != "" ] &&
             [ "$item_path" != "$USER_HOME_DIR" ];
          then
            DO_REVIVE_ITEM=1
            # Wenn mit einzelner Bestätigung, dann noch die Sicherheitsabfrage
            if [ $REVIVE_ITEMS_ACTION -eq 1 ];
            then
              e_and_l " ${light_cyan}${config_file_old_name}${colors_off}"
              ask_yes_or_no_plus "" " Diese Komponente reaktivieren" "" "n"
              if [ $? -eq 0 ];
              then
                DO_REVIVE_ITEM=0
              fi
            fi
            # ---------------------
            # Element reaktivieren
            # ---------------------
            if [ $DO_REVIVE_ITEM -eq 1 ];
            then
              e_and_l -n " Reaktiviere ${light_yellow}${item_path:0:8}../${config_file_old_name##*/}${colors_off} ... "
              mv -f "$item_path" "$config_file_old_name" &>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
          ((i+=1))
        done
        e_and_l "$REBOOT_MSG"
        remove_file "$DEACTIVATED_ITEMS_LIST"
        add_full_log
      else
        e_and_l "$HALF_MINUS_LINE"
        e_and_l " $HINWEIS_TAG: Die Liste gefundener deaktivierter Komponenten ist gespeichert in:"
        e_and_l " ${light_yellow}$DEACTIVATED_ITEMS_LIST${colors_off}"
      fi
    else
      remove_file "$DEACTIVATED_ITEMS_LIST"
      e_and_l " $NOTHING_FOUND_TEXT ... $OK_TAG"
    fi
  else
    remove_file "$DEACTIVATED_ITEMS_LIST"
    e_and_l " $NOTHING_FOUND_TEXT ... $OK_TAG"
  fi
}

#===============================================================================
# Download einer Bild-Datei (Pixmap)
#===============================================================================
function download_icon_file {
  PKG_PICTURE_NAME="$1.png"
  ICON_OVERRIDE=$2
  PKG_PICTURE_FILE="$PKG_IPIX_DIR/$PKG_PICTURE_NAME"
  if [ -d "$PKG_IPIX_DIR" ] &&
     [[ ! -s "$PKG_PICTURE_FILE" || $ICON_OVERRIDE -eq 1 ]];
  then
    PKG_PICTURE_URL="$RESSOURCE_SERVER_DIR/png/$PKG_PICTURE_NAME"
    LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$PKG_PICTURE_NAME"
    wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$PKG_PICTURE_URL" &>/dev/null
    DOWNLOAD_RESULT=$?
    if [ $DOWNLOAD_RESULT -eq 0 ] &&
       [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
       [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
    then
      mv -f "$LOCAL_DOWNLOAD_FILE" "$PKG_PICTURE_FILE" &>/dev/null
      chown -R "root:root" "$PKG_PICTURE_FILE" &>/dev/null
      chmod -R 0644 "$PKG_PICTURE_FILE" &>/dev/null
    else
      remove_file "$LOCAL_DOWNLOAD_FILE"
    fi
  fi
}

#===============================================================================
# Gibt einen Text aus und schreibt diesen in die Log-Datei
#===============================================================================
function e_and_l {
  if [ "$1" == "-n" ];
  then
    TEXT_TO_WRITE="$2"
    NEWLINE=''
  else
    TEXT_TO_WRITE="$1"
    NEWLINE=$'\n'
  fi
  echo -e -n "$TEXT_TO_WRITE$NEWLINE"
  if [ "${OPTION_FLAG[log]}" != "" ];
  then
    if [ ${OPTION_FLAG[log]} -eq 1 ];
    then
      LOG_TEXT=$(clear_text "$TEXT_TO_WRITE")
      echo -e -n "$LOG_TEXT$NEWLINE" >> "$LOG_FILE"
    fi
  fi
}

#===============================================================================
# Aufräumen nach der Beendigung des Auswahl-Menüs
#===============================================================================
function exit_from_menu {
  dialog --clear
  clear
  setterm -cursor on 2>/dev/null
  # Wenn es vorher keine Konfigurations-Datei gab,
  # dann die selbst erstellte auch wieder löschen
  if [ -f "$DIALOG_RC_FILE" ] &&
     [ $REMOVE_DIALOG_RC -eq 1 ];
  then
    remove_file "$DIALOG_RC_FILE"
  fi
  unset DIALOGRC
}

#===============================================================================
# Erweiterung des Repository für ein erweitertes Programmpaket "ERW"
# HINWEIS: Diese Funktion verwendet bereits die Verwaltung ohne apt-key ;o)
#===============================================================================
function extend_repo_erw {
  ERW_PAKET_NAME=$1
  e_and_l " ${light_yellow}$ERW_PAKET_NAME${colors_off} ist ein erweitertes Programmpaket (ERW):"
  # ---------------------------------
  # Dateinamen und Befehle erstellen
  # ---------------------------------
  REPO_KEY_URL="${ERW_AUTH_KEY[$ERW_PAKET_NAME]}" # URL zum Download der Schlüssel-Datei
  LOCAL_KEY_FILE="$APT_SOURCES_MAIN_DIR/trusted.gpg.d/$ERW_PAKET_NAME" # Ziel-Datei mit Schlüssel für Quellangaben
  LOCAL_REPO_FILE="$APT_SOURCES_LIST_DIR/$ERW_PAKET_NAME.list" # Ziel-Datei für die Quellangaben
  REPO_SRC_TXT="${ERW_REPO_TXT[$ERW_PAKET_NAME]}" # Text zum Eintrag in die Datei mit den Quellangaben
  REPO_CMD="echo -e \"$REPO_SRC_TXT\" | tee \"$LOCAL_REPO_FILE\""
  # -----------------------------------------------------------------
  # Quell-Listen durch Anlegen des Authentifizierungs-Schlüssels und
  # einer entsprechenden Datei in /etc/apt/sources.list.d/ erweitern
  # -----------------------------------------------------------------
  # Authentifizierungs-Schlüssel erstellen
  do_log "$PRE_SPACE Authentifizierungs-Schlüssel: $REPO_KEY_URL"
  do_log "$PRE_SPACE Repository-Quelldatei-Eintrag: $REPO_SRC_TXT"
  e_and_l -n "$PRE_SPACE Erweitere die Paketquellen, bitte warten ... "
  # -----------------------------------------------
  # 1. Datei mit Schlüssel runterladen und anlegen
  # -----------------------------------------------
  LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$ERW_PAKET_NAME.ikey"
  wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$REPO_KEY_URL" &>"$LOG_TEMP"
  DOWNLOAD_RESULT=$?
  if [ $DOWNLOAD_RESULT -eq 0 ] &&
     [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
     [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
  then
    if [ $(echo "$REPO_KEY_URL" | grep -c -i -E "\.asc$") -gt 0 ] ||
       [[ $(grep -c -i -E "BEGIN PGP" "$LOCAL_DOWNLOAD_FILE" 2>/dev/null) -gt 0 &&
          $(grep -c -i -E "END PGP" "$LOCAL_DOWNLOAD_FILE" 2>/dev/null) -gt 0 ]];
    then
      LOCAL_KEY_FILE+=".asc"
    else
      LOCAL_KEY_FILE+=".gpg"
    fi
    create_backup_file "$LOCAL_KEY_FILE"
    cp -f "$LOCAL_DOWNLOAD_FILE" "$LOCAL_KEY_FILE" &>"$LOG_TEMP"
    if [ $? -eq 0 ];
    then
      chown -R "root:root" "$LOCAL_KEY_FILE" &>/dev/null
      chmod -R 0644 "$LOCAL_KEY_FILE" &>/dev/null
      remove_file "$LOCAL_DOWNLOAD_FILE"
      # ------------------------------------
      # 2. Datei mit Quellangaben erstellen
      # ------------------------------------
      create_backup_file "$LOCAL_REPO_FILE"
      # Quellen-Datei erstellen und Repository aktualisieren
      eval " $REPO_CMD" &>"$LOG_TEMP"
      if [ $? -eq 0 ] &&
         [ -s "$LOCAL_REPO_FILE" ];
      then
        e_and_l "$OK_TAG"
        repo_update "$PRE_SPACE Aktualisiere das Repository, bitte warten ... "
      else
        e_and_l ""
        e_and_l "$PRE_SPACE $ERROR_TAG beim Erstellen der Quellen-Datei!"
        add_full_log
      fi
    else
      e_and_l "$ERROR_TAG $LINENO"
      add_full_log
    fi
  else
    e_and_l ""
    e_and_l "$PRE_SPACE $ERROR_TAG beim Download des Authentifizierungs-Schlüssels!"
    add_full_log
    remove_file "$LOCAL_DOWNLOAD_FILE"
  fi
}

#===============================================================================
# Erweiterung des Repository für ein erweitertes Programmpaket "PPA"
#===============================================================================
function extend_repo_ppa {
  PPA_PAKET_NAME=$1
  e_and_l " ${light_yellow}$PPA_PAKET_NAME${colors_off} ist ein erweitertes Programmpaket (PPA):"
  REPO_SRC_TXT="${PPA_REPO_TXT[$PPA_PAKET_NAME]}"
  do_log "$PRE_SPACE Repository-Eintrag: $REPO_SRC_TXT"
  e_and_l -n "$PRE_SPACE Erweitere die Paketquellen, bitte warten ... "
  add-apt-repository -y "$REPO_SRC_TXT" &>"$LOG_TEMP"
  if [ $? -eq 0 ];
  then
    e_and_l "$OK_TAG"
    repo_update "$PRE_SPACE Aktualisiere das Repository, bitte warten ... "
  else
    e_and_l ""
    e_and_l "$PRE_SPACE $ERROR_TAG beim Erweitern des Repository!"
    add_full_log
  fi
}

#===============================================================================
# UUIDs für die EFI-System-Partition (ESP) ermitteln
#===============================================================================
function get_esp_uuids {
  # ---------------------------------------------------------------------------
  # UUID der EFI-System-Partition des selben Laufwerks von dem gestartet wurde
  # ---------------------------------------------------------------------------
  efi_system_partition="$(fdisk -l -o device,type ${boot_device} | grep -i -E "^.*\s+efi" | awk '{print $1}' | head -n 1 | xargs 2>/dev/null)"
  uuid_efi_system="$(blkid -s UUID -o value ${efi_system_partition} 2>/dev/null | xargs 2>/dev/null)"
  # ---------------------------------------------------------------
  # UUID der in der fstab als eingetragene Partition für /boot/efi
  # ---------------------------------------------------------------
  uuid_efi_fstab="$(grep -i -E "^\s*UUID\s*\=.*\/boot\/efi" "$ETC_FSTAB" 2>/dev/null | sed -E "s/^(.*)UUID\s*\=//i" | sed -E "s/(\s|\t)+.*//i" | head -n 1 | xargs 2>/dev/null)"
  # -----------------------------------------------------------------------
  # UUID der Partition auf der /boot/efi aktuell tatsächlich gemountet ist
  # -----------------------------------------------------------------------
  if [ -d "/boot/efi" ] &&
     [ ! -L "/boot/efi" ];
  then
    uuid_efi_mount="$(lsblk -no UUID $(df -P "/boot/efi" 2>/dev/null | awk 'END{print $1}') | xargs 2>/dev/null)"
  else
    uuid_efi_mount=""
  fi
}

#===============================================================================
# Prüfung ob ein Paket schon installiert ist
# Rückgaben: 0 = nicht installiert
#            1 = installiert mit der normalen Paketverwaltung (apt/dpkg)
#            2 = installiert als Snap-Paket
#            3 = Ordner mit ausführbaren Dateien in /opt gefunden
#            4 = Ordner mit ausführbaren Dateien in /home/USER/apps gefunden
#            5 = Ordner mit ausführbaren Dateien in /usr/share gefunden
#            6 = installiert als Flatpak-Paket
#
# ACHTUNG: Neben der RÜCKGABE des Installations-Codes ÄNDERT diese Funktion
#          auch den Wert der Variable PKG_VERSION!
#===============================================================================
function get_install_status {
  PKG_INSTALL_STATUS=0
  PKG_VERSION=""
  # ---------------------------------------------------------------------
  # 1. Prüfen ob in der Standard dpkg-Datenbank als installiert vermerkt
  # ---------------------------------------------------------------------
  if [ $(LANG=C dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
  then
    PKG_INSTALL_STATUS=1
    PKG_VERSION=$(get_pkg_apt_version "$1" 1)
  fi
  # ----------------------------------------
  # 2. Prüfen ob als Snap-Paket installiert
  # ----------------------------------------
  if [ $PKG_INSTALL_STATUS -eq 0 ] && [ $SNAP_ACTIVE -gt 0 ];
  then
    if [ $(LANG=C snap info "$1" 2>/dev/null | grep -i -c -E "installed\:") -ne 0 ];
    then
      PKG_INSTALL_STATUS=2
      PKG_VERSION=$(get_pkg_snap_version "$1" 1)
    fi
  fi
  # ------------------------------------------------------------------
  # 3. Prüfen ob es im System-Anwendungs-Ordner "/opt" einen
  # entsprechenden Programmordner mit ausführbaren Dateien gibt
  # ------------------------------------------------------------------
  if [ $PKG_INSTALL_STATUS -eq 0 ];
  then
    THE_PKG_TEST_NAME="${DEB_PKG_NAME[$1]}"
    if [ "$THE_PKG_TEST_NAME" == "" ];
    then
      THE_PKG_TEST_NAME="${WEB_PKG_NAME[$1]}"
      if [ "$THE_PKG_TEST_NAME" == "" ];
      then
        THE_PKG_TEST_NAME="$1"
      fi
    fi
    if [ "$THE_PKG_TEST_NAME" != "" ];
    then
      THE_PKG_INST_DIR="/opt/$THE_PKG_TEST_NAME"
      if [ -d "$THE_PKG_INST_DIR" ];
      then
        if [ $(find "$THE_PKG_INST_DIR" -type f -executable 2>/dev/null | wc -l) -gt 0 ];
        then
          PKG_INSTALL_STATUS=3
          PKG_VERS_FILE="$THE_PKG_INST_DIR/.$1"
          PKG_VERS_FILE+="_version"
          if [ -s "$PKG_VERS_FILE" ];
          then
            PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs)
          else
            PKG_VERSION=""
          fi
        fi
      fi
    fi
  fi
  # ------------------------------------------------------------------
  # 4. Prüfen ob es im eigenen Anwendungs-Ordner (siehe WEB_PKG_DIR)
  # einen entsprechenden Programmordner mit ausführbaren Dateien gibt
  # ------------------------------------------------------------------
  if [ $PKG_INSTALL_STATUS -eq 0 ];
  then
    if [ "${WEB_PKG_NAME[$1]}" != "" ];
    then
      THE_PKG_INST_DIR="$WEB_PKG_DIR/${WEB_PKG_NAME[$1]}"
      if [ -d "$THE_PKG_INST_DIR" ];
      then
        if [ $(find "$THE_PKG_INST_DIR" -type f -executable 2>/dev/null | wc -l) -gt 0 ];
        then
          PKG_INSTALL_STATUS=4
          PKG_VERS_FILE="$THE_PKG_INST_DIR/.$1"
          PKG_VERS_FILE+="_version"
          if [ -s "$PKG_VERS_FILE" ]; then PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs); fi
        fi
      fi
    fi
  fi
  # ------------------------------------------------------------------
  # 5. Prüfen ob es im System-Anwendungs-Ordner "/usr/share" einen
  # entsprechenden Programmordner mit ausführbaren Dateien gibt
  # (nur für externe DEB/WEB-Pakete, da es für einige Pakete aus dem Repo
  # bereits vorkonfigurierte Ordner sogar mit ausführbaren Dateien gibt!)
  # ------------------------------------------------------------------
  if [ $PKG_INSTALL_STATUS -eq 0 ];
  then
    if [ "${DEB_PKG_NAME[$1]}" != "" ] ||
       [ "${WEB_PKG_NAME[$1]}" != "" ];
    then
      THE_PKG_INST_DIR="/usr/share/$1"
      if [ -d "$THE_PKG_INST_DIR" ];
      then
        if [ $(find "$THE_PKG_INST_DIR" -type f -executable 2>/dev/null | wc -l) -gt 0 ];
        then
          PKG_INSTALL_STATUS=5
          PKG_VERS_FILE="$THE_PKG_INST_DIR/.$1"
          PKG_VERS_FILE+="_version"
          if [ -s "$PKG_VERS_FILE" ];
          then
            PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs)
          else
            PKG_VERSION=""
          fi
        fi
      fi
    fi
  fi
  # -------------------------------------------
  # 6. Prüfen ob als Flatpak-Paket installiert
  # -------------------------------------------
  if [ $PKG_INSTALL_STATUS -eq 0 ] &&
     [ $FLATPAK_ACTIVE -eq 1 ] &&
     [ -s "$FLATPAK_INSTALLED_PKG_LIST" ];
  then
    FLATPAK_NAME=$(echo "$1" | sed 's/[ -_]//g' | xargs)
    if [ $(grep -c -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_INSTALLED_PKG_LIST}) -gt 0 ] ||
       [ $(grep -c -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_INSTALLED_PKG_LIST}) -gt 0 ];
    then
      PKG_INSTALL_STATUS=6
      PKG_FLATPAK_VERSION=$(get_pkg_flatpak_version "$FLATPAK_NAME" 1)
      PKG_VERSION=$(clean_pkg_version "$PKG_FLATPAK_VERSION")
    fi
  fi
  # -----------------------------------------------------------------

  return $PKG_INSTALL_STATUS
}

#===============================================================================
# Ermittlung einer Paket-Version aus dem Standard-Repository (APT)
#===============================================================================
function get_pkg_apt_version {
  INFO_TYPE=$2 # 0 = verfügbare Version, 1 = installierte Version ermitteln
  if [ $INFO_TYPE -eq 0 ];
  then
    if [ "$APT_PKG_EXTENDED_NAME" != "" ];
    then
      PKG_TO_CHECK="$APT_PKG_EXTENDED_NAME"
    else
      PKG_TO_CHECK="$1"
    fi
    PKG_APT_VERSION=$(LANG=C apt show "$PKG_TO_CHECK" 2>/dev/null | \
      grep -i -E "^\s*Version" | \
      sed -E "s/^\s*version\s*:\s*//i")
  else
    PKG_APT_VERSION=$(LANG=C dpkg-query -W -f='${Version}' "$1" 2>/dev/null)
  fi
  echo -e -n $(clean_pkg_version "$PKG_APT_VERSION")
}

#===============================================================================
# Ermittlung einer Paket-Version eines externen Pakets (DEB)
#===============================================================================
function get_pkg_deb_version {
  THE_PKG_TEST_NAME="${DEB_PKG_NAME[$1]}"
  if [ "$THE_PKG_TEST_NAME" == "" ];
  then
    THE_PKG_TEST_NAME="${WEB_PKG_NAME[$1]}"
    if [ "$THE_PKG_TEST_NAME" == "" ];
    then
      THE_PKG_TEST_NAME="$1"
    fi
  fi
  PKG_VERS_FILE="/opt/$THE_PKG_TEST_NAME/.$1"
  PKG_VERS_FILE+="_version"
  if [ -s "$PKG_VERS_FILE" ];
  then
    PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs)
  else
    PKG_VERSION=${DEB_PKG_VERS["$1"]}
  fi
  echo -e -n "$PKG_VERSION"
}

#===============================================================================
# Ermittlung einer Paket-Version als Flatpak (FLAT)
# --------------------------------------------------
# Parameter $1: Paketname
# Parameter $2: Ermittlung der verfügbaren (0) oder installierten (1) Version
#===============================================================================
function get_pkg_flatpak_version {
  FLATPAK_NAME=$(echo "$1" | sed 's/[ -_]//g' | xargs)
  INFO_TYPE=$2
  PKG_FLATPAK_VERSION=""
  # -----------------------------
  # Verfügbare Version ermitteln
  # -----------------------------
  if [ $INFO_TYPE -eq 0 ];
  then
    if [ -s "$FLATPAK_REMOTE_LIST" ];
    then
      PKG_FLATPAK_VERSION=$(grep -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_REMOTE_LIST} | tail -n 1 | cut -f 2 | xargs 2>/dev/null)
      if [ "$PKG_FLATPAK_VERSION" == "" ];
      then
        PKG_FLATPAK_VERSION=$(grep -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_REMOTE_LIST} | tail -n 1 | cut -f 2 | xargs 2>/dev/null)
      fi
    fi
  fi
  # --------------------------------------
  # Installierte Version ermitteln
  # --------------------------------------
  if [ $INFO_TYPE -eq 1 ];
  then
    if [ -s "$FLATPAK_INSTALLED_PKG_LIST" ];
    then
      PKG_FLATPAK_VERSION=$(grep -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_INSTALLED_PKG_LIST} | tail -n 1 | cut -f 2 | xargs 2>/dev/null)
      if [ "$PKG_FLATPAK_VERSION" == "" ];
      then
        PKG_FLATPAK_VERSION=$(grep -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_INSTALLED_PKG_LIST} | tail -n 1 | cut -f 2 | xargs 2>/dev/null)
      fi
    fi
  fi
  THE_FLAT_PKG_VERSION=$(clean_pkg_version "$PKG_FLATPAK_VERSION")
  if [ "$THE_FLAT_PKG_VERSION" != "" ];
  then
    echo -e -n "$THE_FLAT_PKG_VERSION"
  fi
}

#===============================================================================
# Ermittlung des Referenz-Strings eines Flatpaks
# -----------------------------------------------
# Parameter $1: Paketname
# Parameter $2: Ermittlung der verfügbaren (0) oder installierten (1) Version
#===============================================================================
function get_pkg_flatpak_reference {
  FLATPAK_NAME=$(echo "$1" | sed 's/[ -_]//g' | xargs)
  INFO_TYPE=$2
  TMP_FLATPAK_REFERENCE=""
  # -----------------------------------
  # Verfügbare Version mit Architektur
  # -----------------------------------
  if [ $INFO_TYPE -eq 0 ];
  then
    if [ -s "$FLATPAK_REMOTE_LIST" ];
    then
      TMP_FLATPAK_REFERENCE=$(grep -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_REMOTE_LIST} | tail -n 1 | cut -f 3 | xargs 2>/dev/null)
      if [ "$TMP_FLATPAK_REFERENCE" == "" ];
      then
        TMP_FLATPAK_REFERENCE=$(grep -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_REMOTE_LIST} | tail -n 1 | cut -f 3 | xargs 2>/dev/null)
      fi
    fi
  fi
  # --------------------------------------
  # Installierte Version ohne Architektur
  # --------------------------------------
  if [ $INFO_TYPE -eq 1 ];
  then
    if [ -s "$FLATPAK_INSTALLED_PKG_LIST" ];
    then
      TMP_FLATPAK_REFERENCE=$(grep -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_INSTALLED_PKG_LIST} | tail -n 1 | cut -f 3 | cut -d'/' -f 1 | xargs 2>/dev/null)
      if [ "$TMP_FLATPAK_REFERENCE" == "" ];
      then
        TMP_FLATPAK_REFERENCE=$(grep -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_INSTALLED_PKG_LIST} | tail -n 1 | cut -f 3 | cut -d'/' -f 1 | xargs 2>/dev/null)
      fi
    fi
  fi
  if [ "$TMP_FLATPAK_REFERENCE" != "" ];
  then
    echo -e -n "$TMP_FLATPAK_REFERENCE"
  fi
}

#===============================================================================
# Ermittlung einer Paket-Version als Snap (SNAP)
#===============================================================================
function get_pkg_snap_version {
  INFO_TYPE=$2 # 0 = verfügbare Version, 1 = installierte Version ermitteln
  PKG_SNAP_CHANNEL="" # Leer = Standard (stable)
  if [ $SNAP_ACTIVE -gt 0 ];
  then
    if [ $INFO_TYPE -eq 0 ];
    then
      FULL_PKG_SNAP_INFO=$(LANG=C snap info "$1" 2>/dev/null | sed -E "s/^\s*(latest)\s*\/\s*//gi")
      # Zuerst auf stable-Version prüfen
      PKG_SNAP_VERSION=$(echo "$FULL_PKG_SNAP_INFO" | \
        grep -i -E "^\s*stable" | \
        sed -E "s/^\s*stable\s*\:*\s*//")
      # Wenn keine stable-Version gefunden, dann auf candidate prüfen
      if [ $(echo "$PKG_SNAP_VERSION" | grep -c -E "[0-9]") -eq 0 ];
      then
        PKG_SNAP_VERSION=$(echo "$FULL_PKG_SNAP_INFO" | \
          grep -i -E "^\s*candidate" | \
          sed -E "s/^\s*candidate\s*\:*\s*//")
        # Wenn keine candidate-Version gefunden, dann auf beta prüfen
        if [ $(echo "$PKG_SNAP_VERSION" | grep -c -E "[0-9]") -gt 0 ];
        then
          PKG_SNAP_CHANNEL="candidate"
        else
          PKG_SNAP_VERSION=$(echo "$FULL_PKG_SNAP_INFO" | \
            grep -i -E "^\s*beta" | \
            sed -E "s/^\s*beta\s*\:*\s*//")
          # Wenn keine beta-Version gefunden, dann auf edge prüfen
          if [ $(echo "$PKG_SNAP_VERSION" | grep -c -E "[0-9]") -gt 0 ];
          then
            PKG_SNAP_CHANNEL="beta"
          else
            PKG_SNAP_VERSION=$(echo "$FULL_PKG_SNAP_INFO" | \
              grep -i -E "^\s*edge" | \
              sed -E "s/^\s*edge\s*\:*\s*//")
            if [ $(echo "$PKG_SNAP_VERSION" | grep -c -E "[0-9]") -gt 0 ];
            then
              PKG_SNAP_CHANNEL="edge"
            fi
          fi
        fi
      fi
    else
      FULL_PKG_SNAP_INFO=$(LANG=C snap list "$1" 2>/dev/null | awk 'NR>1' | head -n 1)
      PKG_SNAP_VERSION=$(echo "$FULL_PKG_SNAP_INFO" | awk '{print $2}' | sed -E "s/\-//g" | xargs)
      # PKG_SNAP_REVISION=$(echo "$FULL_PKG_SNAP_INFO" | awk '{print $3}' | sed -E "s/\-//g" | xargs)
      PKG_SNAP_TRACKING=$(echo "$FULL_PKG_SNAP_INFO" | awk '{print $4}' | sed -E "s/\-//g" | xargs)
      if [ $(echo "$PKG_SNAP_TRACKING" | grep -i -c -E "candidate") -gt 0 ];
      then
        PKG_SNAP_CHANNEL="candidate"
      else
        if [ $(echo "$PKG_SNAP_TRACKING" | grep -i -c -E "beta") -gt 0 ];
        then
          PKG_SNAP_CHANNEL="beta"
        else
          if [ $(echo "$PKG_SNAP_TRACKING" | grep -i -c -E "edge") -gt 0 ];
          then
            PKG_SNAP_CHANNEL="edge"
          fi
        fi
      fi
      PKG_SNAP_NOTES=$(echo "$FULL_PKG_SNAP_INFO" | awk '{print $6}' | sed -E "s/\-//g" | xargs)
    fi
    # Versionsnummer bereinigen
    THE_SNAP_PKG_VERSION=$(clean_pkg_version "$PKG_SNAP_VERSION")
    # Ggf. Zusatzinfos anhängen
    if [ "$PKG_SNAP_CHANNEL" != "" ];
    then
      THE_SNAP_PKG_VERSION+=" "
      if [ $INFO_TYPE -eq 0 ];
      then
        THE_SNAP_PKG_VERSION+="${light_red}"
      else
        THE_SNAP_PKG_VERSION+="${light_magenta}"
      fi
      THE_SNAP_PKG_VERSION+="$PKG_SNAP_CHANNEL${colors_off}"
    fi
    # Ggf. Hinweis auf Classic-Mode anhängen
    if [ $(echo "$PKG_SNAP_VERSION" | grep -i -c -E " classic") -gt 0 ] || # aus snap info
      [ $(echo "$PKG_SNAP_NOTES" | grep -i -c -E "classic") -gt 0 ];      # aus snap list
    then
      THE_SNAP_PKG_VERSION+=" ${light_red}classic${colors_off}"
    fi
  else
    THE_SNAP_PKG_VERSION=""
  fi
  echo -e -n "$THE_SNAP_PKG_VERSION"
}

#===============================================================================
# Ermittlung einer Paket-Version einer ausführbaren Datei (WEB)
#===============================================================================
function get_pkg_web_version {
  PKG_VERS_FILE="$WEB_PKG_DIR/${WEB_PKG_NAME[$1]}/.$1"
  PKG_VERS_FILE+="_version"
  if [ -s "$PKG_VERS_FILE" ];
  then
    PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs)
  else
    PKG_VERSION=${WEB_PKG_VERS["$1"]}
  fi
  echo -e -n "$PKG_VERSION"
}

#===============================================================================
# Ermittlung einer Paket-Version einer ausführbaren Datei (SHAR)
#===============================================================================
function get_pkg_shar_version {
  PKG_VERS_FILE="/usr/share/$1/.$1_version"
  if [ -s "$PKG_VERS_FILE" ];
  then
    PKG_VERSION=$(cat "$PKG_VERS_FILE" | xargs)
  else
    PKG_VERSION=""
  fi
  echo -e -n "$PKG_VERSION"
}

#===============================================================================
# Ermittlung der internen Paketart (Zuordnung gemäß o.s. Listen)
# mit Prüfung, ob dazu (unabhängig von deren Gültigkeit) vollständige Angaben
# zu deren Installation vorhanden sind. Hier wird nicht geprüft, ob die Pakete
# auch tatsächlich zur Installation oder zum Download verfügbar stehen.
# Rückgaben: Keine, statt dessen wird die Variable PACKAGE_TYPE gesetzt auf:
#            "STD"  = in keiner alternativen Quell-Liste => Standard-Repository
#            "ERW"  = installierbar durch Erweiterung des Repository
#            "PPA"  = installierbar durch Erweiterung des Repository
#            "DEB"  = installierbar mit downloadbarer .deb-Datei
#            "WEB"  = ausführbare Datei zum Download, Entpacken und Kopieren
#            "NONE" = unvollständige Angaben in den alternativen Quell-Listen
#===============================================================================
function get_package_type {
  if [ "$PACKAGE_TYPE" == "" ]; then PACKAGE_TYPE="STD"; fi
  # --------------
  # Paket-Typ ERW
  # --------------
  if [ "$PACKAGE_TYPE" == "STD" ];
  then
    if [ "${ERW_AUTH_KEY[$1]}" != "" ] ||
       [ "${ERW_REPO_TXT[$1]}" != "" ];
    then
      if [ "${ERW_AUTH_KEY[$1]}" != "" ] &&
         [ "${ERW_REPO_TXT[$1]}" != "" ];
      then
        PACKAGE_TYPE="ERW"
      else
        PACKAGE_TYPE="NONE"
      fi
    fi
  fi
  # --------------
  # Paket-Typ PPA
  # --------------
  if [ "$PACKAGE_TYPE" == "STD" ] ||
     [ "$PACKAGE_TYPE" == "NONE" ];
  then
    if [ "${PPA_REPO_TXT[$1]}" != "" ];
    then
      PACKAGE_TYPE="PPA"
    fi
  fi
  # --------------
  # Paket-Typ DEB
  # --------------
  if [ "$PACKAGE_TYPE" == "STD" ] ||
     [ "$PACKAGE_TYPE" == "NONE" ];
  then
    FOUND_PKG=0
    for arch_name in ${ARCH_NAME_LIST[@]};
    do
      IDX_NAME="$1"
      IDX_NAME+="_"
      IDX_NAME+="$arch_name"
      if [ "${DEB_PKG_FILE[$IDX_NAME]}" != "" ];
      then
        FOUND_PKG=1
        break
      fi
    done
    if [ $FOUND_PKG -eq 1 ];
    then
      PACKAGE_TYPE="DEB"
    fi
  fi
  # --------------
  # Paket-Typ WEB
  # --------------
  if [ "$PACKAGE_TYPE" == "STD" ] ||
     [ "$PACKAGE_TYPE" == "NONE" ];
  then
    if [ "${WEB_PKG_NAME[$1]}" != "" ];
    then
      FOUND_PKG=0
      for arch_name in ${ARCH_NAME_LIST[@]};
      do
        IDX_NAME="$1"
        IDX_NAME+="_"
        IDX_NAME+="$arch_name"
        if [ "${WEB_PKG_FILE[$IDX_NAME]}" != "" ];
        then
          FOUND_PKG=1
          break
        fi
      done
      if [ $FOUND_PKG -eq 1 ];
      then
        PACKAGE_TYPE="WEB"
      else
        PACKAGE_TYPE="NONE"
      fi
    fi
  fi
}

#===============================================================================
# Ermittlung der maximalen Größe eines tmpfs
#===============================================================================
function get_tmpfs_size {
  MOUNT_POINT="$1"
  # Größe nur berechnen, wenn das tmpfs in der fstab enthalten und aktiviert ist
  if [ "$MOUNT_POINT" != "" ] &&
     [ $(grep -i -c -E "^\s*tmpfs\s*${MOUNT_POINT}\s" "$ETC_FSTAB") -gt 0 ];
  then
    # Wenn die Größe explizit angegeben ist, diese auslesen und umwandeln ...
    if [ $(grep -i -c -E "^\s*tmpfs\s*${MOUNT_POINT}\s.*size\s*=" "$ETC_FSTAB") -gt 0 ];
    then
      THE_RAMDISK_SIZE=$(grep -i -E "^\s*tmpfs\s*${MOUNT_POINT}" "$ETC_FSTAB" | sed 's/.*size\s*=\s*//gi' | cut -d" " -f 1 | cut -d"," -f 1 | xargs)
      THE_RAMSIZE_UNIT=$(echo $THE_RAMDISK_SIZE | sed 's/[0-9]*//g')
      THE_RAMDISK_SIZE=$(echo $THE_RAMDISK_SIZE | sed 's/[^0-9]*//g')
      case $THE_RAMSIZE_UNIT in
        "%") THE_RAMDISK_SIZE=$((MEMORY_TOTAL / 1024 / 1024 * THE_RAMDISK_SIZE / 100)) ;;
        "M") THE_RAMDISK_SIZE=$((THE_RAMDISK_SIZE)) ;;
        "G") THE_RAMDISK_SIZE=$((THE_RAMDISK_SIZE * 1024)) ;;
        "T") THE_RAMDISK_SIZE=$((THE_RAMDISK_SIZE * 1024 * 1024)) ;;
      esac
    else # ... sonst 50% des Hauptspeichers (Linux-Standard)
      THE_RAMDISK_SIZE=$((MEMORY_TOTAL / 1024 / 1024 / 2))
    fi
  else
    THE_RAMDISK_SIZE=0
  fi
  echo -e -n "$THE_RAMDISK_SIZE"
}

#===============================================================================
# Ermittlung der Anzahl Benutzer und Existenz von Superusern
#===============================================================================
function get_user_list {
  IFS=$'\n' HOME_DIR_LIST=($(find /home * -mindepth 1 -maxdepth 1 -type d -print 2>/dev/null | sort))
  IFS=' '
  ANZAHL_USER=${#HOME_DIR_LIST[@]}
  SUDOER_EXIST=0
  if [ $ANZAHL_USER -gt 0 ];
  then
    for userdir in ${HOME_DIR_LIST[@]};
    do
      TEST_USER_NAME=${userdir/\/home\//}
      if [ "$TEST_USER_NAME" != "$USER_USERNAME" ] &&
         [ $(id $TEST_USER_NAME 2>/dev/null | grep -i -c -E "\(sudo\)") -gt 0 ];
      then
        ((SUDOER_EXIST+=1))
        break
      fi
    done
  fi
  # ---------------------------------------------------------------------------
  # Da der Aufruf dieser Funktion nur als Benutzer "root" oder "pi" erfolgt,
  # anbieten das Skript abzubrechen, wenn es auch noch andere Sudoer gibt
  # ---------------------------------------------------------------------------
  if [ $SUDOER_EXIST -gt 0 ];
  then
    e_and_l " Es sind auch schon andere Benutzer als ${light_cyan}Superuser${colors_off} (Sudoer) eingerichtet,"
    e_and_l " so dass dieses Skript auch von solchen Benutzern ausgeführt werden kann."
    ask_yes_or_no_plus "other_sudoers" " Willst Du jetzt trotzdem als ${bold_yellow}$USER_USERNAME${colors_off} weitermachen" "" "n"
    if [ $? -ne 1 ];
    then
      exit 0
    fi
  fi
}

#===============================================================================
# Versionsnummer der Form A.B.C.D in nummerischen Wert umwandeln
# ---------------------------------------------------------------
# HINWEIS: Führende Nullen interpretiert Bash als oktale Zahlen,
# die Werte daher mit dem Prefix 10# versehen (Dezimal-Wert) ;)
#===============================================================================
function get_version_value {
  THE_VERSION=$(echo -n ${1} | sed -E "s/\-/\./g" | sed -E "s/[^0-9\.]//g" | xargs)
  VERSION_PART_1=$(echo ${THE_VERSION} | cut -d '.' -f 1 | xargs)
  if [ "$VERSION_PART_1" == "" ]; then VERSION_PART_1="000"; fi
  VERSION_PART_2=$(echo ${THE_VERSION} | cut -d '.' -f 2 | xargs)
  if [ "$VERSION_PART_2" == "" ]; then VERSION_PART_2="000"; fi
  VERSION_PART_3=$(echo ${THE_VERSION} | cut -d '.' -f 3 | xargs)
  if [ "$VERSION_PART_3" == "" ]; then VERSION_PART_3="000"; fi
  VERSION_PART_4=$(echo ${THE_VERSION} | cut -d '.' -f 4 | xargs)
  if [ "$VERSION_PART_4" == "" ]; then VERSION_PART_4="000"; fi
  VERSION_VALUE=$(((10#${VERSION_PART_1:0:3}*1000000000)+(10#${VERSION_PART_2:0:3}*1000000)+(10#${VERSION_PART_3:0:3}*1000)+(10#${VERSION_PART_4:0:3}*1)))
  echo -e -n "$VERSION_VALUE"
}

#===============================================================================
# Auslesen eines dconf-Wertes
#===============================================================================
function gsettings_get {
  if gsettings --version &>/dev/null;
  then
    GS_RETURN_VALUE=$(sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" gsettings get ${1} ${2} 2>/dev/null)
    if [ $? -eq 0 ];
    then
      echo "$GS_RETURN_VALUE" | sed s/\'//g | sed s/\"//g
      return 0
    else
      GS_RETURN_VALUE=$(gsettings get ${1} ${2} 2>/dev/null)
      if [ $? -eq 0 ];
      then
        echo -e -n "$GS_RETURN_VALUE" | sed s/\'//g | sed s/\"//g
        return 0
      else
        echo -e -n ""
        return 1
      fi
    fi
  else
    echo -e -n ""
    return 1
  fi
}

#===============================================================================
# Setzen eines dconf-Wertes
#===============================================================================
function gsettings_set {
  if gsettings --version &>/dev/null;
  then
    gsettings set ${1} ${2} ${3} &>/dev/null
    GS_RETURN_CODE=$?
    sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" gsettings set ${1} ${2} ${3} &>/dev/null
    if [ $? -eq 0 ] ||
       [ $GS_RETURN_CODE -eq 0 ];
    then
      return 0
    else
      return 1
    fi
  else
    return 1
  fi
}

#===============================================================================
# Einfügung einer bestimmten Anzahl von (Leer-)Zeichen
# -----------------------------------------------------
# Parameter $1: Anzahl
# Parameter $2: Füllzeichen (optional)
# Parameter $3: Schriftfarbe (optional)
#===============================================================================
function insert_spaces {
  FILL_CHAR=" "
  CHR_COLOR=""
  END_COLOR=""
  if [ "$2" != "" ]; then FILL_CHAR="${2:0:1}"; fi
  if [ "$3" != "" ]; then CHR_COLOR="${3}"; END_COLOR="${colors_off}"; fi
  echo -e -n "$CHR_COLOR"
  i=1
  while [ $i -le $1 ];
  do
    echo -e -n "$FILL_CHAR"
    ((i+=1))
  done
  echo -e -n "$END_COLOR"
}

#===============================================================================
# Installation eines Programmpakets
#===============================================================================
function install_pkg {
  PAKET=$1
  APT_PKG_EXTENDED_NAME=""
  INSTALL_TRY=$2
  IS_SIMILAR_PKG=$3
  IS_UPDATE=$4

  # echo -e "| $PAKET | $INSTALL_TRY | $IS_SIMILAR_PKG | $IS_UPDATE |" # NUR ZUM TESTEN

  # ---------------------------------------------------------------
  # Zähler für Hinweise zu ähnlichen bereits installierten Paketen
  # ---------------------------------------------------------------
  SIMILAR_WARNING_SHOWN=0

  # ------------------------------------------------------------------
  # Beim ersten Versuch ein Trennzeichen und laufende Nummer anzeigen
  # ------------------------------------------------------------------
  LFD_NR=""
  if [ $INSTALL_TRY = 0 ];
  then
    if [ $IS_UPDATE -eq 1 ];
    then
      e_and_l -n "$PRE_SPACE"
    else
      if [ $pkg_in_category -eq 0 ];
      then
        e_and_l "$FULL_LINE"
      else
        e_and_l "$HALF_LINE"
      fi
      LFD_NR=$(show_nr $PAKETS_COUNTER)
      e_and_l -n "$LFD_NR"
    fi
  fi

  # -------------------------------------------------------------
  # Nur weitermachen, wenn das Paket nicht schon installiert ist
  # -------------------------------------------------------------
  get_install_status $PAKET
  INST_RES=$?
  if [ $INST_RES -eq 0 ];
  then

    # ------------------------------------------------------------------
    # Nach der zweiten Iteration abbrechen um Endlosschleife abzufangen
    # => zugunsten mehrstufiger Alternativen-Suche erstmal weggelassen
    # ------------------------------------------------------------------
    # if [ $INSTALL_TRY -gt 1 ];
    # then
    #   ((PAKETS_NOAVAIL+=1))
    #   ((PAKETS_COUNTER+=1))
    #   e_and_l "$PRE_SPACE $ERROR_TAG: Das Programmpaket ${light_red}$PAKET${colors_off} konnte nicht gefunden werden."
    #   return 0
    # fi

    SKIP_THIS=0
    SKIP_REASON=""
    # -----------------------------------------------------------
    # Per Parameter angegebene wegzulassende Pakete überspringen
    # -----------------------------------------------------------
    if [ ${#SKIP_LIST[@]} -ne 0 ];
    then
      for skip_this_pkg in ${SKIP_LIST[@]};
      do
        if [ "$PAKET" == "$skip_this_pkg" ];
        then
          SKIP_THIS=1
          SKIP_REASON=" (mit skippkgs ausgeschlossen)"
          break
        fi
      done
    fi

    # -----------------------------------------------------------
    # Nicht verfügbare Pakete auf Raspberry / Pi OS überspringen
    # -----------------------------------------------------------
    if [ $SKIP_THIS -eq 0 ];
    then
      check_skip_raspi $PAKET
      SKIP_THIS=$?
      SKIP_REASON=" (in Ausschlussliste)"
    fi

    # -----------------------------------------------------------------
    # Paket überspringen, wenn dessen Basispaket nicht installiert ist
    # -----------------------------------------------------------------
    # ALT: (mit DEPENDS_PACK)
    # -----------------------------------------------------------------
    # DEPENDS_ON_PACK="${DEPENDS_PACK[$PAKET]}"
    # if [ "$DEPENDS_ON_PACK" != "" ];
    # then
    #   ORG_PKG_VERSION="$PKG_VERSION"
    #   get_install_status "$DEPENDS_ON_PACK"
    #   if [ $? -eq 0 ];
    #   then
    #     SKIP_THIS=1
    #     SKIP_REASON=" (unerfüllte Abhängigkeit)"
    #   fi
    #   PKG_VERSION="$ORG_PKG_VERSION"
    # fi
    # -----------------------------------------------------------------
    # NEU (mit AUTO_ADD_PKGS)
    # -----------------------------------------------------------------

    # ----------------------------------------------------------------------
    # Wenn das zu installierende Paket selbst ein Basispaket ist, zu dem
    # genau ein anderes Paket vorher installiert werden soll (bspw. -data),
    # dann den Status des vorher zu installierenden Paketes prüfen.
    # ----------------------------------------------------------------------
    PRE_INST_PKG_NAME=""
    PRE_INST_PKG_INST_STATUS=0
    for base_pack in ${!AUTO_ADD_PKGS[@]};
    do
      if [ "$base_pack" == "$PAKET" ];
      then
        if [ "${AUTO_ADD_PPOS[$base_pack]}" == "true" ];
        then
          PRE_REQ_ADD_LIST="${AUTO_ADD_PKGS[$base_pack]}"
          if [ ${#PRE_REQ_ADD_LIST[@]} -eq 1 ];
          then
            PRE_INST_PKG_NAME=${PRE_REQ_ADD_LIST[0]}
            ORG_PKG_VERSION="$PKG_VERSION"
            get_install_status "$PRE_INST_PKG_NAME"
            PRE_INST_PKG_INST_STATUS=$?
            PKG_VERSION="$ORG_PKG_VERSION"
          fi
        fi
      fi
    done

    # ---------------------------------------------------------------------
    # Wenn das zu installierende Paket ein Basispaket hat, welches vorher
    # installiert werden soll, dann den Status dieses Basispaketes prüfen.
    # ---------------------------------------------------------------------
    BASE_PKG_NAME=""
    BASE_PKG_INST_STATUS=0
    for base_pack in ${!AUTO_ADD_PKGS[@]};
    do
      if [ "${AUTO_ADD_PPOS[$base_pack]}" != "true" ];
      then
        if [ "$BASE_PKG_NAME" == "" ];
        then
          BASE_PKG_ADD_LIST="${AUTO_ADD_PKGS[$base_pack]}"
          for add_pack in ${BASE_PKG_ADD_LIST};
          do
            if [ "$PAKET" == "$add_pack" ];
            then
              BASE_PKG_NAME="$base_pack"
              ORG_PKG_VERSION="$PKG_VERSION"
              get_install_status "$BASE_PKG_NAME"
              BASE_PKG_INST_STATUS=$?
              if [ $BASE_PKG_INST_STATUS -eq 0 ];
              then
                SKIP_THIS=1
                SKIP_REASON=" (${light_cyan}$base_pack${colors_off} ist nicht installiert)"
              fi
              PKG_VERSION="$ORG_PKG_VERSION"
              break
            fi
          done
        fi
      fi
    done

    # ----------------------------------------------------------------
    # Nur weitermachen, wenn das Paket nicht übersprungen werden soll
    # ----------------------------------------------------------------
    if [ $SKIP_THIS -eq 0 ];
    then

      # ---------------------------------------------------------------
      # 1. Ermitteln, auf welche Art das Paket installiert werden kann
      # ---------------------------------------------------------------
      INST_MODE_LIST="0" # Liste der möglichen Installations-Modi
      INSTALL_MODE=0     # Tatsächlich ausgewählter Installations-Modus

      IDX_NAME="$PAKET"
      IDX_NAME+="_"
      IDX_NAME+="$ARCHITECTURE_MAIN"
      OTHER_ARCH_TEXT=""
      PKG_FOREIGN_ARCH=""

      # ----------------------------------------------------------
      # Prüfen ob das Paket in der Force-Snap-Liste enthalten ist,
      # also bevorzugt als Snap zu installieren ist
      # ----------------------------------------------------------
      FORCE_THIS_SNAPPY=0
      if [ ${OPTION_FLAG[addsnap]} -eq 1 ] &&
         [ $SNAP_ACTIVE -gt 0 ] &&
         [ ${#FORCE_SNAPPY_LIST[@]} -ne 0 ];
      then
        for snap_this_pkg in ${FORCE_SNAPPY_LIST[@]};
        do
          if [ "$PAKET" == "$snap_this_pkg" ];
          then
            FORCE_THIS_SNAPPY=1
            break
          fi
        done
      fi

      # ----------------------------------------------------------
      # Prüfen ob das Paket in der Force-Flatpak-Liste enthalten
      # ist, also bevorzugt als Flatpak zu installieren ist
      # ----------------------------------------------------------
      FORCE_THIS_FLATPAK=0
      if [ ${OPTION_FLAG[addflat]} -eq 1 ] &&
         [ $FLATPAK_ACTIVE -eq 1 ] &&
         [ ${#FORCE_FLATPAK_LIST[@]} -ne 0 ];
      then
        for flatpak_this_pkg in ${FORCE_FLATPAK_LIST[@]};
        do
          if [ "$PAKET" == "$flatpak_this_pkg" ];
          then
            FORCE_THIS_FLATPAK=1
            break
          fi
        done
      fi

      # ------------------------------------------------------------
      # Prüfen ob das Paket in der Force-Extern-Liste enthalten ist,
      # also bevorzugt aus einer externen Quelle zu installieren ist
      # ------------------------------------------------------------
      FORCE_THIS_EXTERN=0
      if [ ${#FORCE_EXTERN_LIST[@]} -ne 0 ];
      then
        for extern_this_pkg in ${FORCE_EXTERN_LIST[@]};
        do
          if [ "$PAKET" == "$extern_this_pkg" ];
          then
            FORCE_THIS_EXTERN=1
            break
          fi
        done
      fi

      # -------------------------------------------------------------
      # 1.1. Prüfen ob Paket im Standard-Repository (oder im zweiten
      #      Durchlauf mit erweitertem Repository) verfügbar ist,
      #      sofern nicht ein anderes Paketformat festgelegt ist
      # -------------------------------------------------------------
      if [ $FORCE_THIS_SNAPPY -eq 0 ] &&
         [ $FORCE_THIS_FLATPAK -eq 0 ] &&
         [ $FORCE_THIS_EXTERN -eq 0 ];
      then
        if [ $(apt list "$PAKET" -a 2>/dev/null | grep -i -E "$PAKET" | grep -i -v -E "[0-9]snap" | grep -i -c -E "$ARCHITECTURE_ALL") -gt 0 ];
        then
          # APT_PKG_EXTENDED_NAME="$(apt list "$PAKET" -a 2>/dev/null | grep -i -E "$PAKET" | grep -i -v -E "[0-9]snap" | grep -i -E "$ARCHITECTURE_ALL" | head -n 1 | awk '{print $1}')"
          APT_PKG_EXTENDED_NAME="$PAKET"
          # Zur Sicherheit Triggerung einer Snap-Installation durch "Depends: snapd" nochmals abfangen
          if [ $(LANG=C apt show "$APT_PKG_EXTENDED_NAME" -a 2>/dev/null | grep -i -E "depend.*\:" | grep -c -i -E "\bsnapd\b") -eq 0 ];
          then
            INST_MODE_LIST+=",1"
            INSTALL_MODE=1
          fi
        fi
      fi

      # -----------------------------------------------------------------------
      # 1.2. Prüfen ob das Programmpaket als Snap-Paket verfügbar ist (SNAP)
      #      Bei Aufruf von install_pkg nach Erweiterung der Repos auslassen
      # -----------------------------------------------------------------------
      if [ ${OPTION_FLAG[addsnap]} -eq 1 ] &&
         [ $FORCE_THIS_FLATPAK -eq 0 ] &&
         [ $FORCE_THIS_EXTERN -eq 0 ] &&
         [ $SNAP_ACTIVE -gt 0 ];
# TODO: Testen, ob diese Prüfungen tatsächlich ausgelassen werden können
# [ "$LAST_ERW_PACK" == "" ] &&
# [ "$LAST_PPA_PACK" == "" ];
      then
        snap info "$PAKET" &>/dev/null
        if [ $? -eq 0 ];
        then
          INST_MODE_LIST+=",2"
          INSTALL_MODE=2
        fi
      fi

      # -----------------------------------------------------------------------
      # 1.3. Prüfen ob das Programmpaket als Flatpak-Paket verfügbar ist (FLAT)
      #      Bei Aufruf von install_pkg nach Erweiterung der Repos auslassen
      # -----------------------------------------------------------------------
      if [ ${OPTION_FLAG[addflat]} -eq 1 ] &&
         [ $FORCE_THIS_SNAPPY -eq 0 ] &&
         [ $FORCE_THIS_EXTERN -eq 0 ] &&
         [ $FLATPAK_ACTIVE -eq 1 ];
# TODO: Testen, ob diese Prüfungen tatsächlich ausgelassen werden können
# [ "$LAST_ERW_PACK" == "" ] &&
# [ "$LAST_PPA_PACK" == "" ];
      then
        FLATPAK_NAME=$(echo "$PAKET" | sed 's/[ -_]//g' | xargs)
        if [ $(grep -c -i -E "\.$FLATPAK_NAME[0-9]*[\/\.]" ${FLATPAK_REMOTE_LIST}) -gt 0 ] ||
           [ $(grep -c -i -E "^$FLATPAK_NAME[0-9]*\s+[0-9]" ${FLATPAK_REMOTE_LIST}) -gt 0 ];
        then
          INST_MODE_LIST+=",6"
          INSTALL_MODE=6
        fi
      fi

      # -----------------------------------------------------------------
      # 1.4. Prüfen ob es für das Paket Eintragungen zur Erweiterung des
      #      Repo gibt, diese durchführen und install_pkg neu aufrufen
      #      sofern nicht eine andere Paketverwaltung bevorzugt wird
      # -----------------------------------------------------------------
      if [ ${OPTION_FLAG[extends]} -eq 1 ] &&
         [ $FORCE_THIS_SNAPPY -eq 0 ] &&
         [ $FORCE_THIS_FLATPAK -eq 0 ] &&
         [ $FORCE_THIS_EXTERN -eq 0 ];
      then
        # -----------
        # 1.4.1. ERW
        # -----------
        if [ "$LAST_ERW_PACK" != "$PAKET" ];
        then
          # LAST_ERW_PACK="$PAKET"
          if [ "${ERW_AUTH_KEY[$PAKET]}" != "" ] &&
             [ "${ERW_REPO_TXT[$PAKET]}" != "" ];
          then
            # if [ $INSTALL_TRY -eq 0 ];
            # then
              LAST_ERW_PACK="$PAKET"
              extend_repo_erw "$PAKET"
              e_and_l -n "$PRE_SPACE"
            # fi
            ((INSTALL_TRY+=1))
            install_pkg $PAKET $INSTALL_TRY 0 0
            return 0
          fi
        fi
        # -----------
        # 1.4.2. PPA
        # -----------
        if [ "$LAST_PPA_PACK" != "$PAKET" ];
        then
          # LAST_PPA_PACK="$PAKET"
          if [ "${PPA_REPO_TXT[$PAKET]}" != "" ];
          then
            # if [ $INSTALL_TRY -eq 0 ];
            # then
              LAST_PPA_PACK="$PAKET"
              extend_repo_ppa "$PAKET"
              e_and_l -n "$PRE_SPACE"
            # fi
            ((INSTALL_TRY+=1))
            install_pkg $PAKET $INSTALL_TRY 0 0
            return 0
          fi
        fi
      fi

      # -----------------------------------------------------------------
      # 1.5. Prüfen ob das Paket in der .deb-Datei-Liste enthalten ist
      #      und diese Datei auch als Download zur Verfügung steht (DEB)
      # -----------------------------------------------------------------
      if [ ${OPTION_FLAG[external]} -eq 1 ] &&
         [ $FORCE_THIS_SNAPPY -eq 0 ] &&
         [ $FORCE_THIS_FLATPAK -eq 0 ];
      then
        # --------------------------------------------------------
        # Installations-Kandidaten für Haupt-Architekturen suchen
        # --------------------------------------------------------
        PACKAGE_FILE_DEB_URL="${DEB_PKG_FILE[$IDX_NAME]}"
        PACKAGE_CSUM_DEB_URL="${DEB_PKG_CSUM[$IDX_NAME]}"
        if [ "$PACKAGE_FILE_DEB_URL" != "" ];
        then
          check_url_file "$PACKAGE_FILE_DEB_URL"
          if [ $? -eq 0 ];
          then
            INST_MODE_LIST+=",3"
            INSTALL_MODE=3
          fi
        fi
        # --------------------------------------------------------------------
        # Wenn kein Installations-Kandidat für die Haupt-Architektur gefunden
        # wurde, dann Installations-Kandidaten für Fremd-Architekturen suchen
        # --------------------------------------------------------------------
        if [ $INSTALL_MODE -ne 3 ];
        then
          for other_arch in ${ARCH_NAME_LIST[@]};
          do
            if [ "$other_arch" != "$ARCHITECTURE_MAIN" ];
            then
              OTHER_IDX_NAME="$PAKET"
              OTHER_IDX_NAME+="_"
              OTHER_IDX_NAME+="$other_arch"
              PACKAGE_FILE_DEB_URL="${DEB_PKG_FILE[$OTHER_IDX_NAME]}"
              PACKAGE_CSUM_DEB_URL="${DEB_PKG_CSUM[$OTHER_IDX_NAME]}"
              if [ "$PACKAGE_FILE_DEB_URL" != "" ];
              then
                if [ ${OPTION_FLAG[foreign]} -ne 0 ] &&
                  [ "$other_arch" == "$ARCHITECTURE_OTHER" ];
                then
                  check_url_file "$PACKAGE_FILE_DEB_URL"
                  if [ $? -eq 0 ];
                  then
                    INST_MODE_LIST+=",3"
                    INSTALL_MODE=3
                    PKG_FOREIGN_ARCH="$other_arch"
                    OTHER_ARCH_TEXT=""
                    break
                  fi
                else
                  if [ ! "$OTHER_ARCH_TEXT" == "" ]; then OTHER_ARCH_TEXT+=", "; fi
                  OTHER_ARCH_TEXT+="$other_arch"
                fi
              fi
            fi
          done
        fi
      fi

      # --------------------------------------------------------------
      # 1.6. Prüfen ob das Paket in der Liste der Downloads enthalten
      #      und als solcher auch verfügbar ist (WEB)
      # --------------------------------------------------------------
      if [ ${OPTION_FLAG[external]} -eq 1 ] &&
         [ $FORCE_THIS_SNAPPY -eq 0 ] &&
         [ $FORCE_THIS_FLATPAK -eq 0 ];
      then
        # --------------------------------------------------------
        # Installations-Kandidaten für Haupt-Architekturen suchen
        # --------------------------------------------------------
        PACKAGE_FILE_WEB_URL="${WEB_PKG_FILE[$IDX_NAME]}"
        PACKAGE_CSUM_WEB_URL="${WEB_PKG_CSUM[$IDX_NAME]}"
        if [ "$PACKAGE_FILE_WEB_URL" != "" ];
        then
          check_url_file "$PACKAGE_FILE_WEB_URL"
          if [ $? -eq 0 ];
          then
            INST_MODE_LIST+=",4"
            INSTALL_MODE=4
            PACKAGE_INST_DIR="$WEB_PKG_DIR/${WEB_PKG_NAME[$PAKET]}"
          fi
        fi
        # --------------------------------------------------------------------
        # Wenn kein Installations-Kandidat für die Haupt-Architektur gefunden
        # wurde, dann Installations-Kandidaten für Fremd-Architekturen suchen
        # --------------------------------------------------------------------
        if [ $INSTALL_MODE -ne 4 ];
        then
          for other_arch in ${ARCH_NAME_LIST[@]};
          do
            if [ "$other_arch" != "$ARCHITECTURE_MAIN" ];
            then
              OTHER_IDX_NAME="$PAKET"
              OTHER_IDX_NAME+="_"
              OTHER_IDX_NAME+="$other_arch"
              PACKAGE_FILE_WEB_URL="${WEB_PKG_FILE[$OTHER_IDX_NAME]}"
              PACKAGE_CSUM_WEB_URL="${WEB_PKG_CSUM[$OTHER_IDX_NAME]}"
              if [ "$PACKAGE_FILE_WEB_URL" != "" ];
              then
                if [ ${OPTION_FLAG[foreign]} -ne 0 ] &&
                  [ "$other_arch" == "$ARCHITECTURE_OTHER" ];
                then
                  check_url_file "$PACKAGE_FILE_WEB_URL"
                  if [ $? -eq 0 ];
                  then
                    INST_MODE_LIST+=",4"
                    INSTALL_MODE=4
                    PKG_FOREIGN_ARCH="$other_arch"
                    OTHER_ARCH_TEXT=""
                    PACKAGE_INST_DIR="$WEB_PKG_DIR/${WEB_PKG_NAME[$PAKET]}"
                    break
                  fi
                else
                  if [ ! "$OTHER_ARCH_TEXT" == "" ]; then OTHER_ARCH_TEXT+=", "; fi
                  OTHER_ARCH_TEXT+="$other_arch"
                fi
              fi
            fi
          done
        fi
      fi

      # -------------------------------------------------------------
      # 1.7. Prüfen ob Paket im Standard-Repository vorhanden ist,
      #      sofern ein anderes Paketformat bevorzugt wurde,
      #      aber kein solches Paket gefunden wurde
      # -------------------------------------------------------------
      if [ $INSTALL_MODE -eq 0 ];
      then
        if [ $FORCE_THIS_SNAPPY -ne 0 ] ||
           [ $FORCE_THIS_FLATPAK -ne 0 ] ||
           [ $FORCE_THIS_EXTERN -ne 0 ];
        then
          if [ $(apt list "$PAKET" -a 2>/dev/null | grep -i -E "$PAKET" | grep -i -v -E "[0-9]snap" | grep -i -c -E "$ARCHITECTURE_ALL") -gt 0 ];
          then
            # APT_PKG_EXTENDED_NAME="$(apt list "$PAKET" -a 2>/dev/null | grep -i -E "$PAKET" | grep -i -v -E "[0-9]snap" | grep -i -E "$ARCHITECTURE_ALL" | head -n 1 | awk '{print $1}')"
            APT_PKG_EXTENDED_NAME="$PAKET"
            # Zur Sicherheit Triggerung einer Snap-Installation durch "Depends: snapd" nochmals abfangen
            if [ $(LANG=C apt show "$APT_PKG_EXTENDED_NAME" -a 2>/dev/null | grep -i -E "depend.*\:" | grep -c -i -E "\bsnapd\b") -eq 0 ];
            then
              INST_MODE_LIST+=",1"
              INSTALL_MODE=1
            fi
          fi
        fi
      fi

      # -----------------------------------------------------------
      # 1.8. Wenn kein Installations-Kandidat gefunden wurde, dann
      #      eine neue Suche nach einem ähnlichen Paket starten
      # -----------------------------------------------------------
      if [ $INSTALL_MODE -eq 0 ];
      then
        if [ "$OTHER_ARCH_TEXT" != "" ];
        then
          AVAIL_TEXT="nur verfügbar für ${bold_magenta}$OTHER_ARCH_TEXT${colors_off}"
        else
          AVAIL_TEXT="$NA_TXT"
          if [ ${OPTION_FLAG[extends]}  -eq 0 ] ||
             [ ${OPTION_FLAG[external]} -eq 0 ] ||
             [ ${OPTION_FLAG[addflat]}  -eq 0 ] ||
             [ ${OPTION_FLAG[addsnap]}  -eq 0 ];
          then
            AVAIL_TEXT+=" ${dark_gray}(andere Quelle?)${colors_off}"
          fi
        fi
        e_and_l " ${light_red}$PAKET${colors_off} ist $AVAIL_TEXT"
        # --------------------------------------------------------------
        # Wenn es vor der erfolglosen Suche des Pakets eine Erweiterung
        # des Repository gegeben hat, diese wieder bereinigen
        # --------------------------------------------------------------
        if [ "$LAST_ERW_PACK" != "" ] &&
           [ "$OTHER_ARCH_TEXT" == "" ];
        then
          clear_repo "$PAKET"
        fi
        # ----------------------------------------------------------------------
        # Wenn ein Alternativ-Paket angegeben und nicht gesperrt ist, dann
        # prüfen, ob dieses nicht bereits in einer vorangegangenen Schleife
        # versucht wurde zu installieren, und wenn auch das nicht der Fall ist,
        # dann Installation mit dem Alternativ-Paket durchstarten ...
        # ----------------------------------------------------------------------
        if [ ${OPTION_FLAG[skipsims]} -eq 0 ] &&
           [ "${SIMILAR_PACK[$PAKET]}" != "" ];
        then
          # ------------------------------------------------------
          # Zur Vermeidung von Endlos-Schleifen nur weitermachen
          # wenn das Paket vorher nicht bereits verarbeitet wurde
          # ------------------------------------------------------
          PACK_ALREADY_SEEN=0
          for seen in ${PACKS_SEEN_LIST[@]};
          do
            if [ "$seen" != "" ] &&
               [ "${SIMILAR_PACK[$PAKET]}" == "$seen" ];
            then
              PACK_ALREADY_SEEN=1
              break
            fi
          done
          # ------------------------------------------------------
          if [ $PACK_ALREADY_SEEN -eq 0 ];
          then
            PACKS_SEEN_LIST+=("${SIMILAR_PACK[$PAKET]}")
            ((PAKETS_NOAVAIL+=1))
            if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA+=1)) ; fi
            e_and_l -n "$PRE_SPACE Alternative"
            ((INSTALL_TRY+=1))
            install_pkg "${SIMILAR_PACK[$PAKET]}" $INSTALL_TRY 1 0
            return 0
          fi
        fi
      fi

      # ------------------------------------------------------------------------
      # 2. Wenn ein Installations-Kandidat gefunden wurde, dann Installation
      #    und ggf, weitere Aktionen wie Konfiguration etc. durchführen
      #    (der Übersicht halber wieder nacheinander und nicht mit elseifs ;)
      # ------------------------------------------------------------------------
      if [ $INSTALL_MODE -ne 0 ];
      then

        if [ ${OPTION_FLAG[status]} -eq 0 ];
        then

          CONTINUE_INSTALL=1

          ASKED_ALREADY_TO_CONTINUE=0
          # --------------------------------------------------------------------
          # Wenn das Paket aus mehreren Quellen zur Verfügung steht, vor der
          # Installation prüfen ob es dies aus einer bevorzugten Quelle gibt,
          # ansonsten den Benutzer eine Auswahl treffen lassen.
          # --------------------------------------------------------------------
          if [ ${#INST_MODE_LIST} -gt 3 ]; # "0,n" z.B. "0,2,4"
          then
            # -----------------------------------------------------
            # Wenn es ein Flatpak gibt und dies bevorzugt wird ...
            # -----------------------------------------------------
            if [ $(echo ${INST_MODE_LIST} | grep -c -E ",6") -gt 0 ] &&
               [ ${OPTION_FLAG[prioflat]} -eq 1 ];
            then
              INSTALL_MODE=6
            else
              # -------------------------------------------------------------
              # ... sonst, wenn es ein SNAP gibt und dies bevorzugt wird ...
              # -------------------------------------------------------------
              if [ $(echo ${INST_MODE_LIST} | grep -c -E ",2") -gt 0 ] &&
                 [ ${OPTION_FLAG[priosnap]} -eq 1 ];
              then
                INSTALL_MODE=2
              else
                # --------------------------------------------
                # ... sonst weitere Prüfungen durchführen und
                #     ggf. den Benutzer auswählen lassen
                # --------------------------------------------
                DO_ASK_FOR_INSTALL_MODE=1
                # -------------------------------------------------------
                # Wenn das Paket aus gleicher Quelle wie das Basis-Paket
                # sein muss weitere Prüfungen durchführen
                # -------------------------------------------------------
                if [ ${OPTION_FLAG[esamesrc]} -eq 1 ];
                then
                  # ------------------------------------------------
                  # Wenn es das Paket nicht aus der gleichen Quelle
                  # gibt, dann die Installation abbrechen
                  # ------------------------------------------------
                  if [[ "$PRE_INST_PKG_NAME" != "" && $(echo ${INST_MODE_LIST} | grep -c -i -E "\,$PRE_INST_PKG_INST_STATUS") -eq 0 ]] ||
                     [[ "$BASE_PKG_NAME" != "" && $(echo ${INST_MODE_LIST} | grep -c -i -E "\,$BASE_PKG_INST_STATUS") -eq 0 ]];
                  then
                    show_base_pkg $PAKET 0
                    e_and_l " Das Paket ${light_yellow}$PAKET${colors_off} (${light_magenta}$(inst_status_to_name $INSTALL_MODE)${colors_off}) wird daher ${bold_white}nicht${colors_off} installiert."
                    INSTALL_MODE=0
                    DO_ASK_FOR_INSTALL_MODE=0
                  fi
                  # ---------------------------------------------------------
                  # Wenn es das Paket aus der gleichen Quelle gibt, dann
                  # automatisch die Installation aus dieser Quelle auswählen
                  # ---------------------------------------------------------
                  if [[ "$PRE_INST_PKG_NAME" != "" && $(echo ${INST_MODE_LIST} | grep -c -i -E "\,$PRE_INST_PKG_INST_STATUS") -gt 0 ]];
                  then
                    INSTALL_MODE=$PRE_INST_PKG_INST_STATUS
                    DO_ASK_FOR_INSTALL_MODE=0
                  fi
                  if [[ "$BASE_PKG_NAME" != "" && $(echo ${INST_MODE_LIST} | grep -c -i -E "\,$BASE_PKG_INST_STATUS") -gt 0 ]];
                  then
                    INSTALL_MODE=$BASE_PKG_INST_STATUS
                    DO_ASK_FOR_INSTALL_MODE=0
                  fi
                fi
                # --------------------------------------------
                # Wenn zuletzt immer weiterhin eine Auswahl
                # besteht, dann den Benutzer auswählen lassen
                # --------------------------------------------
                if [ $DO_ASK_FOR_INSTALL_MODE -eq 1 ];
                then
                  show_base_pkg $PAKET 0
                  ask_for_install_mode "$PAKET" "$INST_MODE_LIST"
                  INSTALL_MODE=$?
                fi
                if [ $INSTALL_MODE -eq 0 ];
                then
                  CONTINUE_INSTALL=0
                fi
              fi
            fi
          else
          # --------------------------------------------------------------------
          # Zusätzliche Abfrage, wenn es keine Mehrfachauswahl zur Quelle gibt
          # und ein erforderliches Basispaket oder ein zugehöriges vorher zu
          # installierendes Paket nicht oder aus anderer Quelle installiert ist
          # --------------------------------------------------------------------
            show_base_pkg $PAKET 1
          fi

          # --------------------------------------------------------------------
          # Ja/Nein-Abfrage (wird automatisch mit Ja beantwortet, wenn die
          # Option "force" gewählt wurde und es auch keinen Konflikt gibt)
          # Wird alles in "ask_yes_no_info" überprüft ;)
          # --------------------------------------------------------------------
          if [ $CONTINUE_INSTALL -eq 1 ] &&
             [ $ASKED_ALREADY_TO_CONTINUE -eq 0 ];
          then
            ask_yes_no_info "$PAKET" 0
            CONTINUE_INSTALL=$?
          fi

          # --------------------------------------------------------------------
          # Wenn Hinweise zu Voraussetzungen existieren, diese
          # vorher anzeigen und ggf. Tests dazu durchführen
          # --------------------------------------------------------------------
          if [ $CONTINUE_INSTALL -eq 1 ];
          then
            if [ "${DEB_PKG_MESG["$PAKET"]}" != "" ] ||
               [ "${WEB_PKG_MESG["$PAKET"]}" != "" ];
            then
              if [ ${OPTION_FLAG[force]} -ne 0 ];
              then
                e_and_l -n " Installation von ${light_yellow}$PAKET${colors_off}"
                if [ "$PKG_VERSION" != "" ];
                then
                  e_and_l -n " ${light_yellow}$PKG_VERSION${colors_off}"
                fi
                e_and_l -n " (${light_magenta}$(inst_status_to_name $INSTALL_MODE)${colors_off}) ... "
                if [ ${OPTION_FLAG[quiet]} -eq 0 ]; then e_and_l ""; fi
              fi
              FILL_WORD="wirklich"
              # ----------------------------------------------------
              # Falls vorhanden Hinweis zu Voraussetzungen anzeigen
              # ----------------------------------------------------
              SHOW_PKG_MSG="${WEB_PKG_MESG["$PAKET"]}"
              if [ "$SHOW_PKG_MSG" == "" ]; then SHOW_PKG_MSG="${DEB_PKG_MESG["$PAKET"]}"; fi
              if [ "$SHOW_PKG_MSG" != "" ];
              then
                if [ ${OPTION_FLAG[force]} -ne 0 ]; then e_and_l -n "$PRE_SPACE"; fi
                e_and_l " $ACHTUNG_TAG: ${light_yellow}$SHOW_PKG_MSG${colors_off}"
              fi
              # --------------------------------------------------------
              # Falls vorhanden Prüfung der Voraussetzungen durchführen
              # --------------------------------------------------------
              EVAL_RESULT=0
              EVAL_TEST="${WEB_PKG_EVAL["$PAKET"]}"
              if [ "$EVAL_TEST" == "" ]; then EVAL_TEST="${DEB_PKG_EVAL["$PAKET"]}"; fi
              if [ "$EVAL_TEST" != "" ];
              then
                eval "$EVAL_TEST" &>/dev/null
                EVAL_RESULT=$?
                e_and_l -n "$PRE_SPACE Diese Voraussetzung ${bold_white}scheint${colors_off}"
                if [ $EVAL_RESULT -ne 0 ];
                then
                  e_and_l -n " ${bold_red}nicht${colors_off}"
                  FILL_WORD="trotzdem"
                fi
                e_and_l " erfüllt zu sein."
              else
                if [ "$SHOW_PKG_MSG" != "" ];
                then
                  e_and_l "$PRE_SPACE Bitte prüfe vor der Installation, ob diese Voraussetzung erfüllt ist."
                fi
              fi
              e_and_l -n "$PRE_SPACE"
              # ----------------------------------------------------------
              # Nach bestandener Prüfung zu Voraussetzungen normal fragen
              # (mit Option force für automatisches Weitermachen) ...
              # ----------------------------------------------------------
              if [ "$EVAL_TEST" != "" ] &&
                 [ $EVAL_RESULT -eq 0 ];
              then
                # -------------------------------------------------------------
                # Wenn trotz bestandener Prüfung eine weitere Abfrage erfolgen
                # soll, dann auch einen weiteren Hinweis dazu anzeigen
                # -------------------------------------------------------------
                if [ ${OPTION_FLAG[force]} -eq 0 ];
                then
                  e_and_l " Bitte prüfe zur Sicherheit nochmals selbst, ob dies wirklich so ist."
                  e_and_l -n "$PRE_SPACE"
                fi
                ask_yes_no_info "$PAKET" 0
                CONTINUE_INSTALL=$?
              else
                # ----------------------------------------------------------
                #  ... sonst, wenn es keinen bestandenen Test oder nur einen
                #  Hinweis gibt nochmals ohne automatische Antwort fragen
                # ----------------------------------------------------------
                ask_yes_or_no_plus "pkg_pre_$PAKET" " Dieses Programmpaket jetzt $FILL_WORD installieren" "" "n"
                CONTINUE_INSTALL=$?
              fi
              # if [ $CONTINUE_INSTALL -eq 1 ]; then e_and_l -n "${PRE_SPACE}"; fi
            fi
          fi

          # --------------------------------------------------------------------
          # Die Installation kann beginnen ...
          # --------------------------------------------------------------------
          if [ $CONTINUE_INSTALL -eq 1 ];
          then

            # ------------------------------------------------------------------
            # VOR der Installation ggf. vorbereitende Konfiguration durchführen
            # ------------------------------------------------------------------
            PRE_CONF_RESULT=0
            if [ "${PRE_INST_CONF[$PAKET]}" != "" ];
            then
              # e_and_l ""
              e_and_l -n " Führe vorbereitende ${light_yellow}Konfiguration${colors_off} für ${light_yellow}$PAKET${colors_off} durch ... "
              PRE_ACTION="${PRE_INST_CONF[$PAKET]}"
              if [ $(echo -n "$PRE_ACTION" | grep -i -c -E "^\s*http") -gt 0 ];
              then
                CONFIG_FILE_NAME="${PRE_ACTION##*/}"
                CONFIG_URL="$PRE_ACTION"
                LOCAL_CONFIG_FILE="$DOWNLOAD_DIR/$CONFIG_FILE_NAME"
                wget -nv -O "$LOCAL_CONFIG_FILE" "$CONFIG_URL" &>"$LOG_TEMP"
                if [ $? -eq 0 ] &&
                   [ -s "$LOCAL_CONFIG_FILE" ] &&
                   [ $(grep -i -c -E "Error\s*404" "$LOCAL_CONFIG_FILE") -eq 0 ];
                then
                  # ------------------------------------------------------------
                  # Heruntergeladenes Konfigurations-Skript ausführen mit dem Benutzernamen
                  # als erstem Parameter zur Verwendung im aufgerufenen Konfigurations-Skript
                  # ------------------------------------------------------------
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_CONFIG_FILE" &>/dev/null
                  chmod -R 0755 "$LOCAL_CONFIG_FILE" &>/dev/null
                  echo -e ""
                  ( "$LOCAL_CONFIG_FILE" ${USER_USERNAME} ${DOWNLOAD_DIR} ${RESSOURCE_SERVER_DIR} ${OS_V_CODENAME} ${INSTALL_MODE} 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; ) | tee "$LOG_TEMP"
                  if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                  then
                    do_log "$OK_TAG"
                  else
                    do_log "$ERROR_TAG"
                    PRE_CONF_RESULT=1
                  fi
                  # Konfigurations-Skript löschen
                  # remove_file "$LOCAL_CONFIG_FILE"
                else
                  e_and_l ""
                  e_and_l "$PRE_SPACE $ERROR_TAG: Das Konfigurations-Skript konnte nicht geladen werden!"
                  # Durch wget eventuell angelegte unbrauchbare Datei löschen
                  remove_file "$LOCAL_CONFIG_FILE"
                  PRE_CONF_RESULT=1
                fi
                echo -e ""
                if [ ${OPTION_FLAG[skipmesg]} -eq 0 ] &&
                   [ ${OPTION_FLAG[quiet]} -eq 0 ];
                then
                  echo -e -n "$PRE_SPACE Bitte ${bold_white}Enter${colors_off} drücken zum Weitermachen ... "
                  read dummy
                fi
              else
                echo -e ""
                { eval "$PRE_ACTION" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                then
                  do_log "$OK_TAG"
                else
                  do_log "$ERROR_TAG"
                  PRE_CONF_RESULT=1
                fi
              fi
              remove_file "$LAST_EXIT_CODE"
              do_log "Aktion: $PRE_ACTION"
              add_full_log
              echo -e ""
              if [ $PRE_CONF_RESULT -eq 0 ]; then e_and_l -n "$PRE_SPACE"; fi
            fi

            INSTALL_RESULT=1

            # ------------------------------------------------------------------
            # Ggf. nur weitermachen, wenn die vorbereitende Konfiguration
            # erfolgreich war ...
            # ------------------------------------------------------------------
            if [ $PRE_CONF_RESULT -eq 0 ];
            then

              e_and_l -n " Installation von ${light_yellow}$PAKET${colors_off}"
              if [ "$PKG_VERSION" != "" ];
              then
                e_and_l -n " ${light_yellow}$PKG_VERSION${colors_off}"
              fi
              e_and_l -n " (${light_magenta}$(inst_status_to_name $INSTALL_MODE)${colors_off}) ... "
              if [ ${OPTION_FLAG[quiet]} -eq 0 ]; then e_and_l ""; fi

              # ----------------------------------------------------------------
              # Installation mit apt
              # ---------------------
              # Hinweis: Statt dem reinen Paketnamen wird zudem auch die Version
              # bzw. Quelle mit angegeben (dazu wird APT_PKG_EXTENDED_NAME in
              # der Funktioon install_pkg ermittelt), um eine eindeutige Auswahl
              # zu treffen und nicht "versehentlich" wieder automatisch ein vom
              # System "bevorzugtes" Snap zu installieren!
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 1 ] &&
                 [ "$APT_PKG_EXTENDED_NAME" != "" ];
              then
                if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                then
                  echo -n '\n\n\n' | apt install "$APT_PKG_EXTENDED_NAME" -y &>"$LOG_TEMP"
                  INSTALL_RESULT=$?
                else
                  { apt install "$APT_PKG_EXTENDED_NAME" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                  INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                  remove_file "$LAST_EXIT_CODE"
                fi
                if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                then
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                  else
                    e_and_l "$ERROR_TAG"
                  fi
                else
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    do_log "$OK_TAG"
                  else
                    do_log "$ERROR_TAG"
                  fi
                fi
                add_full_log
              fi

              # ----------------------------------------------------------------
              # Installation mit snap
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 2 ];
              then
                # -----------------------------------------
                # Sicherheitsbafrage für "non-stable" Snaps
                SNAP_CHECK_1=1
                SNAP_VERSION_OPTION=""
                TMP_PKG_VERSION=$(get_pkg_snap_version "$PAKET" 0)
                if [ $(echo "$TMP_PKG_VERSION" | grep -i -c -E "candidate") -gt 0 ];
                then
                  SNAP_VERSION_OPTION="--candidate"
                fi
                if [ $(echo "$TMP_PKG_VERSION" | grep -i -c -E "beta") -gt 0 ];
                then
                  SNAP_VERSION_OPTION="--beta --devmode"
                fi
                if [ $(echo "$TMP_PKG_VERSION" | grep -i -c -E "edge") -gt 0 ];
                then
                  SNAP_VERSION_OPTION="--edge --devmode"
                fi
                if [ "$SNAP_VERSION_OPTION" != "" ];
                then
                  SHOW_VERSION_TEXT=${SNAP_VERSION_OPTION//--/}
                  SHOW_VERSION_TEXT=${SHOW_VERSION_TEXT/ devmode/}
                  SHOW_VERSION_TEXT=${SHOW_VERSION_TEXT/ jailmode/}
                  e_and_l "$PRE_SPACE $ACHTUNG_TAG: Die Version \"${light_red}$SHOW_VERSION_TEXT${colors_off}\" ist nicht für den produktiven Einsatz"
                  e_and_l "$PRE_SPACE gedacht sowie ohne Support und somit möglicherweise nicht funktionsfähig!"
                  ask_yes_or_no_plus "snap_non_stable_$PAKET" "$PRE_SPACE Soll diese Version trotzdem installiert werden" "" "n"
                  SNAP_CHECK_1=$?
                fi
                # -----------------------------------------------------
                # Sicherheitsbafrage für "klassische" Snaps
                # Hinweis: Wenn das System keinen jailmode unterstützt,
                # wird die Installation danach ohne jailmode versucht!
                # (Snap ist ja soo inkonsistent ... :(
                SNAP_CHECK_2=1
                SNAP_CLASSIC_OPTION=""
                TMP_PKG_VERSION=$(get_pkg_snap_version "$PAKET" 0)
                if [ $(echo "$TMP_PKG_VERSION" | grep -i -c -E "classic") -gt 0 ];
                then
                  SNAP_CLASSIC_OPTION="--classic --jailmode"
                  e_and_l "$PRE_SPACE $ACHTUNG_TAG: Diese klassische Version ist nicht durch die Sicherheitssandbox"
                  e_and_l "$PRE_SPACE von Snap geschützt und kann möglicherweise ohne manuelle Nacharbeit auch"
                  ask_yes_or_no_plus "snap_classic_$PAKET" "$PRE_SPACE nicht lauffähig sein. Trotzdem installieren" "" "n"
                  SNAP_CHECK_2=$?
                  if [ $SNAP_CHECK_2 -eq 1 ];
                  then
                    e_and_l ""
                    e_and_l " OK, ich versuche erstmal die Installation in einer ${bold_yellow}Sandbox${colors_off} zu erzwingen ..."
                    e_and_l ""
                  fi
                fi
                # -----------------------------------------
                if [ $SNAP_CHECK_1 -eq 1 ] &&
                   [ $SNAP_CHECK_2 -eq 1 ];
                then
                  if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                  then
                    echo -n '\n\n\n' | snap install ${SNAP_VERSION_OPTION} ${SNAP_CLASSIC_OPTION} "$PAKET" &>"$LOG_TEMP"
                    INSTALL_RESULT=$?
                    if [ $INSTALL_RESULT -ne 0 ] &&
                       [ "$SNAP_CLASSIC_OPTION" != "" ];
                    then
                      SNAP_CLASSIC_OPTION=${SNAP_CLASSIC_OPTION/--jailmode/}
                      echo -n '\n\n\n' | snap install ${SNAP_VERSION_OPTION} ${SNAP_CLASSIC_OPTION} "$PAKET" &>"$LOG_TEMP"
                      INSTALL_RESULT=$?
                    fi
                  else
                    { snap install ${SNAP_VERSION_OPTION} ${SNAP_CLASSIC_OPTION} "$PAKET" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                    INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                    if [ $INSTALL_RESULT -ne 0 ] &&
                       [ "$SNAP_CLASSIC_OPTION" != "" ];
                    then
                      e_and_l ""
                      e_and_l " Schade, das hat wohl ${bold_red}nicht${colors_off} funktioniert, also Installation ${bold_yellow}ohne Sandbox${colors_off} ..."
                      e_and_l ""
                      SNAP_CLASSIC_OPTION=${SNAP_CLASSIC_OPTION/--jailmode/}
                      { snap install ${SNAP_VERSION_OPTION} ${SNAP_CLASSIC_OPTION} "$PAKET" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                      INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                    fi
                    remove_file "$LAST_EXIT_CODE"
                  fi
                  if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                  then
                    if [ $INSTALL_RESULT -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                  else
                    if [ $INSTALL_RESULT -eq 0 ];
                    then
                      do_log "$OK_TAG"
                    else
                      do_log "$ERROR_TAG"
                    fi
                  fi
                  add_full_log
                else
                  INSTALL_RESULT=1
                  if [ ${OPTION_FLAG[notoall]} -ne 1 ];
                  then
                    e_and_l "$PRE_SPACE ${light_cyan}$PAKET${colors_off} wurde ${light_red}nicht${colors_off} installiert"
                  fi
                  ((PAKETS_SKIP+=1))
                  ((PAKETS_NOAVAIL-=1))
                fi
              fi  # Ende INSTALL_MODE 2 (Snap)

              # ----------------------------------------------------------------
              # Installation mit flatpak
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 6 ];
              then
                if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                then
                  echo -n '\n\n\n' | flatpak install $(get_pkg_flatpak_reference ${PAKET} 0) --noninteractive -y &>"$LOG_TEMP"
                  INSTALL_RESULT=$?
                else
                  { flatpak install $(get_pkg_flatpak_reference ${PAKET} 0) --noninteractive -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                  INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                  remove_file "$LAST_EXIT_CODE"
                fi
                if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                then
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                  else
                    e_and_l "$ERROR_TAG"
                  fi
                else
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    do_log "$OK_TAG"
                  else
                    do_log "$ERROR_TAG"
                  fi
                fi
                if [ $INSTALL_RESULT -eq 0 ];
                then
                  update_flatpak_list
                fi
                add_full_log
              fi # Ende INSTALL_MODE 6 (Flatpak)

              # ----------------------------------------------------------------
              # Download einer Datei zum Installieren oder Entpacken / Kopieren
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 3 ] ||
                 [ $INSTALL_MODE -eq 4 ];
              then
                if [ $INSTALL_MODE -eq 3 ];
                then
                  PACKAGE_FILE_URL="$PACKAGE_FILE_DEB_URL"
                  PACKAGE_CSUM_URL="$PACKAGE_CSUM_DEB_URL"
                fi
                if [ $INSTALL_MODE -eq 4 ];
                then
                  PACKAGE_FILE_URL="$PACKAGE_FILE_WEB_URL"
                  PACKAGE_CSUM_URL="$PACKAGE_CSUM_WEB_URL"
                fi
                DOWNLOAD_FILE_NAME="${PACKAGE_FILE_URL##*/}"
                LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
                do_log ""
                e_and_l -n "$PRE_SPACE Download von ${light_yellow}$DOWNLOAD_FILE_NAME${colors_off}, bitte warten ... "
                wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$PACKAGE_FILE_URL" &>"$LOG_TEMP"
                DOWNLOAD_RESULT=$?
                if [ $DOWNLOAD_RESULT -eq 0 ] &&
                   [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
                   [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
                then
                  e_and_l "$OK_TAG"
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
                  FAIL_TEXT="$PRE_SPACE Das Paket ${light_yellow}$PAKET${colors_off} wird daher zur Sicherheit ${light_red}nicht${colors_off} installiert!"
                  # Checksumme überprüfen falls vorhanden
                  if [ "$PACKAGE_CSUM_URL" != "" ];
                  then
                    e_and_l -n "$PRE_SPACE Verifiziere heruntergeladene Datei ... "
                    # Checksummen berechnen und formatieren
                    CHECKSUM256=$(shasum -a 256 "$LOCAL_DOWNLOAD_FILE" 2>/dev/null)
                    CHECKSUM256=${CHECKSUM256% *}
                    CHECKSUM512=$(shasum -a 512 "$LOCAL_DOWNLOAD_FILE" 2>/dev/null)
                    CHECKSUM512=${CHECKSUM512% *}
                    CHECKSUM_OK="no"
                    # Wenn es sich um eine URL handelt, dann Download der Checksummen-Datei ...
                    if [ $(echo -n "$PACKAGE_CSUM_URL" | grep -i -c -E "^\s*http") -gt 0 ];
                    then
                      CSUM_FILE_NAME="${PACKAGE_CSUM_URL##*/}"
                      LOCAL_CSUM_DATA="$DOWNLOAD_DIR/$CSUM_FILE_NAME"
                      wget -nv -O "$LOCAL_CSUM_DATA" "$PACKAGE_CSUM_URL" &>"$LOG_TEMP"
                      DOWNLOAD_RESULT=$?
                      if [ $DOWNLOAD_RESULT -eq 0 ] &&
                         [ -s "$LOCAL_CSUM_DATA" ] &&
                         [ $(grep -i -c -E "Error\s*404" "$LOCAL_CSUM_DATA") -eq 0 ];
                      then
                        chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_CSUM_DATA" &>/dev/null
                        # Checksummen vergleichen
                        if [ $(grep -i -c ${CHECKSUM256} "$LOCAL_CSUM_DATA") -gt 0 ] ||
                           [ $(grep -i -c ${CHECKSUM512} "$LOCAL_CSUM_DATA") -gt 0 ];
                        then
                          CHECKSUM_OK="yes"
                        fi
                      else
                        e_and_l "$ERROR_TAG"
                        e_and_l "$PRE_SPACE Die Prüfsummen-Datei konnte nicht heruntergeladen werden!"
                        e_and_l "$FAIL_TEXT"
                        # Durch wget eventuell angelegte unbrauchbare Datei löschen
                        remove_file "$LOCAL_CSUM_DATA"
                        add_full_log
                      fi
                    else # ... sonst ist der Eintrag selbst schon die Checksumme
                      # Checksummen vergleichen
                      if [ $(echo -n "$CHECKSUM256" | grep -i -c "$PACKAGE_CSUM_URL") -gt 0 ] ||
                         [ $(echo -n "$CHECKSUM512" | grep -i -c "$PACKAGE_CSUM_URL") -gt 0 ];
                      then
                        CHECKSUM_OK="yes"
                      fi
                    fi
                    if [ "$CHECKSUM_OK" == "yes" ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      if [ $DOWNLOAD_RESULT -eq 0 ];
                      then
                        e_and_l "$ERROR_TAG: Keine gültige Prüfsumme gefunden!"
                        e_and_l "$FAIL_TEXT"
                      fi
                      INSTALL_RESULT=1
                      DOWNLOAD_RESULT=1 # NICHT Weitermachen
                    fi
                  else
                    e_and_l "$PRE_SPACE $WARN_TAG: Datei kann wegen fehlender Prüfsumme nicht verifiziert werden!"
                    ask_yes_or_no_plus "pkg_no_csum_$PAKET" "$PRE_SPACE ${bold_yellow}$DOWNLOAD_FILE_NAME${colors_off} trotzdem installieren" "" "n"
                    if [ $? -eq 1 ];
                    then
                      e_and_l "$PRE_SPACE $USER_CHOICE_YES"
                    else
                      e_and_l "$PRE_SPACE $USER_CHOICE_NO"
                      ((PAKETS_SKIP+=1))
                      ((PAKETS_NOAVAIL-=1))
                      if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA-=1)); fi
                      INSTALL_RESULT=1
                      DOWNLOAD_RESULT=1 # NICHT Weitermachen
                    fi
                  fi
                else
                  # Durch wget eventuell angelegte unbrauchbare Datei löschen
                  remove_file "$LOCAL_DOWNLOAD_FILE"
                  e_and_l "$ERROR_TAG"
                  e_and_l "$PRE_SPACE Die Datei konnte ${bold_red}nicht${colors_off} heruntergeladen werden!"
                  add_full_log
                  INSTALL_RESULT=1
                  DOWNLOAD_RESULT=1 # NICHT Weitermachen
                fi
              fi

              FOREIGN_WARNING="$PRE_SPACE $ACHTUNG_TAG: Dieses Programmpaket ist nicht für die Haupt-Architektur dieses"$'\n'
              FOREIGN_WARNING+="$PRE_SPACE Systems, sondern für die Fremd-Architektur ${bold_blue}$PKG_FOREIGN_ARCH${colors_off} gedacht. Das Programm"$'\n'
              FOREIGN_WARNING+="$PRE_SPACE ist daher eventuell nicht lauffähig und kann das System destabilisieren!"
              # ----------------------------------------------------------------
              # Installation eines .deb-Pakets
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 3 ] &&
                 [ $DOWNLOAD_RESULT -eq 0 ];
              then
                if [ "$PKG_FOREIGN_ARCH" != "" ];
                then
                  e_and_l "$FOREIGN_WARNING"
                  ask_yes_or_no_plus "pkg_foreign_deb_$PAKET" "$PRE_SPACE ${bold_yellow}$PAKET${colors_off} trotzdem installieren" "" "n"
                  if [ $? -eq 1 ];
                  then
                    e_and_l "$PRE_SPACE $USER_CHOICE_YES"
                  else
                    e_and_l "$PRE_SPACE $USER_CHOICE_NO"
                    ((PAKETS_SKIP+=1))
                    ((PAKETS_NOAVAIL-=1))
                    if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA-=1)); fi
                    INSTALL_RESULT=1
                    DOWNLOAD_RESULT=1 # NICHT Weitermachen
                  fi
                fi
                if [ $DOWNLOAD_RESULT -eq 0 ];
                then
                  e_and_l -n "$PRE_SPACE Installation von ${light_yellow}$LOCAL_DOWNLOAD_FILE${colors_off} ... "
                  if [ ${OPTION_FLAG[quiet]} -eq 0 ]; then e_and_l ""; fi
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
                  chmod -R 0664 "$LOCAL_DOWNLOAD_FILE" &>/dev/null
                  if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                  then
                    echo -n '\n\n\n' | apt install "$LOCAL_DOWNLOAD_FILE" -y &>"$LOG_TEMP"
                    INSTALL_RESULT=$?
                  else
                    { apt install "$LOCAL_DOWNLOAD_FILE" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                    INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                    remove_file "$LAST_EXIT_CODE"
                  fi
                  if [ ${OPTION_FLAG[quiet]} -eq 1 ];
                  then
                    if [ $INSTALL_RESULT -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                  else
                    if [ $INSTALL_RESULT -eq 0 ];
                    then
                      do_log "$OK_TAG"
                    else
                      do_log "$ERROR_TAG"
                    fi
                  fi
                  add_full_log
                fi
              fi # Ende INSTALL_MODE 3 (DEB)

              # ----------------------------------------------------------------
              # Entpacken und Kopieren eines Fremd-Pakets
              # ----------------------------------------------------------------
              if [ $INSTALL_MODE -eq 4 ] &&
                 [ $DOWNLOAD_RESULT -eq 0 ];
              then
                if [ "$PKG_FOREIGN_ARCH" != "" ];
                then
                  e_and_l "$FOREIGN_WARNING"
                  ask_yes_or_no_plus "pkg_foreign_other_$PAKET" "$PRE_SPACE ${bold_yellow}$PAKET${colors_off} trotzdem installieren" "" "n"
                  if [ $? -eq 1 ];
                  then
                    e_and_l "$PRE_SPACE $USER_CHOICE_YES"
                  else
                    e_and_l "$PRE_SPACE $USER_CHOICE_NO"
                    ((PAKETS_SKIP+=1))
                    ((PAKETS_NOAVAIL-=1))
                    if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA-=1)); fi
                    INSTALL_RESULT=1
                    DOWNLOAD_RESULT=1 # NICHT Weitermachen
                  fi
                fi
                if [ $DOWNLOAD_RESULT -eq 0 ];
                then
                  # ---------------------
                  # App-Ordner erstellen
                  # ---------------------
                  e_and_l -n "$PRE_SPACE Erstelle Ordner $PACKAGE_INST_DIR ... "
                  # 1. Sicherheitshalber Hauptordner anlegen und Zugriffsrechte setzen
                  if [ ! -d "$WEB_PKG_DIR" ];
                  then
                    mkdir -p "$WEB_PKG_DIR" &>"$LOG_TEMP"
                    if [ $? -eq 0 ];
                    then
                      chown -R "$USER_USERNAME:$USER_USERNAME" "$WEB_PKG_DIR" &>/dev/null
                      chmod -R 0755 "$WEB_PKG_DIR" &>/dev/null
                    fi
                  fi
                  # 2. Unterordner mit Paketnamen
                  if [ ! -d "$PACKAGE_INST_DIR" ];
                  then
                    mkdir -p "$PACKAGE_INST_DIR" &>"$LOG_TEMP"
                    if [ $? -eq 0 ];
                    then
                      chown -R "$USER_USERNAME:$USER_USERNAME" "$PACKAGE_INST_DIR" &>/dev/null
                      chmod -R 0755 "$PACKAGE_INST_DIR" &>/dev/null
                      e_and_l "$OK_TAG"
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                  else
                    e_and_l "$OK_TAG"
                  fi
                  add_full_log
                  # ------------------------
                  # Entpacken bzw. Kopieren
                  # ------------------------
                  # Datei-Attribute setzen
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
                  chmod -R 0664 "$LOCAL_DOWNLOAD_FILE" &>/dev/null
                  # Datei-Format ermitteln
                  AFTER_ACTION="Entpacke"
                  if [ $(echo -n "$LOCAL_DOWNLOAD_FILE" | grep -i -c ".ZIP") -ne 0 ] ||
                     [ $(echo -n "$LOCAL_DOWNLOAD_FILE" | grep -i -c ".7Z") -ne 0 ];
                  then
                    DOWNLOAD_FORMAT="ZIP"
                  else
                    if [ $(echo -n "$LOCAL_DOWNLOAD_FILE" | grep -i -c ".tar") -ne 0 ] ||
                       [ $(echo -n "$LOCAL_DOWNLOAD_FILE" | grep -i -c ".tgz") -ne 0 ];
                    then
                      DOWNLOAD_FORMAT="TAR"
                    else
                      DOWNLOAD_FORMAT="EXE"
                      AFTER_ACTION="Kopiere"
                    fi
                  fi

                  WPKG_CLEAN_NAME=$(echo "$PAKET" | tr A-Z a-z | sed 's/ /-/g' | xargs)

                  # Je nach Datei-Format entpacken oder kopieren
                  e_and_l -n "$PRE_SPACE $AFTER_ACTION ${light_yellow}$LOCAL_DOWNLOAD_FILE${colors_off}\n$PRE_SPACE nach ${light_yellow}$PACKAGE_INST_DIR${colors_off} ... "
                  if [ "$DOWNLOAD_FORMAT" == "ZIP" ];
                  then
                    7z x "$LOCAL_DOWNLOAD_FILE" -o"$PACKAGE_INST_DIR" -y &>"$LOG_TEMP"
                    INSTALL_RESULT=$?
                  else
                    if [ "$DOWNLOAD_FORMAT" == "TAR" ];
                    then
                      tar -axf "$LOCAL_DOWNLOAD_FILE" -C "$PACKAGE_INST_DIR" &>"$LOG_TEMP"
                      INSTALL_RESULT=$?
                      if [ $INSTALL_RESULT -ne 0 ];
                      then
                        tar -xzf "$LOCAL_DOWNLOAD_FILE" -C "$PACKAGE_INST_DIR" &>"$LOG_TEMP"
                        INSTALL_RESULT=$?
                      fi
                    else # DOWNLOAD_FORMAT "EXE"
                      cp -f "$LOCAL_DOWNLOAD_FILE" "$PACKAGE_INST_DIR" &>"$LOG_TEMP"
                      INSTALL_RESULT=$?
                      # Für ausführbare Programme, die nur als Datei kopiert und nicht installiert worden sind,
                      # und auch nicht aus einen Archiv entpackt wurden, zusätzlich einen Menü-Eintrag hinzufügen
                      if [ $INSTALL_RESULT -eq 0 ];
                      then
                        chmod -R 0755 "$PACKAGE_INST_DIR" &>/dev/null
                        APPIMG_FILE_NAME="$DOWNLOAD_FILE_NAME"
                        if [ -s "$PACKAGE_INST_DIR/$APPIMG_FILE_NAME" ];
                        then
                          # Icon runterladen und mit im Programmordner hinterlegen
                          # (ggf. redundant mit Suche einer Bilddatei weiter unten)
                          IMAGE_FILE_NAME="$WPKG_CLEAN_NAME.png"
                          ICON_TARGET_FILE="$PACKAGE_INST_DIR/$IMAGE_FILE_NAME"
                          LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$IMAGE_FILE_NAME"
                          wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$RESSOURCE_SERVER_DIR/png/$IMAGE_FILE_NAME" &>/dev/null
                          DOWNLOAD_RESULT=$?
                          if [ $DOWNLOAD_RESULT -eq 0 ] &&
                             [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
                             [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
                          then
                            cp -f "$LOCAL_DOWNLOAD_FILE" "$ICON_TARGET_FILE" &>/dev/null
                            chown -R "root:root" "$ICON_TARGET_FILE" &>/dev/null
                            chmod -R 0644 "$ICON_TARGET_FILE" &>/dev/null
                          fi
                          # .desktop-Datei anlegen
                          DESKTOP_FILE="$GLOBAL_STARTER_DIR/$WPKG_CLEAN_NAME.desktop"
                          echo -e "[Desktop Entry]" > "$DESKTOP_FILE" 2>/dev/null
                          if [ $? -eq 0 ];
                          then
                            echo -e "Type=Application" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Name=${WEB_PKG_NAME[$PAKET]}" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Comment=${WEB_PKG_NAME[$PAKET]} starten" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Exec=\"$PACKAGE_INST_DIR/$APPIMG_FILE_NAME\"" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Icon=$ICON_TARGET_FILE" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Categories=${WEB_PKG_CATY[$PAKET]};" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "Terminal=false" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "StartupNotify=true" >> "$DESKTOP_FILE" 2>/dev/null
                            echo -e "NoDisplay=false" >> "$DESKTOP_FILE" 2>/dev/null
                            chown -R "root:root" "$DESKTOP_FILE" &>/dev/null
                            chmod -R 0644 "$DESKTOP_FILE" &>/dev/null
                          fi
                        fi
                      fi
                    fi
                  fi

                  # -----------------------------------------------------------
                  # Wenn alles ok, Programm-Version notieren und
                  # den gesamten Programm-Ordner zu eigen machen
                  # -----------------------------------------------------------
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    # Programm-Version als Datei speichern -------------
                    PKG_VERS_FILE="$PACKAGE_INST_DIR/.$PAKET"
                    PKG_VERS_FILE+="_version"
                    echo -e "${WEB_PKG_VERS[$PAKET]}" > "$PKG_VERS_FILE" 2>/dev/null
                    # --------------------------------------------------
                    e_and_l "$OK_TAG"
                    e_and_l "$PRE_SPACE $HINWEIS_TAG: Eventuell müssen die Zugriffsrechte noch angepasst werden!"
                    chown -R "$USER_USERNAME:$USER_USERNAME" "$PACKAGE_INST_DIR" &>/dev/null
                  else
                    e_and_l "$ERROR_TAG"
                  fi
                  add_full_log

                  # -----------------------------------------------------------
                  # Wenn alles ok, zudem prüfen ob es ein Icon zu dem Paket
                  # gibt und ggf. eine passende Bilddatei herunterladen
                  # -----------------------------------------------------------
                  if [ $INSTALL_RESULT -eq 0 ];
                  then
                    # Kategorien mit Programmpaketen ohne Starter auslassen
                    if
                     [ "$CURRENT_CATEGORY" != "a" ] &&
                     [ "$CURRENT_CATEGORY" != "d" ] &&
                     [ "$CURRENT_CATEGORY" != "f" ] &&
                     [ "$CURRENT_CATEGORY" != "u" ] &&
                     [ "$CURRENT_CATEGORY" != "x" ] &&
                     [ "$CURRENT_CATEGORY" != "xx" ];
                    then
                      download_icon_file "$WPKG_CLEAN_NAME" 0
                    fi
                  fi

                fi # Fehler beim Download
              fi # Ende INSTALL_MODE 4 (WEB)

            fi

            if [ $INSTALL_RESULT -eq 0 ]; # 0 = Installation OK
            then
              ((PAKETS_AVAIL+=1))
              if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_AVAIL+=1)); fi
            else
              ((PAKETS_NOAVAIL+=1))
              if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA+=1)); fi
            fi

            # -----------------------------------------------------------------
            # NACH erfolgreicher Installation ggf. Konfiguration durchführen
            # -----------------------------------------------------------------
            if [ $INSTALL_RESULT -eq 0 ];
            then
              if [ "${POST_INST_CONF[$PAKET]}" != "" ];
              then
                e_and_l ""
                e_and_l -n "$PRE_SPACE Führe weitere ${light_yellow}Konfiguration${colors_off} durch ... "
                POST_ACTION="${POST_INST_CONF[$PAKET]}"
                if [ $(echo -n "$POST_ACTION" | grep -i -c -E "^\s*http") -gt 0 ];
                then
                  CONFIG_FILE_NAME="${POST_ACTION##*/}"
                  CONFIG_URL="$POST_ACTION"
                  LOCAL_CONFIG_FILE="$DOWNLOAD_DIR/$CONFIG_FILE_NAME"
                  wget -nv -O "$LOCAL_CONFIG_FILE" "$CONFIG_URL" &>"$LOG_TEMP"
                  if [ $? -eq 0 ] &&
                     [ -s "$LOCAL_CONFIG_FILE" ] &&
                     [ $(grep -i -c -E "Error\s*404" "$LOCAL_CONFIG_FILE") -eq 0 ];
                  then
                    # Heruntergeladenes Konfigurations-Skript ausführen mit dem Benutzernamen
                    # als erstem Parameter zur Verwendung im aufgerufenen Konfigurations-Skript
                    chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_CONFIG_FILE" &>/dev/null
                    chmod -R 0755 "$LOCAL_CONFIG_FILE" &>/dev/null
                    echo -e ""
                    ( "$LOCAL_CONFIG_FILE" ${USER_USERNAME} ${DOWNLOAD_DIR} ${RESSOURCE_SERVER_DIR} ${OS_V_CODENAME} ${INSTALL_MODE} >&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; ) | tee "$LOG_TEMP"
                    if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                    then
                      do_log "$OK_TAG"
                    else
                      do_log "$ERROR_TAG"
                    fi
                    # Konfigurations-Skript löschen
                    # remove_file "$LOCAL_CONFIG_FILE"
                  else
                    e_and_l ""
                    e_and_l "$PRE_SPACE $ERROR_TAG: Das Konfigurations-Skript konnte nicht geladen werden!"
                    # Durch wget eventuell angelegte unbrauchbare Datei löschen
                    remove_file "$LOCAL_CONFIG_FILE"
                  fi
                  echo -e ""
                  if [ ${OPTION_FLAG[skipmesg]} -eq 0 ] &&
                     [ ${OPTION_FLAG[quiet]} -eq 0 ];
                  then
                    echo -e -n "$PRE_SPACE Bitte ${bold_white}Enter${colors_off} drücken zum Weitermachen ... "
                    read dummy
                  fi
                else
                  echo -e ""
                  { eval "$POST_ACTION" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                  if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                  then
                    do_log "$OK_TAG"
                  else
                    do_log "$ERROR_TAG"
                  fi
                fi
                remove_file "$LAST_EXIT_CODE"
                do_log "Aktion: $POST_ACTION"
                add_full_log
                echo -e ""
              fi
            fi

            # -----------------------------------------------------------------
            # Nach NICHT erfolgreicher Installation das Repo wieder bereinigen
            # -----------------------------------------------------------------
            if [ $INSTALL_RESULT -ne 0 ];
            then
              clear_repo "$PAKET"
            fi

            # -----------------------------------------------------
            # Nach erfolgreicher Installation ggf. Starter anlegen
            # -----------------------------------------------------
            if [ $INSTALL_RESULT -eq 0 ]; then copy_starter_to_desktop "$PAKET" "" 0; fi

          else # wenn Ja-Nein-Abfrage negativ ausgefallen

            # do_log "$PRE_SPACE $PAKET wurde nicht installiert"
            if [ ${OPTION_FLAG[notoall]} -ne 1 ];
            then
              e_and_l "$PRE_SPACE ${light_cyan}$PAKET${colors_off} wurde ${light_red}nicht${colors_off} installiert"
            fi
            ((PAKETS_SKIP+=1))

          fi

        else # wenn OPTION_FLAG[status] = 1

          # -----------------------------------------------------------
          # Möglichkeiten zur Installation des Programmpakets anzeigen
          # -----------------------------------------------------------
          IMODE_MSG=" ${light_yellow}$PAKET${colors_off}"
          # -----------------------------------------------------
          # Wenn nur eine Version (Quelle) existiert, dann auch
          # die Versionsnummer eines verfügbaren Pakets ermitteln
          PKG_VERSION=""
          if [ ${#INST_MODE_LIST} -eq 3 ]; # "0,n" z.B. "0,2"
          then
            case $INSTALL_MODE in
              1) PKG_VERSION=$(get_pkg_apt_version  "$PAKET" 0)    ;;
              2) PKG_VERSION=$(get_pkg_snap_version "$PAKET" 0)    ;;
              3) PKG_VERSION=$(get_pkg_deb_version  "$PAKET")      ;;
              4) PKG_VERSION=$(get_pkg_web_version  "$PAKET")      ;;
              6) PKG_VERSION=$(get_pkg_flatpak_version "$PAKET" 0) ;;
            esac
            if [ "$PKG_VERSION" != "" ] &&
               [ "$PKG_VERSION" != "0" ];
            then
              IMODE_MSG+=" ${light_yellow}$PKG_VERSION${colors_off}"
            fi
          fi
          # -----------------------------------------------------
          IMODE_MSG+=" ist nicht installiert, aber"
          # -----------------------------------------
          # Wenn nur eine Version (Quelle) existiert,
          # dann diese Quelle auch benennen
          if [ ${#INST_MODE_LIST} -gt 3 ]; # "0,n" z.B. "0,2,4"
          then
            IMODE_MSG+=" ${light_magenta}mehrfach${colors_off}"
          else
            case "$INSTALL_MODE" in
              1) IMODE_MSG+="" ;;
              2) IMODE_MSG+=" als ${light_magenta}Snap${colors_off}" ;;
            3|4) if [ "$PKG_FOREIGN_ARCH" == "" ];
                then
                  # IMODE_MSG+=" als ${light_magenta}Download ("
                  # if [ $INSTALL_MODE -eq 3 ]; then IMODE_MSG+="DEB"; else IMODE_MSG+="WEB"; fi
                  # IMODE_MSG+=")${colors_off}"
                  IMODE_MSG+=" von ${light_magenta}extern${colors_off}"
                else
                  IMODE_MSG+=" für ${light_magenta}$PKG_FOREIGN_ARCH${colors_off}"
                fi
                ;;
              6) IMODE_MSG+=" als ${light_magenta}Flatpak${colors_off}" ;;
            esac
          fi
          # -----------------------------------------
          IMODE_MSG+=" verfügbar"
          e_and_l "$IMODE_MSG"

          ((PAKETS_AVAIL+=1))
          if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_AVAIL+=1)); fi

          # -----------------------------------------------------------
          # Hinweis auf bereits installierte Alternativen anzeigen
          # und dabei auch deren Starter mit anlegen
          # -----------------------------------------------------------
          show_similar_pkg $PAKET

        fi

      else # Wenn kein Installations-Kandidat gefunden wurde

        ((PAKETS_NOAVAIL+=1))
        if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_NOAVA+=1)); fi

      fi

    else # Wenn das Paket übersprungen werden soll

      e_and_l " ${light_cyan}$PAKET${colors_off} wird übersprungen$SKIP_REASON"

      ((PAKETS_SKIP+=1))

    fi

  else # Wenn das Paket schon installiert ist

    IMODE_MSG=" ${light_green}$PAKET${colors_off}"
    if [ "$PKG_VERSION" != "" ] &&
       [ "$PKG_VERSION" != "0" ];
    then
      IMODE_MSG+=" ${light_yellow}$PKG_VERSION${colors_off}"
    fi
    IMODE_MSG+=" ist"
    case "$INST_RES" in
        1) if [ $IS_SIMILAR_PKG -eq 0 ]; then IMODE_MSG+=" bereits"; fi ;;
        2) IMODE_MSG+=" als ${light_magenta}Snap${colors_off}" ;;
      3|4) IMODE_MSG+=" in ${light_magenta}$THE_PKG_INST_DIR${colors_off}" ;;
        5) IMODE_MSG+=" in ${light_magenta}$THE_PKG_INST_DIR${colors_off}" ;;
        6) IMODE_MSG+=" als ${light_magenta}Flatpak${colors_off}" ;;
    esac
    e_and_l "$IMODE_MSG installiert"

    ((PAKETS_EXIST+=1))

    if [ $IS_SIMILAR_PKG -eq 1 ]; then ((PAKETS_SIMILAR_EXIST+=1)); fi

    # ---------------------------------------------------------
    # "Auf Wunsch" auch für schon installierte Programme sowie
    #  deren installierte Alternativen einen Starter anlegen
    # ---------------------------------------------------------
    copy_starter_to_desktop "$PAKET" "" 0
    show_similar_pkg $PAKET

  fi

  ((PAKETS_COUNTER+=1))
}

#===============================================================================
# Die Snap-Paketverwaltung installieren
#===============================================================================
function install_snap {
  ask_yes_or_no_plus "" " Die ${light_cyan}Snap-Paketverwaltung${colors_off} jetzt installieren" "" "n"
  if [ $? -eq 1 ];
  then
    e_and_l -n " Installiere die ${light_yellow}Snap-Paketverwaltung${colors_off}, bitte warten ... "
    # -------------------------------------------------------
    # Installations- und Update-Blockaden für snapd aufheben
    # -------------------------------------------------------
    SNAP_UNHOLD_RESULT=0
    snap_unhold
    # ------------------
    # Snap installieren
    # ------------------
    apt install snapd -y &>"$LOG_TEMP"
    if [ $? -eq 0 ];
    then
      SNAP_INSTALLED=1
      SNAP_ACTIVE=$(LANG=C systemctl status snapd 2>/dev/null | grep -c -i -E "\:\s*\bactive\b")
      if [ $SNAP_ACTIVE -gt 0 ];
      then
        SNAP_SYSTEM_VERSION="$(snap --version 2>/dev/null | grep -i -E "^\bsnap(d)*\b" | head -n 1 | awk '{print $2}' | xargs 2>/dev/null)"
      else
        SNAP_SYSTEM_VERSION=""
      fi
      if [ "$SNAP_SYSTEM_VERSION" != "" ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
      fi
    else
      e_and_l "$ERROR_TAG"
    fi
    add_full_log
  fi
}

#===============================================================================
# Kurzbezeichnung eines Installations-Typs zurückgeben
#===============================================================================
function inst_status_to_name {
  PKG_TYPE_NAME=""
  case $1 in
    1) PKG_TYPE_NAME="STD"  ;;
    2) PKG_TYPE_NAME="SNAP" ;;
    3) PKG_TYPE_NAME="DEB"  ;;
    4) PKG_TYPE_NAME="WEB"  ;;
    5) PKG_TYPE_NAME="SHAR" ;;
    6) PKG_TYPE_NAME="FLAT" ;;
  esac
  echo -e -n "$PKG_TYPE_NAME"
}

#===============================================================================
# Einen Starter auf dem Desktop als vertrauenswürdig markieren, um ihn korrekt
# anzuzeigen und die Sicherheitsabfrage beim Anklicken zu vermeiden
# (Puh, dieses neue "Feature" von Ubuntu war ganz schön gut versteckt ... ;))
#===============================================================================
function make_starter_trusted {
  if [ -s "$1" ];
  then
    # < Ubuntu 21 (opt.: yes)
    sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" gio set "$1" "metadata::trusted" true &>/dev/null
    # Ab Ubuntu 21
    sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" gio set "$1" "metadata::caja-trusted-launcher" true &>/dev/null
    # Sonderfall XFCE
    if [ "$DESKTOP_ENVIRONMENT" == "XFCE" ];
    then
      sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" gio set -t string "$1" "metadata::xfce-exe-checksum" "$(sha256sum "$1" | awk '{print $1}')" &>/dev/null
    fi
  fi
}

#===============================================================================
# Namen von Starter-Dateien und darin enthaltene Programmaufrufe unterscheiden
# sich oft stark von deren Paketnamen. Damit die von Paketen erstellten Starter
# besser identifiziert werden können, werden deren zu suchende Namen mit dieser
# Funktion so gut wie möglich assoziiert
#===============================================================================
function probe_starter_name {
  THE_STARTER_NAME="$1"
  # --------------------------------------------------------
  # Überflüssige und störende Erweiterungen des Paketnamens
  # --------------------------------------------------------
  THE_STARTER_NAME="${THE_STARTER_NAME/-bin/}"
  THE_STARTER_NAME="${THE_STARTER_NAME/-client/}"
  THE_STARTER_NAME="${THE_STARTER_NAME/-common/}"
  THE_STARTER_NAME="$(echo -e -n ${THE_STARTER_NAME} | sed -E "s/^com\.//i")"
  THE_STARTER_NAME="$(echo -e -n ${THE_STARTER_NAME} | sed -E "s/^org\.[^(gnome|mate)]//i")"
  # THE_STARTER_NAME="$(echo -e -n ${THE_STARTER_NAME} | sed -E "s/\-gtk$\.//i")"
  # THE_STARTER_NAME="$(echo -e -n ${THE_STARTER_NAME} | sed -E "s/\-qt$\.//i")"
  if [ $(echo "$THE_STARTER_NAME" | grep -i -c "mate") -eq 0 ];
  then
    THE_STARTER_NAME="${THE_STARTER_NAME/-desktop/}"
  fi
  THE_STARTER_NAME="${THE_STARTER_NAME/-stable/}"
  # -------------------------------------------------------------
  # Bekannte Unterschiede zwischen Paket- und Starter-Dateinamen
  # -------------------------------------------------------------
  THE_STARTER_NAME="${THE_STARTER_NAME/gnome-weather/weather}"
  THE_STARTER_NAME="${THE_STARTER_NAME/obs-studio/com.obsproject.studio}"
  THE_STARTER_NAME="${THE_STARTER_NAME/python3-opensnitch-ui/opensnitch_ui}"
  THE_STARTER_NAME="${THE_STARTER_NAME/realvnc-vnc-server/realvnc-vncserver-service}"
  THE_STARTER_NAME="${THE_STARTER_NAME/realvnc-vnc-viewer/realvnc-vncviewer}"
  THE_STARTER_NAME="${THE_STARTER_NAME/steam-launcher/steam}"
  THE_STARTER_NAME="$(echo ${THE_STARTER_NAME} | sed -E "s/virtualbox.*/virtualbox/gi")"
  # THE_STARTER_NAME="${THE_STARTER_NAME/virtualbox-7.1/virtualbox}"
  # THE_STARTER_NAME="${THE_STARTER_NAME/virtualbox-7.2/virtualbox}"
  # -------------------------------------------------------------
  echo -e -n "$THE_STARTER_NAME"
}

#===============================================================================
# Prüfung einer sinnvollen Auswahl zur Verarbeitung
#===============================================================================
function ready_for_action {
  # ---------------------
  # Paket-Liste erzeugen
  # ---------------------
  TMP_LIST="$INST_ONLY_PKG"
  for k in ${KAT_KEY_LIST[@]};
  do
    if [ ${KATEGORIE_FLAG[$k]} -eq 1 ];
    then
      TMP_LIST+=" ${KATEGORIE_PKGS[$k]}"
    fi
  done
  # --------------------------------------------
  # Automatisch zu ergänzende Pakete hinzufügen
  # --------------------------------------------
  for p in ${TMP_LIST};
  do
    ADDITIONAL_PACKS="${AUTO_ADD_PKGS[$p]}"
    if [ "$ADDITIONAL_PACKS" != "" ];
    then
      if [ "${AUTO_ADD_PPOS[$p]}" != "true" ];
      then
        # Zusätzliche Pakete NACH Basispaket einfügen
        TMP_LIST=$(echo " $TMP_LIST " | sed -E "s/ $p / $p $ADDITIONAL_PACKS /")
      else
        # Zusätzliche Pakete VOR Basispaket einfügen
        TMP_LIST=$(echo " $TMP_LIST " | sed -E "s/ $p / $ADDITIONAL_PACKS $p /")
      fi
    fi
  done
  # -----------------------------
  # Liste in ein Array umwandeln
  # -----------------------------
  ALL_PKG_LIST=(${TMP_LIST})
  # ------------------------------------
  # Prüfung
  # ------------------------------------
  TOTAL_PACKS=${#ALL_PKG_LIST[@]}
  if [[ $TOTAL_PACKS             -eq 0 &&
        $USE_ILIST_FILE          -eq 0 &&
        ${OPTION_FLAG[cleansys]} -eq 0 &&
        ${OPTION_FLAG[desktop]}  -eq 0 &&
        ${OPTION_FLAG[dload]}    -eq 0 &&
        ${OPTION_FLAG[dsave]}    -eq 0 &&
        ${OPTION_FLAG[extras]}   -eq 0 &&
        ${OPTION_FLAG[exupdate]} -eq 0 &&
        ${OPTION_FLAG[infoonly]} -eq 0 &&
        ${OPTION_FLAG[kuplock]}  -eq 0 &&
        ${OPTION_FLAG[kunlock]}  -eq 0 &&
        ${OPTION_FLAG[optimize]} -eq 0 &&
        ${OPTION_FLAG[personal]} -eq 0 &&
        ${OPTION_FLAG[remove]}   -eq 0 &&
        ${OPTION_FLAG[repair]}   -eq 0 &&
        ${OPTION_FLAG[reset]}    -eq 0 &&
        ${OPTION_FLAG[revive]}   -eq 0 &&
        ${OPTION_FLAG[setutc]}   -eq 0 &&
        ${OPTION_FLAG[snapcont]} -eq 0 &&
        ${OPTION_FLAG[snapkill]} -eq 0 &&
        ${OPTION_FLAG[snapstop]} -eq 0 &&
        ${OPTION_FLAG[sysbench]} -eq 0 ]];
  then
    return 1
  else
    return 0
  fi
}

#===============================================================================
# Ermittlung der benutzerspezifischen Konfigurations-Daten eines
# Programmpakets zur nachfolgenden Löschung
#===============================================================================
function remove_cfg {
  echo -e ""
  e_and_l " ${light_blue}Schritt 2/$REMOVE_ACTION:${colors_off} Löschen der Konfiguration"
  echo -e -n " Starte Suche, bitte warten ... "
  NOTHING_FOUND_TEXT="Es wurde keine individuelle Konfiguration gefunden"
  # ------------------------------------------------------------------------
  # Betroffene Ordner und Dateien ermitteln und daraus eine Liste erstellen
  # ------------------------------------------------------------------------
  REMOVE_CONFIG_LIST="$DOWNLOAD_DIR/remove_config.tmp"
  echo -e -n "" > "$REMOVE_CONFIG_LIST"
  # --------------------
  # Alles außer Flatpak
  # --------------------
  if [ $INST_STATUS -ne 6 ];
  then
    # ---------
    # Nur SNAP
    # ---------
    if [ $INST_STATUS -eq 2 ] ||
       [ $2 -eq 1 ];
    then
      find ${USER_HOME_DIR} -iname "$1" -type d,f 2>/dev/null | grep -i -E "snap\/" >> "$REMOVE_CONFIG_LIST"
      find ${USER_HOME_DIR} -iname ".$1" -type d,f 2>/dev/null | grep -i -E "snap\/" >> "$REMOVE_CONFIG_LIST"
    fi
    # -----------------
    # Alles außer SNAP
    # -----------------
    if [ $INST_STATUS -ne 2 ] ||
       [ $2 -eq 1 ];
    then
      find ${USER_HOME_DIR} -iname "$1" -type d,f 2>/dev/null | grep -v -i -E "snap\/" >> "$REMOVE_CONFIG_LIST"
      find ${USER_HOME_DIR} -iname ".$1" -type d,f 2>/dev/null | grep -v -i -E "snap\/" >> "$REMOVE_CONFIG_LIST"
    fi
  fi
  # --------
  # Flatpak
  # --------
  if [ $INST_STATUS -eq 6 ];
  then
    THE_FLATPAK_REF_STRING=$(get_pkg_flatpak_reference $1 1)
    find ${USER_HOME_DIR} -iname "$THE_FLATPAK_REF_STRING" -type d,f 1>>"$REMOVE_CONFIG_LIST" 2>/dev/null
    find ${USER_HOME_DIR} -iname ".$THE_FLATPAK_REF_STRING" -type d,f 1>>"$REMOVE_CONFIG_LIST" 2>/dev/null
  fi
  # ----------------
  echo -e "$FERTIG_TAG" # Achtung: OHNE -n
  do_remove_items $REMOVE_CONFIG_LIST 0
}

#===============================================================================
# Ermittlung aller Daten zu einem Programmpaket
#===============================================================================
function remove_dat {
  echo -e ""
  e_and_l " ${light_blue}Schritt 3/$REMOVE_ACTION:${colors_off} Löschen weiterer zugehöriger Daten"
  echo -e -n " Starte Suche, bitte warten ... "
  NOTHING_FOUND_TEXT="Es wurden keine weiteren Daten gefunden"
  # Betroffene Ordner und Dateien ermitteln und daraus eine Liste erstellen ---
  REMOVE_DAT_LIST="$DOWNLOAD_DIR/remove_dat.tmp"
  echo -e -n "" > "$REMOVE_DAT_LIST"
# -----------------------------------------------------------------------------
# DIE INTENSIVE SUCHE WIRD DERZEIT MICHT DURCHGEFÜHRT / ANGEBOTEN
# -----------------------------------------------------------------------------
#   e_and_l " Wie soll die Suche nach weiteren zugehörigen Daten erfolgen?"
#   e_and_l " [${bold_yellow}e${colors_off}] Erweiterte Vorkommen in den Namen von Ordnern und Dateien"
#   e_and_l " [${bold_yellow}i${colors_off}] Zusätzlich intensive Suche nach Vorkommen ${bold_white}in${colors_off} allen Dateien (langsam!)"
#   e_and_l -n " Bitte eine Option auswählen: "
#   SEARCH_METHOD=""
#   while [ "$SEARCH_METHOD" != "e" ] &&
#         [ "$SEARCH_METHOD" != "E" ] &&
#         [ "$SEARCH_METHOD" != "i" ] &&
#         [ "$SEARCH_METHOD" != "I" ];
#   do
#     read -N 1 -r -s SEARCH_METHOD
#   done
#   e_and_l "$SEARCH_METHOD"
# -----------------------------------------------------------------------------
  if [ $INST_STATUS -eq 6 ];
  then
    THE_SEARCH_STRING=$(get_pkg_flatpak_reference $1 1)
  else
    THE_SEARCH_STRING="$1"
  fi
# -----------------------------------------------------------------------------
  find / -iname "*$THE_SEARCH_STRING*" -type d,f 1>>"$REMOVE_DAT_LIST" 2>/dev/null
# -----------------------------------------------------------------------------
#   if [ "$SEARCH_METHOD" == "i" ] ||
#      [ "$SEARCH_METHOD" == "I" ];
#   then
#     grep -i -l "$REMOVE_PKG_NAME" ... ... ... 1>>"$REMOVE_DAT_LIST" 2>/dev/null
#   fi
# -----------------------------------------------------------------------------
  # Doppelte Einträge entfernen
  if [ -s "$REMOVE_DAT_LIST" ];
  then
    THE_TEMP_FILE="$DOWNLOAD_DIR/tmp_rm_item_list.tmp"
    awk '!seen[$0]++' "$REMOVE_DAT_LIST" > "$THE_TEMP_FILE" 2>/dev/null
    remove_file "$REMOVE_DAT_LIST"
    mv -f "$THE_TEMP_FILE" "$REMOVE_DAT_LIST" &>/dev/null
  fi
  echo -e "$FERTIG_TAG" # Achtung: OHNE -n
  do_remove_items $REMOVE_DAT_LIST 1
}

#===============================================================================
# Mehrfach hintereinander vorkommende Leerzeilen aus einer Datei entfernen
#===============================================================================
function remove_double_empty_lines {
  THE_TMP_FILE="$1.rmv_dbl_tmp"
  cat -s "$1" > "$THE_TMP_FILE" 2>/dev/null
  if [ $? -eq 0 ];
  then
    mv -f "$THE_TMP_FILE" "$1" &>/dev/null
  fi
}

#===============================================================================
# Löschen einer bestimmten einzelnen Datei
#===============================================================================
function remove_file {
  if [ "$1" != "" ] &&
     [ -f "$1" ];
  then
    rm -f "$1" &>/dev/null
    RM_RESULT=$?
  else
    RM_RESULT=1
  fi
  return $RM_RESULT
}

#===============================================================================
# Löschen der Starter eines Programmpakets
#===============================================================================
function remove_starter {
  if [ $INST_STATUS -eq 6 ];
  then
    THE_PKG_REAL_NAME=$(get_pkg_flatpak_reference $1 1)
  else
    THE_PKG_REAL_NAME="$1"
  fi
  if [ "$THE_PKG_REAL_NAME" != "" ];
  then
    do_log " Lösche Starter zu $1"
    # -----------------------------------------------------------
    # Starter mit dem gleichen Dateinamen wie das Paketes selbst
    # -----------------------------------------------------------
    remove_file "$GLOBAL_STARTER_DIR/$THE_PKG_REAL_NAME.desktop"
    find "$USER_HOME_DIR" -type f -iname "$THE_PKG_REAL_NAME.desktop" -delete &>"$LOG_TEMP"
    # -----------------------------------------------
    # Starter mit ähnlichen Dateinamen wie das Paket
    # (sicherheitshalber nur in persönlichen Ordnern)
    # -----------------------------------------------
    PROBE_STARTER_NAME=$(probe_starter_name "$THE_PKG_REAL_NAME")
    find "$USER_HOME_DIR" -type f -iregex ".*$PROBE_STARTER_NAME.*\.desktop$" -delete &>"$LOG_TEMP"
    # ---------------------------------------------------------------------
    # Starter(-Liste) mit vordefinierten Dateinamen (andere als Paketname)
    # ---------------------------------------------------------------------
    tmp_list=${PKG_STARTER_LIST[$THE_PKG_REAL_NAME]};
    if [ "$tmp_list" != "" ];
    then
      for starter_file in ${tmp_list[@]};
      do
        remove_file "$GLOBAL_STARTER_DIR/$starter_file.desktop"
        find "$USER_HOME_DIR" -type f -iname "$starter_file.desktop" -delete &>"$LOG_TEMP"
      done
    fi
    add_full_log
  fi
}

#===============================================================================
# Löschen eines Programmpakets
# -----------------------------
# Parameter:
# $1: Paketname
# $2: Löschart (0 = einfaches entfernen, 1 = entfernen mit purge)
#===============================================================================
function remove_pkg {
  THE_PKG_REAL_NAME="$1"
  THE_REMOVE_MODE=$2
  # ----------------------------------------------------------------------------
  # Prüfen, ob Voraussetzungen zum Entfernen des Pakets gegeben sind
  # ----------------------------------------------------------------------------
  PRE_CONF_RESULT=0
  if [ "${PRE_REMOVE_CONF[$THE_PKG_REAL_NAME]}" != "" ];
  then
    e_and_l ""
    e_and_l " Führe vorbereitende ${light_yellow}Konfiguration${colors_off} für ${light_yellow}$THE_PKG_REAL_NAME${colors_off} durch ... "
    PRE_ACTION="${PRE_REMOVE_CONF[$THE_PKG_REAL_NAME]}"
    if [ $(echo -n "$PRE_ACTION" | grep -i -c -E "^\s*http") -gt 0 ];
    then
      CONFIG_FILE_NAME="${PRE_ACTION##*/}"
      CONFIG_URL="$PRE_ACTION"
      LOCAL_CONFIG_FILE="$DOWNLOAD_DIR/$CONFIG_FILE_NAME"
      wget -nv -O "$LOCAL_CONFIG_FILE" "$CONFIG_URL" &>"$LOG_TEMP"
      if [ $? -eq 0 ] &&
         [ -s "$LOCAL_CONFIG_FILE" ] &&
         [ $(grep -i -c -E "Error\s*404" "$LOCAL_CONFIG_FILE") -eq 0 ];
      then
        # --------------------------------------------------
        # Heruntergeladenes Konfigurations-Skript ausführen
        # --------------------------------------------------
        chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_CONFIG_FILE" &>/dev/null
        chmod -R 0755 "$LOCAL_CONFIG_FILE" &>/dev/null
        e_and_l ""
        ( "$LOCAL_CONFIG_FILE" ${USER_USERNAME} ${DOWNLOAD_DIR} ${RESSOURCE_SERVER_DIR} ${OS_V_CODENAME} ${INST_STATUS} 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; ) | tee "$LOG_TEMP"
        if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
        then
          do_log "$OK_TAG"
        else
          do_log "$ERROR_TAG"
          PRE_CONF_RESULT=1
        fi
        remove_file "$LOCAL_CONFIG_FILE"
      else
        e_and_l "$PRE_SPACE $ERROR_TAG: Das Konfigurations-Skript konnte nicht geladen werden!"
        # Durch wget eventuell angelegte unbrauchbare Datei löschen
        remove_file "$LOCAL_CONFIG_FILE"
        PRE_CONF_RESULT=1
      fi
      if [ ${OPTION_FLAG[skipmesg]} -eq 0 ] &&
         [ ${OPTION_FLAG[quiet]} -eq 0 ];
      then
        echo -e -n "$PRE_SPACE Bitte ${bold_white}Enter${colors_off} drücken zum Weitermachen ... "
        read dummy
      fi
    else
      e_and_l ""
      { eval "$PRE_ACTION" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
      then
        do_log "$OK_TAG"
      else
        do_log "$ERROR_TAG"
        PRE_CONF_RESULT=1
      fi
    fi
    remove_file "$LAST_EXIT_CODE"
    do_log "Aktion: $PRE_ACTION"
    add_full_log
  fi
  # ----------------------------------------------------------------------------
  # Paket nur entfernen, wenn ggf. Voraussetzungen dazu erfüllt sind
  # ----------------------------------------------------------------------------
  REMOVE_RESULT=0
  if [ $PRE_CONF_RESULT -eq 0 ];
  then
    e_and_l ""
    e_and_l " Löschen von ${bold_yellow}$THE_PKG_REAL_NAME${colors_off} ... "
    # ----------------------------
    # Mit apt installierte Pakete
    # ----------------------------
    REMOVE_APT_RESULT=0
    if [ $INST_STATUS -eq 1 ];
    then
      if [ $THE_REMOVE_MODE -eq 0 ];
      then
        { apt remove "$THE_PKG_REAL_NAME" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      else
        { apt purge "$THE_PKG_REAL_NAME" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      fi
      REMOVE_APT_RESULT=$(cat "$LAST_EXIT_CODE")
    fi
    # -----------------------------
    # Als Snap installierte Pakete
    # -----------------------------
    REMOVE_SNAP_RESULT=0
    if [ $INST_STATUS -eq 2 ];
    then
      e_and_l ""
      if [ $THE_REMOVE_MODE -eq 0 ];
      then
        { snap remove "$THE_PKG_REAL_NAME" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      else
        { snap remove --purge "$THE_PKG_REAL_NAME" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      fi
      REMOVE_SNAP_RESULT=$(cat "$LAST_EXIT_CODE")
    fi
    # -----------------------------------------------------
    # In /opt oder dem Benutzer-Ordner gespeicherte Pakete
    # -----------------------------------------------------
    REMOVE_OPT_RESULT=0
    if [ $INST_STATUS -eq 3 ];
    then
      TMP_PKG_INST_NAME="${DEB_PKG_NAME[$THE_PKG_REAL_NAME]}"
      if [ "$TMP_PKG_INST_NAME" == "" ];
      then
        TMP_PKG_INST_NAME="${WEB_PKG_NAME[$THE_PKG_REAL_NAME]}"
        if [ "$TMP_PKG_INST_NAME" == "" ];
        then
          TMP_PKG_INST_NAME="$THE_PKG_REAL_NAME"
        fi
      fi
      TMP_PKG_INST_DIR="/opt/$TMP_PKG_INST_NAME"
      if [ -d "$TMP_PKG_INST_DIR" ];
      then
        rm -d -f -r "$TMP_PKG_INST_DIR" &>"$LOG_TEMP"
        REMOVE_OPT_RESULT=$?
      fi
    fi
    # ----------------------------------------------------
    # Dateien und Paket-Ordner in /home/USER/apps löschen
    # ----------------------------------------------------
    REMOVE_HOME_RESULT=0
    if [ $INST_STATUS -eq 4 ];
    then
      TMP_PKG_INST_NAME="${WEB_PKG_NAME[$THE_PKG_REAL_NAME]}"
      if [ "$TMP_PKG_INST_NAME" == "" ];
      then
        TMP_PKG_INST_NAME="$THE_PKG_REAL_NAME"
      fi
      TMP_PKG_INST_DIR="$WEB_PKG_DIR/$TMP_PKG_INST_NAME"
      if [ -d "$TMP_PKG_INST_DIR" ];
      then
        rm -d -f -r "$TMP_PKG_INST_DIR" &>"$LOG_TEMP"
        REMOVE_HOME_RESULT=$?
      fi
    fi
    # -----------------------------------------------
    # Dateien und Paket-Ordner in /usr/share löschen
    # -----------------------------------------------
    REMOVE_SHARE_RESULT=0
    if [ $INST_STATUS -eq 5 ] &&
       [ "$THE_PKG_REAL_NAME" != "" ];
    then
      TMP_PKG_INST_DIR="/usr/share/$THE_PKG_REAL_NAME"
      if [ -d "$TMP_PKG_INST_DIR" ];
      then
        rm -d -f -r "$TMP_PKG_INST_DIR" &>"$LOG_TEMP"
        REMOVE_SHARE_RESULT=$?
      fi
    fi
    # ----------------------------------------------------------------------------
    # Als Flatpak installierte Pakete
    # ----------------------------------------------------------------------------
    REMOVE_FLAT_RESULT=0
    if [ $INST_STATUS -eq 6 ];
    then
      e_and_l ""
      { flatpak uninstall $(get_pkg_flatpak_reference ${THE_PKG_REAL_NAME} 1) --noninteractive -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
      REMOVE_FLAT_RESULT=$(cat "$LAST_EXIT_CODE")
    fi
    # ----------------------------------------------------------------------------
    if [ $REMOVE_APT_RESULT -eq 0 ] &&
       [ $REMOVE_SNAP_RESULT -eq 0 ] &&
       [ $REMOVE_OPT_RESULT -eq 0 ] &&
       [ $REMOVE_HOME_RESULT -eq 0 ] &&
       [ $REMOVE_SHARE_RESULT -eq 0 ] &&
       [ $REMOVE_FLAT_RESULT -eq 0 ];
    then
      e_and_l " $OK_TAG"
    else
      e_and_l " $ERROR_TAG"
      REMOVE_RESULT=1
    fi
  fi
  add_full_log
  remove_file "$LAST_EXIT_CODE"
}

#===============================================================================
# Löschen aller (verbliebenen) Schnappschüsse von Snap-Paketen
# -------------------------------------------------------------
# Parameter:
# $1: Paketname - wenn angegeben werden nur Snapschüsse dieses Pakets gelöscht
# $2: Snapshots direkt löschen (1) oder vorher Aktions-Auswahl anzeigen (0)
#===============================================================================
function remove_snapshots {
  SNAP_REMOVE_SINGLE="$1"
  SNAP_FORCE_REMOVE=$2
  if [ $SNAP_ACTIVE -gt 0 ];
  then
    # -------------------------------------------------------------------------
    # Wenn nur die Schnappschüsse eines bestimmten Snap-Pakets entfernt werden
    # sollen, dann dazu neue dedizierte Liste der Schnappschüsse erstellen
    # -------------------------------------------------------------------------
    if [ "$SNAP_REMOVE_SINGLE" != "" ];
    then
      remove_file "$SNAP_SNAPSHOT_LIST"
      if [ $(snap saved 2>/dev/null | grep -i -c -E "\b$1\b") -gt 0 ];
      then
        LANG=en_US.UTF-8 snap saved 2>/dev/null | grep -i -E "\b$1\b" | awk '{print $1, $2, "(A"$3")", "(V"$4")", "(R"$5")", "(S"$6")"}' > "$SNAP_SNAPSHOT_LIST"
      fi
    fi
    # --------------------------------------------------------------------
    # Nur weitermachen, wenn es Schnappschüsse (des Snap-Pakets) gibt ...
    # --------------------------------------------------------------------
    if [ -s "$SNAP_SNAPSHOT_LIST" ];
    then
      declare -A SNAP_SET_LIST
      declare -A SNAP_NAME_LIST
      declare -A SNAP_AGE_LIST
      declare -A SNAP_VERSION_LIST
      declare -A SNAP_REVISION_LIST
      declare -A SNAP_SIZE_LIST
      i=0
      while read snapset snapname snapage snapversion snaprevision snapsize;
      do
        if [ "$snapset" != "" ] &&
           [ "$snapname" != "" ];
        then
          SNAP_SET_LIST[$i]="$snapset"
          SNAP_NAME_LIST[$i]="$snapname"
          SNAP_AGE_LIST[$i]="$snapage"
          SNAP_VERSION_LIST[$i]="$snapversion"
          SNAP_REVISION_LIST[$i]="$snaprevision"
          SNAP_SIZE_LIST[$i]="$snapsize"
          ((i+=1))
        fi
      done < "$SNAP_SNAPSHOT_LIST"
      ANZAHL_SNAPSHOTS=${#SNAP_SET_LIST[@]}
      if [ $ANZAHL_SNAPSHOTS -gt 0 ];
      then
        if [ $SNAP_FORCE_REMOVE -ne 1 ];
        then
          e_and_l "$HALF_MINUS_LINE"
          e_and_l " Es wurden ${bold_yellow}$ANZAHL_SNAPSHOTS${colors_off} ${light_cyan}veraltete Snap-Schnappschüsse${colors_off} gefunden."
          e_and_l " Was soll ich tun?"
          e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen"
          e_and_l " [${bold_yellow}1${colors_off}] Jeden Schnappschuss einzeln jeweils mit Abfrage löschen"
          e_and_l " [${bold_yellow}2${colors_off}] Alle Schnappschüsse ohne einzelne Abfragen löschen"
          user_choice_012
          REMOVE_MODE=$?
        else
          REMOVE_MODE=2
        fi
        if [ $REMOVE_MODE -gt 0 ];
        then
          if [ $SNAP_FORCE_REMOVE -ne 1 ];
          then
            # ----------------------------------------------------
            # Sicherheitsabfrage wenn alle gelöscht werden sollen
            # ----------------------------------------------------
            if [ $REMOVE_MODE -eq 2 ];
            then
              e_and_l " Es wurden folgende ${light_cyan}Schnappschüsse${colors_off} gefunden:"
              e_and_l " ${bold_white}Name                      Version                  Revision   Set    Größe${colors_off}"
              ss=0
              while [ $ss -lt $ANZAHL_SNAPSHOTS ];
              do
                # -----
                # Name
                # -----
                SNAP_PKG_NAME="${SNAP_NAME_LIST[$ss]}"
                e_and_l -n " ${light_yellow}${SNAP_PKG_NAME:0:25}${colors_off}"
                ((ANZ_SPACES=25-${#SNAP_PKG_NAME}))
                insert_spaces $ANZ_SPACES
                # --------
                # Version
                # --------
                SNAP_PKG_VERSION="${SNAP_VERSION_LIST[$ss]}"
                SNAP_PKG_VERSION="${SNAP_PKG_VERSION/(V/}"
                SNAP_PKG_VERSION="${SNAP_PKG_VERSION/)/}"
                e_and_l -n " ${light_yellow}${SNAP_PKG_VERSION:0:25}${colors_off}"
                ((ANZ_SPACES=25-${#SNAP_PKG_VERSION}))
                insert_spaces $ANZ_SPACES
                # ---------
                # Revision
                # ---------
                SNAP_PKG_REVISION="${SNAP_REVISION_LIST[$ss]}"
                SNAP_PKG_REVISION="${SNAP_PKG_REVISION/(R/}"
                SNAP_PKG_REVISION="${SNAP_PKG_REVISION/)/}"
                e_and_l -n "${SNAP_PKG_REVISION:0:11}"
                ((ANZ_SPACES=11-${#SNAP_PKG_REVISION}))
                insert_spaces $ANZ_SPACES
                # ---------------------------------------------------------------
                # Snap-Set (fortlaufende Nummer der Gruppe von gelöschten Snaps)
                # ---------------------------------------------------------------
                SNAP_PKG_SET="${SNAP_SET_LIST[$ss]}"
                e_and_l -n "${SNAP_PKG_SET:0:7}"
                ((ANZ_SPACES=6-${#snapset}))
                insert_spaces $ANZ_SPACES
                # ------
                # Größe
                # ------
                SNAP_PKG_SIZE="${SNAP_SIZE_LIST[$ss]}"
                SNAP_PKG_SIZE="${SNAP_PKG_SIZE/(S/}"
                SNAP_PKG_SIZE="${SNAP_PKG_SIZE/)/}"
                e_and_l "$SNAP_PKG_SIZE"
                ((ss+=1))
              done
              e_and_l "$HALF_MINUS_LINE"
              e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt gelöscht wird?"
              ask_yes_or_no_plus "remove_snapshots" " Jetzt wirklich ${bold_red}alle${colors_off} Schnappschüsse löschen" "" "n"
              if [ $? -eq 0 ];
              then
                e_and_l " $USER_CHOICE_NO"
                REMOVE_MODE=0
              else
                e_and_l " $USER_CHOICE_YES"
              fi
            fi
            # ----------------------------------------------------
          fi
          if [ $REMOVE_MODE -gt 0 ];
          then
            ss=0
            while [ $ss -lt $ANZAHL_SNAPSHOTS ];
            do
              if [ $SNAP_FORCE_REMOVE -ne 1 ]; then e_and_l "$HALF_MINUS_LINE"; fi
              THE_SNAP_TEXT="${SNAP_NAME_LIST[$ss]} ${SNAP_VERSION_LIST[$ss]/(V/}"
              THE_SNAP_TEXT="${THE_SNAP_TEXT/)/} (Set ${SNAP_SET_LIST[$ss]})"
              DO_REMOVE_THIS=1
              if [ $REMOVE_MODE -eq 1 ];
              then
                e_and_l " Schnappschuss ${light_cyan}$THE_SNAP_TEXT${colors_off}"
                ask_yes_or_no_plus "" " Löschen" "" "n"
                DO_REMOVE_THIS=$?
              fi
              if [ $DO_REMOVE_THIS -eq 1 ];
              then
                e_and_l -n " Lösche Schnappschuss ${light_yellow}$THE_SNAP_TEXT${colors_off} ... "
                snap forget "${SNAP_SET_LIST[$ss]}" "${SNAP_NAME_LIST[$ss]}" &>/dev/null
                if [ $? -eq 0 ];
                then
                  e_and_l "$OK_TAG"
                else
                  e_and_l "$ERROR_TAG"
                fi
              fi
              ((ss+=1))
            done
            if [ $SNAP_FORCE_REMOVE -ne 1 ]; then e_and_l "$HALF_MINUS_LINE"; fi
          fi
        fi
        if [ $SNAP_FORCE_REMOVE -ne 1 ];
        then
          e_and_l " $HINWEIS_TAG: Zum Löschen veralteter ${bold_white}Snap-Revisionen${colors_off} das Tool ${light_magenta}snapco${colors_off} verwenden ;)"
        fi
      fi # Keine Schnappschüsse in Liste enthalten
    fi # Keine Liste mit Schnappschüssen
    remove_file "$SNAP_SNAPSHOT_LIST"
  fi # Kein Snap
}

#===============================================================================
# Aktualisierung des Repository
#===============================================================================
function repo_update {
  e_and_l -n "$1"
  apt update &>"$LOG_TEMP"
  if [ $? -eq 0 ];
  then
    e_and_l "$OK_TAG"
  else
    e_and_l "$ERROR_TAG"
    add_full_log
  fi
}

#===============================================================================
# Zurücksetzen der Auswahl der Paket-Kategorien
#===============================================================================
function reset_categories_selection {
  for k in ${KAT_KEY_LIST[@]};
  do
    KATEGORIE_FLAG[$k]=0
  done
}

#===============================================================================
# Zurücksetzen und zur Initialisierung aller Optionen
# Parameter $1: Menü-Index (oder 0 für alle Einträge)
#===============================================================================
function reset_options_selection {
  for o in ${OPTION_LIST[@]};
  do
    if [ $1 -eq 0 ] ||
       [ $1 -eq ${OPTION_MENU[$o]} ];
    then
      OPTION_FLAG[$o]=0;
    fi
  done
}

# ==============================================================================
# Benutzerspezifische Einstellungen sichern und für aktuellen Durchlauf löschen
# ==============================================================================
function reset_user_config {
  # -----------------------
  # Automatische Antworten
  # -----------------------
  create_backup_file "$AUTO_ANSWER_FILE"
  remove_file "$AUTO_ANSWER_FILE"
  AUTO_ANSWERS=()
  # -------------------------
  # Konfiguration (Optionen)
  # -------------------------
  create_backup_file "$USER_SCRIPT_CONFIG"
  remove_file "$USER_SCRIPT_CONFIG"
  # -------------
  # Paket-Listen
  # -------------
  create_backup_file "$USER_PAKET_LIST"
  remove_file "$USER_PAKET_LIST"
}

#===============================================================================
# Wiederherstellung einer Datei durch ihre Sicherheits-Kopie
#===============================================================================
function restore_backup_file {
  RESTORE_FILE_PATH="$1"
  if [ -f "$RESTORE_FILE_PATH.bak" ];
  then
    mv -f "$RESTORE_FILE_PATH.bak" "$RESTORE_FILE_PATH" &>/dev/null
  else
    if [ -f "$RESTORE_FILE_PATH.save" ];
    then
      mv -f "$RESTORE_FILE_PATH.save" "$RESTORE_FILE_PATH" &>/dev/null
    fi
  fi
}

# ==============================================================================
# Warnung ausgeben, wenn erforderliches Basispaket oder zugehöriges vorher zu
# installierendes Paket nicht oder aus einer anderen Quelle installiert ist,
# und bei Bedarf Frage zum Fortführen des Installations-Vorgangs stellen
# ==============================================================================
function show_base_pkg {
  INFO_PAKET=$1
  ASK_TO_CONTINUE=$2

  SHOW_SKIP_MESSAGE=0

  # ----------------------------------------------------------------
  # Wenn ein zugehöriges vorher zu installierendes Paket nicht oder
  # aus einer anderen Quelle installiert ist, dann Warnung ausgeben
  # ----------------------------------------------------------------
  if [ "$PRE_INST_PKG_NAME" != "" ] &&
     [ $PRE_INST_PKG_INST_STATUS != $INSTALL_MODE ];
  then
    if [ $PRE_INST_PKG_INST_STATUS -eq 0 ];
    then
      SHOW_I_STATUS="nicht"
    else
      OTHER_SRC="$(inst_status_to_name $PRE_INST_PKG_INST_STATUS)"
      SHOW_I_STATUS="aus anderer Quelle (${light_magenta}$OTHER_SRC${colors_off})"
    fi
    # if [ $ASK_TO_CONTINUE -eq 0 ] ||
    #    [ ${OPTION_FLAG[esamesrc]} -eq 0 ];
    # then
      e_and_l " $ACHTUNG_TAG:"
      e_and_l -n "$PRE_SPACE"
    # fi
    e_and_l " Das zugehörige Paket ${light_cyan}$PRE_INST_PKG_NAME${colors_off} ist $SHOW_I_STATUS installiert."
    e_and_l -n "$PRE_SPACE"
    if [ $ASK_TO_CONTINUE -eq 1 ];
    then
      if [ $PRE_INST_PKG_INST_STATUS -eq 0 ] ||
         [ ${OPTION_FLAG[esamesrc]} -eq 0 ];
      then
        ask_yes_no_info "$INFO_PAKET" 1
        CONTINUE_INSTALL=$?
      else
        CONTINUE_INSTALL=0
        SHOW_SKIP_MESSAGE=1
      fi
      ASKED_ALREADY_TO_CONTINUE=1
    fi
  fi

  # --------------------------------------------------------
  # Wenn ein erforderliches Basispaket nicht oder aus einer
  # anderen Quelle installiert ist, dann Warnung ausgeben
  # (Ersteres sollte hier nicht mehr vorkommen, weil schon
  #  zuvor übersprungen, aber das kann sich ja ändern ;)
  # --------------------------------------------------------
  if [ "$BASE_PKG_NAME" != "" ] &&
     [ $BASE_PKG_INST_STATUS != $INSTALL_MODE ];
  then
    if [ $BASE_PKG_INST_STATUS -eq 0 ];
    then
      SHOW_I_STATUS="nicht"
    else
      OTHER_SRC="$(inst_status_to_name $BASE_PKG_INST_STATUS)"
      SHOW_I_STATUS="aus anderer Quelle (${light_magenta}$OTHER_SRC${colors_off})"
    fi
    # if [ $ASK_TO_CONTINUE -eq 0 ] ||
    #    [ ${OPTION_FLAG[esamesrc]} -eq 0 ];
    # then
      e_and_l " $ACHTUNG_TAG:"
      e_and_l -n "$PRE_SPACE"
    # fi
    e_and_l " Das Basispaket ${light_cyan}$BASE_PKG_NAME${colors_off} ist $SHOW_I_STATUS installiert."
    e_and_l -n "$PRE_SPACE"
    if [ $ASK_TO_CONTINUE -eq 1 ];
    then
      if [ $BASE_PKG_INST_STATUS -eq 0 ] ||
         [ ${OPTION_FLAG[esamesrc]} -eq 0 ];
      then
        ask_yes_no_info "$INFO_PAKET" 1
        CONTINUE_INSTALL=$?
      else
        CONTINUE_INSTALL=0
        SHOW_SKIP_MESSAGE=1
      fi
      ASKED_ALREADY_TO_CONTINUE=1
    fi
  fi

  if [ $SHOW_SKIP_MESSAGE -eq 1 ];
  then
    e_and_l " Das Paket ${light_yellow}$INFO_PAKET${colors_off} (${light_magenta}$(inst_status_to_name $INSTALL_MODE)${colors_off}) wird daher ${bold_white}nicht${colors_off} installiert."
  fi
}

#===============================================================================
# Anzeige einer leeren Zeile in blauer Hintergrundfarbe ("Schlussstrich")
#===============================================================================
function show_full_bg_line {
  e_and_l ""
  e_and_l -n "${bg_blue}"
  for ((i=0; i<$USE_COLUMNS; i++)); do e_and_l -n " "; done;
  e_and_l "${colors_off}"
}

#===============================================================================
# Anzeige der Kopfzeile
#===============================================================================
function show_headlines {
  # -------
  # Farben
  # -------
  if [ ${OPTION_FLAG[nocolor]} -ne 1 ];
  then
    printf %b '\e]10;#eeeeee\a' # Schriftfarbe (VT100) immer hell ;)
    printf %b '\e]11;#242628\a' # Hintergrundfarbe (VT100) immer dunkel ;)
  fi
  clear
  HEADLINE_BACKGD_COLOR="${bg_blue}"
  HEADLINE_BORDER_COLOR="${light_blue}$HEADLINE_BACKGD_COLOR"
  HEADLINE_MAIN_COLOR="${bold_white}$HEADLINE_BACKGD_COLOR"
  HEADLINE_VERSION_COLOR="${light_blue}$HEADLINE_BACKGD_COLOR"
  HEADLINE_TEXT=""
  # ---------
  # 1. Zeile
  # ---------
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_TEXT+="┏"
  for ((i=2; i<$USE_COLUMNS; i++)); do HEADLINE_TEXT+="━"; done;
  HEADLINE_TEXT+="┓"
  HEADLINE_TEXT+=$'\n'
  # ---------
  # 2. Zeile
  # ---------
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_TEXT+="┃"
  HEADLINE_TEXT+="$HEADLINE_MAIN_COLOR"
  HEADLINE_TITLE_LENGTH=${#HEADLINE_TITLE}
  HEADLINE_SPACES=$((USE_COLUMNS - $HEADLINE_TITLE_LENGTH))
  HEADLINE_PREV=$((HEADLINE_SPACES / 2))
  HEADLINE_POST=$((HEADLINE_SPACES - $HEADLINE_PREV))
  for ((i=1; i<$HEADLINE_PREV; i++)); do HEADLINE_TEXT+=" "; done;
  HEADLINE_TEXT+="$HEADLINE_TITLE"
  for ((i=1; i<$HEADLINE_POST; i++)); do HEADLINE_TEXT+=" "; done;
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_TEXT+="┃"
  HEADLINE_TEXT+=$'\n'
  # ---------
  # 3. Zeile
  # ---------
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_VERSION="by Michael G. | v$VERSION"
  HEADLINE_VERSION_LENGTH=${#HEADLINE_VERSION}
  HEADLINE_SPACES=$((USE_COLUMNS - $HEADLINE_VERSION_LENGTH))
  HEADLINE_PREV=$((HEADLINE_SPACES / 2))
  HEADLINE_POST=$((HEADLINE_SPACES - $HEADLINE_PREV))
  HEADLINE_TEXT+="┃"
  for ((i=1; i<$HEADLINE_PREV; i++)); do HEADLINE_TEXT+=" "; done;
  HEADLINE_TEXT+="$HEADLINE_VERSION_COLOR"
  HEADLINE_TEXT+="$HEADLINE_VERSION"
  for ((i=1; i<$HEADLINE_POST; i++)); do HEADLINE_TEXT+=" "; done;
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_TEXT+="┃"
  HEADLINE_TEXT+=$'\n'
  # ---------
  # 4. Zeile
  # ---------
  HEADLINE_TEXT+="$HEADLINE_BORDER_COLOR"
  HEADLINE_TEXT+="┗"
  for ((i=2; i<$USE_COLUMNS; i++)); do HEADLINE_TEXT+="━"; done;
  HEADLINE_TEXT+="┛"
  # ---------
  HEADLINE_TEXT+="${colors_off}"
  e_and_l "$HEADLINE_TEXT"
  if [ ${OPTION_FLAG[nocolor]} -ne 1 ]; then echo -e ""; fi
}

#===============================================================================
# Darstellung von Zahlen in einem für Menschen lesbaren Format
# Da Bash nur Integer-Werte verarbeiten kann und grundsätzlich abrundet,
# müssen wir uns mit einem Trick auch noch um die richtige Rundung kümmern ;)
# ----------------------------------------------------------------------------
# Parameter $1: Umzuwandelnde Zahl
# Parameter $2: Zielgröße -> B (Bytes) | K (KB) | M (MB) | G (GB)
# Parameter $3: Faktor für die Größe eines Kilobytes (ohne Angabe = 1024)
#===============================================================================
function show_human_bytes {
  THE_NUMBER=$1
  SIZE_FACTOR="$(echo -n $2 | tr '[:lower:]' '[:upper:]')"
  if [ "$3" != "" ];
  then
    BYTES_FACTOR=$3
  else
    BYTES_FACTOR=$((1024))
  fi
  ONE_KB=$((BYTES_FACTOR))
  HALF_KB=$((ONE_KB / 2))
  ONE_MB=$((ONE_KB * BYTES_FACTOR))
  HALF_MB=$((ONE_MB / 2))
  ONE_GB=$((ONE_MB * BYTES_FACTOR))
  HALF_GB=$((ONE_GB / 2))
  ONE_TB=$((ONE_GB * BYTES_FACTOR))
  HALF_TB=$((ONE_TB / 2))
  if [ $THE_NUMBER -ge $ONE_TB ] &&
     [ "$SIZE_FACTOR" != "G" ] &&
     [ "$SIZE_FACTOR" != "M" ] &&
     [ "$SIZE_FACTOR" != "K" ] &&
     [ "$SIZE_FACTOR" != "B" ];
  then
    ((THE_NUMBER+=HALF_TB))
    ((THE_NUMBER=THE_NUMBER/BYTES_FACTOR/BYTES_FACTOR/BYTES_FACTOR/BYTES_FACTOR))
    THE_NUMBER="${THE_NUMBER} TB"
  else
    if [ $THE_NUMBER -ge $ONE_GB ] &&
       [ "$SIZE_FACTOR" != "M" ] &&
       [ "$SIZE_FACTOR" != "K" ] &&
       [ "$SIZE_FACTOR" != "B" ];
    then
      ((THE_NUMBER+=HALF_GB))
      ((THE_NUMBER=THE_NUMBER/BYTES_FACTOR/BYTES_FACTOR/BYTES_FACTOR))
      THE_NUMBER="${THE_NUMBER} GB"
    else
      if [ $THE_NUMBER -ge $ONE_MB ] &&
         [ "$SIZE_FACTOR" != "K" ] &&
         [ "$SIZE_FACTOR" != "B" ];
      then
        ((THE_NUMBER+=HALF_MB))
        ((THE_NUMBER=THE_NUMBER/BYTES_FACTOR/BYTES_FACTOR))
        THE_NUMBER="${THE_NUMBER} MB"
      else
        if [ $THE_NUMBER -ge $ONE_KB ] &&
           [ "$SIZE_FACTOR" != "B" ];
        then
          ((THE_NUMBER+=HALF_KB))
          ((THE_NUMBER=THE_NUMBER/BYTES_FACTOR))
          THE_NUMBER="${THE_NUMBER} KB"
        else
          THE_NUMBER="${THE_NUMBER} B"
        fi
      fi
    fi
  fi
  echo -e -n "$THE_NUMBER"
}

#===============================================================================
# Hinweis auf Alternativen eines installierten Paketes anzeigen (dabei
# werden zudem Starter zu den gefundenen alternativen Paketen erstellt)
#===============================================================================
function show_similar_pkg {
  if [ ${OPTION_FLAG[skipsims]} -eq 1 ]; then return 0; fi
  SIMILAR_SEEN_LIST=("$1")
  SIMILAR_ALREADY_SEEN=0
  CHECK_SIM_PACK="${SIMILAR_PACK[$1]}"
  while [ "$CHECK_SIM_PACK" != "" ] &&
        [ $SIMILAR_ALREADY_SEEN -eq 0 ];
  do
    for seen in ${SIMILAR_SEEN_LIST[@]};
    do
      if [ "$seen" != "" ] &&
         [ "$CHECK_SIM_PACK" == "$seen" ];
      then
        SIMILAR_ALREADY_SEEN=1
        break
      fi
    done
    if [ $SIMILAR_ALREADY_SEEN -eq 0 ];
    then
      get_install_status "$CHECK_SIM_PACK"
      SIM_PACK_INST_MODE=$?
      if [ $SIM_PACK_INST_MODE -ne 0 ];
      then
        if [ $SIMILAR_WARNING_SHOWN -eq 0 ];
        then
          e_and_l -n "$PRE_SPACE Alternative ${light_green}$CHECK_SIM_PACK${colors_off}"
          if [ "$PKG_VERSION" != "" ] &&
             [ "$PKG_VERSION" != "0" ];
          then
            e_and_l -n " ${light_yellow}$PKG_VERSION${colors_off}"
          fi
          e_and_l -n " ist"
          case "$SIM_PACK_INST_MODE" in
              1|3|4|5) e_and_l -n " bereits" ;;
                    2) e_and_l -n " als ${light_magenta}Snap${colors_off}" ;;
                    6) e_and_l -n " als ${light_magenta}Flatpak${colors_off}" ;;
          esac
          e_and_l " installiert"
          ((PAKETS_EXIST+=1))
          ((PAKETS_SIMILAR_EXIST+=1))
          ((SIMILAR_WARNING_SHOWN+=1))
        fi
        copy_starter_to_desktop "$CHECK_SIM_PACK" "" 0
      fi
    fi
    SIMILAR_SEEN_LIST+=($CHECK_SIM_PACK)
    CHECK_SIM_PACK="${SIMILAR_PACK[$CHECK_SIM_PACK]}"
  done
}

#===============================================================================
# Formattierte Anzeige der laufenden Nummer
#===============================================================================
function show_nr {
  echo -n " "
  if [ $1 -lt 99 ]; then echo -n " "; fi
  if [ $1 -lt 9 ];  then echo -n " "; fi
  echo -e -n "$(($1 + 1)):"
}

#===============================================================================
# Anzeige von übersprungenen Aktionen mit Ausgrauen des Textes
#===============================================================================
function skip_text {
  THE_SKIP_TEXT="$1"
  THE_SKIP_TEXT=${THE_SKIP_TEXT/ ... /}
  THE_SKIP_TEXT="$(clear_text "$THE_SKIP_TEXT") ... "
  if [ "$2" != "" ];
  then
    THE_SKIP_TEXT+="übersprungen ($2)"
  else
    THE_SKIP_TEXT+="wird übersprungen"
  fi
  echo -e -n "${dark_gray}${THE_SKIP_TEXT}${colors_off}"
}

#===============================================================================
# Installation und Updates von Snap blockieren und
# verbliebene (temporäre) Snap-Dateien löschen
# ---------------------------------------------
# Parameter $1: apt-mark hold setzen (1) oder nicht (0)
#===============================================================================
function snap_hold_and_clean {
  DO_MARK_HOLD=$1
  # ----------------------------------------------------------------------------
  # Installation und Updates von Snap blockieren
  # ----------------------------------------------------------------------------
  e_and_l -n " - Blockiere die Aktualisierung des Snap-Systems, bitte warten ... "
  # ----------------------------------
  # "Pinnen" mit Konfigurations-Datei
  # ----------------------------------
  if [ ! -d "$APT_PREFERENCES_DIR" ];
  then
    mkdir -p "$APT_PREFERENCES_DIR" &>/dev/null
  fi
  echo -e "" > "$SNAP_BLOCKING_FILE" 2>/dev/null
  if [ $? -eq 0 ];
  then
    echo -e "Package: snapd" >> "$SNAP_BLOCKING_FILE" 2>/dev/null
    echo -e "Pin: release a=*"  >> "$SNAP_BLOCKING_FILE" 2>/dev/null
    echo -e "Pin-Priority: -10" >> "$SNAP_BLOCKING_FILE" 2>/dev/null
  else
    ((SNAP_HOLD_RESULT+=1))
  fi
  # ----------------------
  # "Halten" mit apt-mark
  # ----------------------
  if [ $DO_MARK_HOLD -eq 1 ];
  then
    apt-mark hold snapd &>/dev/null
    if [ $? -ne 0 ]; then ((SNAP_HOLD_RESULT+=1)); fi
  fi
  # ---------
  if [ $SNAP_HOLD_RESULT -eq 0 ];
  then
    e_and_l "$OK_TAG"
  else
    e_and_l "$ERROR_TAG"
  fi
  # ----------------------------------------------------------------------------
  # Verbliebene (temporäre) Snap-Dateien löschen
  # ----------------------------------------------------------------------------
  e_and_l -n " - Lösche verbliebene Daten von Snap und Paketen, bitte warten ... "
  if [ -d /var/cache/snapd ];
  then
    rm -f -r /var/cache/snapd &>/dev/null
    if [ $? -ne 0 ]; then ((SNAP_RMDIR_RESULT+=1)); fi
  fi
  if [ $SNAP_RMDIR_RESULT -eq 0 ];
  then
    e_and_l "$OK_TAG"
  else
    e_and_l "$ERROR_TAG"
  fi
}

#===============================================================================
# Installations- und Update-Blockaden für snapd aufheben
#===============================================================================
function snap_unhold {
  # ----------------------------------
  # "Pinnen" mit Konfigurations-Datei
  # ----------------------------------
  if [ -s "$SNAP_BLOCKING_FILE" ];
  then
    mv -f "$SNAP_BLOCKING_FILE" "$SNAP_BLOCKING_FILE.bak" &>/dev/null
    if [ $? -ne 0 ]; then ((SNAP_UNHOLD_RESULT+=1)); fi
  fi
  # ----------------------
  # "Halten" mit apt-mark
  # ----------------------
  apt-mark unhold snapd &>/dev/null
  if [ $? -ne 0 ]; then ((SNAP_UNHOLD_RESULT+=1)); fi
  # ---------
}

#===============================================================================
# Zusammenfassung der System-Informationen erstellen
#===============================================================================
function system_info_summary {

  SYS_INFO_TXT=""
  if [ "$MACHINE_MODEL" != "" ];
  then
    SYS_INFO_TXT+=" Modell: ${bold_yellow}$MACHINE_MODEL${colors_off}"$'\n'
  fi

  SYS_INFO_TXT+=" Prozessor:${bold_yellow}"
  if [ "$CPU_MODEL" != "" ] &&
     [ "$CPU_MODEL" != "$MACHINE_MODEL" ];
  then
    SYS_INFO_TXT+=" $CPU_MODEL"
  fi
  if [ "$CPU_CODE" != "" ]; then SYS_INFO_TXT+=" $CPU_CODE"; fi
  if [ $CPU_CORES -gt 0 ]; then SYS_INFO_TXT+=" ${bold_cyan}($CPU_CORES Kerne)"; fi
  SYS_INFO_TXT+="${colors_off}"$'\n'

  if [ "$CPU_MIN_CLOCK" != "" ] &&
     [ "$CPU_MAX_CLOCK" != "" ];
  then
    SYS_INFO_TXT+=" Taktfrequenz: ${bold_yellow}$CPU_MIN_CLOCK${colors_off} bis ${bold_yellow}$CPU_MAX_CLOCK${colors_off} MHz"$'\n'
  fi

  if [ "$CPU_SERIAL" != "" ];
  then
    SYS_INFO_TXT+=" Seriennummer: ${bold_yellow}$CPU_SERIAL${colors_off}"$'\n'
  fi

  if [ "$MEMORY_AVAIL" != "" ] &&
     [ "$MEMORY_TOTAL" != "" ];
  then
    MEMORY_HUMAN_AVAIL=$(show_human_bytes ${MEMORY_AVAIL} "M")
    MEMORY_HUMAN_TOTAL=$(show_human_bytes ${MEMORY_TOTAL} "M")
    SYS_INFO_TXT+=" Speicher: ${bold_yellow}$MEMORY_HUMAN_AVAIL${colors_off} verfügbar / ${bold_yellow}$MEMORY_HUMAN_TOTAL${colors_off} total"$'\n'
  fi

  if [ "$GPU_MODEL" != "" ];
  then
    SYS_INFO_TXT+=" Grafik: ${bold_yellow}$GPU_MODEL${colors_off}"$'\n'
  fi

  if [ "$BOOT_MODE" != "" ];
  then
    SYS_INFO_TXT+=" Boot-Modus: ${bold_yellow}$BOOT_MODE${colors_off}"$'\n'
  fi

  SYS_INFO_TXT+=" Startpartition: ${bold_yellow}${root_partition/\/dev\//}${colors_off}"
  if [ "$root_partition_name" != "" ] ||
     [ "$root_partition_label" != "" ];
  then
    SYS_INFO_TXT+=" ${bold_cyan}("
    if [ "$root_partition_name" != "" ];
    then
      SYS_INFO_TXT+="$root_partition_name"
    fi
    if [ "$root_partition_label" != "" ];
    then
      if [ "$root_partition_name" != "" ]; then SYS_INFO_TXT+=", "; fi
      SYS_INFO_TXT+="$root_partition_label"
    fi
    SYS_INFO_TXT+=")${colors_off}"
  fi
  SYS_INFO_TXT+=$'\n'

  if [ "$OPERATION_SYSTEM" != "" ];
  then
    SYS_INFO_TXT+=" Betriebssystem: ${bold_yellow}"
    if [ $IS_PIOS -gt 0 ]; then SYS_INFO_TXT+="Pi OS / "; fi
    SYS_INFO_TXT+="$OPERATION_SYSTEM${colors_off}"
    if [ $(echo -n "$OPERATION_SYSTEM" | grep -c -i -E "ubuntu") -eq 0 ] &&
       [ "$UBUNTU_VERSION" != "" ];
    then
      SYS_INFO_TXT+=" ${dark_gray}[Ubuntu $UBUNTU_VERSION]${colors_off}"
    fi
    if [ "$OS_BIT_WIDTH" != "" ];
    then
      SYS_INFO_TXT+=" ${bold_cyan}($OS_BIT_WIDTH bit)${colors_off}"
    fi
    SYS_INFO_TXT+=$'\n'
  fi

  if [ "$DEBIAN_VERSION" != "" ];
  then
    SYS_INFO_TXT+=" Debian-Version: ${bold_yellow}$DEBIAN_VERSION${colors_off} ${bold_cyan}($DEBIAN_CODE)${colors_off}"$'\n'
  fi

  SYS_INFO_TXT+=" Kernel-Version: ${bold_yellow}$(uname -r)${colors_off}"$'\n'

  if [ "$ARCHITECTURE_MAIN" != "" ] ||
     [ "$ARCHITECTURE_OTHER" != "" ];
  then
    SYS_INFO_TXT+=" System-Architektur: ${bold_yellow}$ARCHITECTURE_MAIN${colors_off}"
    SYS_INFO_TXT+=" ${bold_cyan}($(uname -m))${colors_off}"
    if [ "${ARCHITECTURE_OTHER}" != "" ];
    then
      SYS_INFO_TXT+=" ${bold_yellow}[+${ARCHITECTURE_OTHER[@]}]${colors_off}"
    fi
    SYS_INFO_TXT+=$'\n'
  fi

  if [ "$CUR_SYS_LANG" != "" ];
  then
    SYS_INFO_TXT+=" Sprachumgebung: ${bold_yellow}$CUR_SYS_LANG${colors_off}"
    if [ "$CUR_LANG_NAME" != "" ]; then SYS_INFO_TXT+=" ${bold_cyan}($CUR_LANG_NAME)${colors_off}"; fi
    SYS_INFO_TXT+=$'\n'
  fi

  if [ "$DISPLAY_MANAGER" != "" ];
  then
    SYS_INFO_TXT+=" Display-Manager: ${bold_yellow}$DISPLAY_MANAGER${colors_off}"$'\n'
  fi

  if [ "$DISPLAY_SERVER" != "" ];
  then
    SYS_INFO_TXT+=" Display-Server: ${bold_yellow}$DISPLAY_SERVER${colors_off}"$'\n'
  fi

  if [ "$DESKTOP_ENVIRONMENT" != "" ];
  then
    SYS_INFO_TXT+=" Desktop-Environment: ${bold_yellow}$DESKTOP_ENVIRONMENT"
    if [ $(echo "$DESKTOP_ENVIRONMENT" | grep -c -i "labwc") -gt 0 ];
    then
      SYS_INFO_TXT+=" (Pixel)"
    fi
    SYS_INFO_TXT+=" $GNOME_VERSION${colors_off}"$'\n'
  fi

  if [ "$WINDOW_MANAGER" != "" ];
  then
    SYS_INFO_TXT+=" Window-Manager: ${bold_yellow}$WINDOW_MANAGER${colors_off}"$'\n'
  fi

  if [ "$WINDOW_THEME" != "" ];
  then
    SYS_INFO_TXT+=" Window-Thema: ${bold_yellow}$WINDOW_THEME${colors_off}"$'\n'
  fi

  if [ "$SYMBOL_THEME" != "" ];
  then
    SYS_INFO_TXT+=" Symbol-Thema: ${bold_yellow}$SYMBOL_THEME${colors_off}"$'\n'
  fi

  if [ "$FILE_MANAGER" != "" ];
  then
    SYS_INFO_TXT+=" Dateimanager: ${bold_yellow}$FILE_MANAGER${colors_off}"$'\n'
  fi

  if [ "$SHELL_TEXT" != "" ];
  then
    SYS_INFO_TXT+=" Shell: ${bold_yellow}$SHELL_TEXT${colors_off}"$'\n'
  fi

  SYS_INFO_TXT+=" Flatpak-Version: ${bold_yellow}"
  if [ "$FLATPAK_SYSTEM_VERSION" != "" ];
  then
    SYS_INFO_TXT+="$FLATPAK_SYSTEM_VERSION"
  else
    SYS_INFO_TXT+="-"
  fi
  SYS_INFO_TXT+="${colors_off}"$'\n'

  SYS_INFO_TXT+=" Docker-Version: ${bold_yellow}"
  if [ "$DOCKER_SYSTEM_VERSION" != "" ];
  then
    SYS_INFO_TXT+="$DOCKER_SYSTEM_VERSION"
  else
    SYS_INFO_TXT+="-"
  fi
  SYS_INFO_TXT+="${colors_off}"$'\n'

  SYS_INFO_TXT+=" Snap-Version: ${bold_yellow}"
  if [ "$SNAP_SYSTEM_VERSION" != "" ];
  then
    SYS_INFO_TXT+="$SNAP_SYSTEM_VERSION"
  else
    if [ $SNAP_INSTALLED -gt 0 ] &&
       [ $SNAP_ACTIVE -eq 0 ];
    then
      SYS_INFO_TXT+="deaktiviert"
    else
      SYS_INFO_TXT+="-"
    fi
  fi
  SYS_INFO_TXT+="${colors_off}"$'\n'

  SYS_INFO_TXT+=" Wine-Version: ${bold_yellow}"
  if [ "$WINE_VERSION" != "" ];
  then
    SYS_INFO_TXT+="$WINE_VERSION"
  else
    SYS_INFO_TXT+="-"
  fi
  SYS_INFO_TXT+="${colors_off}"$'\n'

  SYS_INFO_TXT+=" Hostname: ${bold_yellow}$(hostname)${colors_off}"$'\n'

  XTERM_NR="$(who | grep -E "\(\:" | head -n 1 | cut -d'(' -f 2 | cut -d')' -f 1)"
  if [ "$XTERM_NR" != "" ]; then XTERM_NR="["$XTERM_NR"]"; fi
  SYS_INFO_TXT+=" Benutzer: ${bold_yellow}$USER_USERNAME${colors_off} ${light_yellow}(id ${USER_UID})${colors_off} at ${bold_cyan}$(tty) $XTERM_NR${colors_off}"
  echo -e "$SYS_INFO_TXT"
}

#===============================================================================
# Umwandlung eines Zeitstempels (Sekunden) in einen lesbaren Text
# ----------------------------------------------------------------
# Parameter $1: Sekunden
# Parameter $2: Zeitangaben in Kurzform (true) oder Langform (false)
# Parameter $3: Leerzeichen einfügen (true) oder nicht (false)
#===============================================================================
function time_to_string {
  I_SECONDS=$1
  if [ "$2" == "true" ];
  then
    STR_DAY="d"
    STR_HUR="h"
    STR_MIN="m"
    STR_SEC="s"
  else
    STR_DAY="Tage"
    STR_HUR="Stunden"
    STR_MIN="Minuten"
    STR_SEC="Sekunden"
  fi
  if [ "$3" == "true" ];
  then
    SPACE_CHAR=" "
  else
    SPACE_CHAR=""
  fi
  T_DAYS=$((I_SECONDS / (24 * 60 * 60)))
  T_HOURS=$(((I_SECONDS / 3600) - (T_DAYS * 24)))
  T_MINUTES=$(((I_SECONDS / 60) - (T_DAYS * 24 * 60) - (T_HOURS * 60)))
  T_SECONDS=$((I_SECONDS - (T_DAYS * 24 * 60 * 60) - (T_HOURS * 60 * 60) - (T_MINUTES * 60)))
  TIME_STRING=""
  if [ $T_DAYS    -gt 0 ]; then TIME_STRING="$T_DAYS$SPACE_CHAR$STR_DAY "; fi
  if [ $T_HOURS   -gt 0 ]; then TIME_STRING="$TIME_STRING$T_HOURS$SPACE_CHAR$STR_HUR "; fi
  if [ $T_MINUTES -gt 0 ]; then TIME_STRING="$TIME_STRING$T_MINUTES$SPACE_CHAR$STR_MIN "; fi
  if [ $T_SECONDS -gt 0 ]; then TIME_STRING="$TIME_STRING$T_SECONDS$SPACE_CHAR$STR_SEC"; fi
  if [ "$TIME_STRING" == "" ];
  then
    TIME_STRING="$NE_TXT"
  fi
  echo -e -n "$TIME_STRING"
}

#===============================================================================
# Interne Liste der installierten Flatpak-Pakete erstellen
# Hinweis: Nur Anwendungen, keine Systemkomponenten (Treiber etc.)
#===============================================================================
function update_flatpak_list {
  flatpak list --app --columns=name,version,ref > "$FLATPAK_INSTALLED_PKG_LIST" 2>/dev/null
}

#===============================================================================
# Liste der installierten Snap-Pakete erstellen
# Hinweis: Nur Anwendungen, keine Systemkomponenten (Treiber etc.)
#===============================================================================
function update_snap_list {
  LIST_FILE_NAME="$1"
  # ls -1 /snap/bin | grep -i -v snap > "$SNAP_INSTALLED_PKG_LIST" 2>/dev/null
  snap list 2>/dev/null | \
       grep -i -v -E "\bbase\b" | \
       grep -i -v -E "core" | \
       grep -i -v -E "^mesa" | \
       grep -i -v -E "^snap" | \
       grep -i -v -E "^gnome-[0-9]+" | \
       grep -i -v -E "themes" | \
       awk '{print $1}' | \
       awk 'NR>1' > "$LIST_FILE_NAME"
}

#===============================================================================
# Benutzer zwischen 0, 1 und 2 auswählen lassen
#===============================================================================
function user_choice_012 {
  DEFAULT_CHOICE=0
  if [ "$1" != "" ]; then DEFAULT_CHOICE=$1; fi
  e_and_l -n " Bitte gewünschte Auswahl treffen (Enter-Taste = $DEFAULT_CHOICE): "
  if [ ${OPTION_FLAG[notoall]} -eq 0 ];
  then
    THE_USERS_CHOICE=-1
    while [ $THE_USERS_CHOICE -lt 0 ] ||
          [ $THE_USERS_CHOICE -gt 2 ];
    do
      read -N 1 -r -s THE_USERS_CHOICE
      if [ "$THE_USERS_CHOICE" == $'\n' ];
      then
        THE_USERS_CHOICE=$DEFAULT_CHOICE
      else
        THE_USERS_CHOICE=$(echo $THE_USERS_CHOICE | sed 's/[^0-9]*//g')
        if [ "$THE_USERS_CHOICE" == "" ]; then THE_USERS_CHOICE=-1; fi
      fi
    done
    e_and_l "$THE_USERS_CHOICE"
  else
    THE_USERS_CHOICE=0
    e_and_l "${light_magenta}0${colors_off}"
  fi
  return $THE_USERS_CHOICE
}

#===============================================================================
# Download mehrer "einfacher" Dateien (ohne die Erweiterungen für
# HTML-Webseiten einschließlich deren Verknüpfungen und Medien) von einem
# Server-Verzeichnis in einen lokalen Ordner.
# HINWEIS: Begrenzt auf ein Server-Verzeichnis ohne dessen Unterordner!
#===============================================================================
function wget_dir {
  REMOTE_SOURCE_DIR="$1"
  LOCAL_TARGET_DIR="$2"
  WGET_RESULT=1
  if [ "$LOCAL_TARGET_DIR" != "" ];
  then
    if [ ! -d "$LOCAL_TARGET_DIR" ]; then mkdir -p "$LOCAL_TARGET_DIR" &>/dev/null; fi
    if [ -d "$LOCAL_TARGET_DIR" ];
    then
      wget --recursive --directory-prefix="$LOCAL_TARGET_DIR" --execute robots=off --no-parent --level=1 --no-directories --timestamping --quiet --reject="index.html*" "$REMOTE_SOURCE_DIR"
      WGET_RESULT=$?
      # ------------------------------------------------------------------------
      # Wichtige Parameter
      # ACHTUNG: Auf dem Server muss per .htaccess "Options +Indexes" gesetzt sein ;)
      # ------------------------------------------------------------------------
      # --recursive                # Lädt mehrere Dateien und Ordner rekursiv herunter
      # --directory-prefix         # Zielverzeichnis
      # --execute robots=off       # Ignoriert die Angaben in der robots.txt des Servers
      # --user-agent="Mozilla/5.0" # Setzt eine Browser-Kennung (falls diese erforderlich ist)
      # --no-parent                # Verzweigt nicht in übergeordnete Ordner (./..)
      # --level=1                  # Begrenzt die Anzahl der Unterordner-Level (1=nur der aktuelle Ordner, also nicht rekursiv)
      # --no-directories           # Erzeugt keine Ordnerstruktur entsprechend dem URL-Pfad
      # --timestamping             # Nur Dateien holen, die neuer als die lokalen Dateien sind
      # --random-wait              # Wartet zwichen den Downloads der einzelnen Dateien (Verschleiereung der Automatisierung)
      # --quiet                    # Erzeugt keine Ausgabe wie den Download-Fortschritt
      # --reject="index.html*"     # Löscht die von wget beim Download angelegten internen "index.html*"-Dateien
      # ---------------------------------------------------------------------------
    fi
  fi
  return $WGET_RESULT
}

################################################################################
#                                                                              #
#                             Variablen definieren                             #
#                                                                              #
################################################################################
#===============================================================================
# URLs zum Download dieses Skriptes
#===============================================================================
THIS_SCRIPT_URL="https://migano.de/download/lissy/lissy"
THIS_SCRIPT_ICO="https://migano.de/download/lissy/png/lissy.png"

#===============================================================================
# Schrift- und Hintergrundfarben
# -------------------------------
# Bei Änderungen der Farbnamen auch die COL_VAR_LIST anpassen!
# ACHTUNG: Die Farben für das Menü werden in dialogrc festgelegt
#===============================================================================
# ----------------------------
# Farbenamen nach ANSI-Schema
# ----------------------------
# NR  FG  BG   Name
#  0  30	40	 black
#  1  31	41	 red
#  2  32	42	 green
#  3  33	43	 yellow
#  4  34	44	 blue
#  5  35	45	 magenta
#  6  36	46	 cyan
#  7  37	47	 white
#  8  90	100	 bright black (dark-gray)
#  9  91	101	 bright red
# 10  92	102	 bright green
# 11  93	103	 bright yellow
# 12  94	104	 bright blue
# 13  95	105	 bright magenta
# 14  96	106	 bright cyan
# 15  97	107	 bright white
# ----------------------------
declare -A ANSI_COLOR_NAMES
ANSI_COLOR_NAMES[0]="black"
ANSI_COLOR_NAMES[1]="red"
ANSI_COLOR_NAMES[2]="green"
ANSI_COLOR_NAMES[3]="brown"
ANSI_COLOR_NAMES[4]="blue"
ANSI_COLOR_NAMES[5]="magenta"
ANSI_COLOR_NAMES[6]="cyan"
ANSI_COLOR_NAMES[7]="light-gray"
ANSI_COLOR_NAMES[8]="dark-gray"
ANSI_COLOR_NAMES[9]="light-red"
ANSI_COLOR_NAMES[10]="light-green"
ANSI_COLOR_NAMES[11]="yellow"
ANSI_COLOR_NAMES[12]="light-blue"
ANSI_COLOR_NAMES[13]="light-magenta"
ANSI_COLOR_NAMES[14]="light-cyan"
ANSI_COLOR_NAMES[15]="white"
# ------------
# Text normal
# ------------
black='\033[0;30m'
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
blue='\033[0;34m'
magenta='\033[0;35m'
cyan='\033[0;36m'
white='\033[0;97m'
# ----------
# Text hell
# ----------
dark_gray='\033[0;90m'
light_red='\033[0;91m'
light_green='\033[0;92m'
light_yellow='\033[0;93m'
light_blue='\033[0;94m'
light_magenta='\033[0;95m'
light_cyan='\033[0;96m'
light_gray='\033[0;37m'
# ----------
# Text fett
# ----------
bold_black='\033[1;30m'
bold_red='\033[1;31m'
bold_green='\033[1;32m'
bold_yellow='\033[1;33m'
bold_blue='\033[1;34m'
bold_magenta='\033[1;35m'
bold_cyan='\033[1;36m'
bold_white='\033[1;37m'
# -------------------
# Text unterstrichen
# -------------------
uline_black='\033[4;30m'
uline_red='\033[4;31m'
uline_green='\033[4;32m'
uline_yellow='\033[4;33m'
uline_blue='\033[4;34m'
uline_magenta='\033[4;35m'
uline_cyan='\033[4;36m'
uline_white='\033[4;37m'
# ------------
# Hintergrund
# ------------
bg_black='\033[40m'
bg_red='\033[41m'
bg_green='\033[42m'
bg_yellow='\033[43m'
bg_blue='\033[44m'
bg_magenta='\033[45m'
bg_cyan='\033[46m'
bg_white='\033[47m'
# -------------
# Keine Farben
# -------------
colors_off='\033[0m'
colors_invers='\033[7m'
# ------------
# Linienfarbe
# ------------
full_line_color='\033[1;34m'
half_line_color='\033[0;90m'
if [ -x "/usr/bin/tput" ] && tput setaf 1 &>/dev/null;
then
  # clear_this_line=$(tput el) # Aktuell nicht benötigt
  clear_last_line=$(tput cuu 1 && tput el)
fi

#===============================================================================
# Anzahl der zur Verfügung stehenden Spalten im aktuellen Terminal
#===============================================================================
USE_COLUMNS=$(echo ${COLUMNS} | sed 's/[^0-9]*//g')
if [ "$USE_COLUMNS" != "" ];
then
  if [ $USE_COLUMNS -lt 80 ]; then USE_COLUMNS=80; fi
else
  USE_COLUMNS=80
fi

#===============================================================================
# Textbausteine
#===============================================================================
HEADLINE_TITLE="Linux System Setup Utility"
FULL_LINE="${full_line_color}$(printf '─%.0s' {1..80})${colors_off}"
HALF_LINE="${half_line_color}$(printf '─%.0s' {1..40})${colors_off}"
HALF_MINUS_LINE="${half_line_color}$(printf '\x2D%.0s' {1..40})${colors_off}"
PRE_SPACE=$(printf ' %.0s' {1..5})
NA_TXT="nicht verfügbar"
NE_TXT="nicht ermittelbar"
NF_TXT="nicht gefunden"
NG_TXT="nicht mit GNOME"
NM_TXT="nur mit MATE"
NR_TXT="nicht für root"
NU_TXT="nur mit Ubuntu"
NV_TXT="nicht vorhanden"
NFPI45_TXT="nur für Pi 4 / 5"
NAPIOSDESK_TXT="nicht bei Pi OS"
KF_TAG="${bold_green}ok${colors_off} ${dark_gray}(keine fehlenden gefunden)${colors_off}"
NC_TAG="${bold_green}ok${colors_off} ${dark_gray}(keine Änderung)${colors_off}"
ND_TAG="${bold_green}ok${colors_off} ${dark_gray}(keine Dateien gefunden)${colors_off}"
NF_TAG="${bold_green}ok${colors_off} ${dark_gray}(keine gefunden)${colors_off}"
OA_TAG="${bold_green}ok${colors_off} ${dark_gray}(Autostart aktiv)${colors_off}"
OK_TAG="${bold_green}ok${colors_off}"
FERTIG_TAG="${bold_green}fertig${colors_off}"
HINWEIS_TAG="${bold_yellow}Hinweis${colors_off}"
WARN_TAG="${bold_yellow}Warnung${colors_off}"
ACHTUNG_TAG="${bold_red}Achtung${colors_off}"
ERROR_TAG="${bold_red}Fehler${colors_off}"
NA_TAG="$ERROR_TAG - $NA_TXT"
USER_CHOICE_YES="OK, Du hast es so gewollt ..."
USER_CHOICE_NO="Sicherheit geht vor!"
REBOOT_MSG=" $HINWEIS_TAG: Änderungen werden erst nach Neustart des Systems wirksam."
NO_DESKTOP_INFO=" $HINWEIS_TAG: Lissy wurde nicht aus einem Desktop gestartet. Folgende Komponenten"$'\n'
NO_DESKTOP_INFO+=" werden daher übersprungen und nicht zur Installation/Konfiguration angeboten:"

#===============================================================================
# Eigenen Benutzernamen und Benutzer-ID ermitteln
#===============================================================================
if [ $SUDO_USER ]; then USER_USERNAME="$SUDO_USER"; else USER_USERNAME=$(whoami); fi
USER_UID=$(id -u $USER_USERNAME)

#===============================================================================
# Ordner zur Speicherung von Downloads, Konfigurationen u. Log-Dateien anlegen
# ACHTUNG: Angaben OHNE Slash(/) am Ende!
#===============================================================================
# ---------------------
# Ordner des Benutzers
# ---------------------
SCRIPT_PATH="$(pwd)"
SCRIPT_NAME="${0##*/}"
if [ "$USER_USERNAME" == "root" ];
then
  USER_HOME_DIR="/root"
  DOWNLOAD_DIR="/tmp/$SCRIPT_NAME"
else
  USER_HOME_DIR="/home/$USER_USERNAME"
  DOWNLOAD_DIR="$USER_HOME_DIR/Downloads/$SCRIPT_NAME"
fi

# ------------------------------------------------
# Ordner für Konfigurationsdateien dieses Skripts
# ------------------------------------------------
USER_CONFIG_DIR="$USER_HOME_DIR/.config"
if [ ! -d "$USER_CONFIG_DIR" ];
then
  mkdir -p "$USER_CONFIG_DIR" &>/dev/null
  if [ $? -eq 0 ];
  then
    chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_CONFIG_DIR" &>/dev/null
    chmod -R 0755 "$USER_CONFIG_DIR" &>/dev/null
  fi
fi
SCRIPT_CONFIG_DIR="$USER_CONFIG_DIR/$SCRIPT_NAME"
if [ ! -d "$SCRIPT_CONFIG_DIR" ];
then
  mkdir -p "$SCRIPT_CONFIG_DIR" &>/dev/null
  if [ $? -eq 0 ];
  then
    chown -R "$USER_USERNAME:$USER_USERNAME" "$SCRIPT_CONFIG_DIR" &>/dev/null
    chmod -R 0755 "$SCRIPT_CONFIG_DIR" &>/dev/null
  fi
fi
# -------------------------------------------
# Ordner für Downloads und temporäre Dateien
# -------------------------------------------
DOWNLOAD_DIR+="_files"
if [ ! -d "$DOWNLOAD_DIR" ];
then
  mkdir -p "$DOWNLOAD_DIR" &>/dev/null
  if [ $? -eq 0 ];
  then
    chown -R "$USER_USERNAME:$USER_USERNAME" "$DOWNLOAD_DIR" &>/dev/null
    chmod -R 0755 "$DOWNLOAD_DIR" &>/dev/null
  else
    echo -e ""
    echo -e " ${bold_white}$HEADLINE_TITLE v$VERSION${colors_off}"
    echo -e " $ERROR_TAG: ${bold_blue}$DOWNLOAD_DIR${colors_off} kann nicht angelegt werden!"
    echo -e ""
    exit 1
  fi
fi
# ---------------------------------------------------
# Ordner mit individuellen Menü-Einträgen (Startern)
# ---------------------------------------------------
STARTMENU_DIR="$USER_HOME_DIR/.local/share/applications"

#===============================================================================
# Quell-Angaben der Paketverwaltung (OHNE / am Ende!)
#===============================================================================
# Basis-Ordner für apt-Quell-Angaben
APT_SOURCES_MAIN_DIR="/etc/apt"
# Datei mit Quell-Angaben
APT_SOURCES_LIST_FILE="$APT_SOURCES_MAIN_DIR/sources.list"
# Ordner mit Dateien, die weitere Quell-Angaben beinhalten
APT_SOURCES_LIST_DIR="$APT_SOURCES_MAIN_DIR/sources.list.d"
# Ordner mit Dateien, die individuelle Konfigurationen für apt enthalten
APT_PREFERENCES_DIR="$APT_SOURCES_MAIN_DIR/preferences.d"

#===============================================================================
# Dateien zur Speicherung von temporären Daten
#===============================================================================
# Log-Dateien
LOG_FILE="$DOWNLOAD_DIR/$(date +%Y-%m-%d-%H%M).log"
LOG_TEMP="$DOWNLOAD_DIR/$(date +%Y-%m-%d-%H%M).tmp"
# Datei zur Zwischenspeicherung des Exit-Codes des letzten Kommandos
LAST_EXIT_CODE="$DOWNLOAD_DIR/laexco"

#===============================================================================
# Dateien zur Speicherung von Konfigurationen
#===============================================================================
# Antworten auf Fragen zur Installation von Programmen
# und Durchführung von Optionen (autoyorn)
AUTO_ANSWER_FILE="$SCRIPT_CONFIG_DIR/auto_answers"
# Paketlisten (saveconf)
USER_PAKET_LIST="$SCRIPT_CONFIG_DIR/$SCRIPT_NAME.list"
# Ausgewählte Kategorien und Optionen (saveconf)
USER_SCRIPT_CONFIG="$SCRIPT_CONFIG_DIR/$SCRIPT_NAME.conf"

#===============================================================================
# Sonstige Dateien zur Speicherung von Ergebnislisten
#===============================================================================
# Liste mit Diensten, die zu erheblicher Verzögerung des Boot-Vorgangs führen
BOOT_BLAME_LIST="$DOWNLOAD_DIR/boot_blame.list"
# Liste ungültiger Verknüpfungen
BROKEN_LINKS_LIST="$DOWNLOAD_DIR/broken_links.list"
# Liste verwaister Paket-Konfigurationen
CONFIG_REST_LIST="$DOWNLOAD_DIR/config_rest.list"
# Liste vormals deaktivierter Komponenten
DEACTIVATED_ITEMS_LIST="$DOWNLOAD_DIR/deactivated_items.list"
# Liste abgelaufener APT-Key-Signaturen
EXPIRED_APT_KEYS_LIST="$DOWNLOAD_DIR/expired_apt_keys.list"
# Liste mit fehlerhaften System-Diensten
FAILED_SERVICES_LIST="$DOWNLOAD_DIR/failed_services.list"
# Liste veralteter Kernel-Komponenten
OLD_KERNEL_LIST="$DOWNLOAD_DIR/old_kernel.list"
# Liste fehlerhafter Paket-Abhängigkeiten
PKG_BROKEN_LIST="$DOWNLOAD_DIR/pkg_broken.list"
# Liste nicht mehr benötigter Pakete und Komponenten
PKG_GARBAGE_LIST="$DOWNLOAD_DIR/pkg_garbage.list"
# Liste fehlerhafter Netzwerk-Dateisysteme
FSTAB_NETPATH_LIST="/home/michael/Downloads/lissy_files/fstab_netpath.list"

#===============================================================================
# Daten für automatische Antworten (autoyorn) einlesen
# (vor Anzeige des Menus, damit darin die Option für autoyorn nur angezeigt
#  wird, wenn es auch automatische Antworten gibt).
#===============================================================================
declare -A AUTO_ANSWERS
if [ -s "$AUTO_ANSWER_FILE" ];
then
  while read auto_answer_line;
  do
    if [ "$auto_answer_line" != "" ];
    then
      auto_answer_id="$(echo $auto_answer_line | cut -d':' -f 1)"
      auto_answer_txt="$(echo $auto_answer_line | cut -d':' -f 2)"
      AUTO_ANSWERS["$auto_answer_id"]="$auto_answer_txt"
    fi
  done < "$AUTO_ANSWER_FILE"
else
  echo -e "" > "$AUTO_ANSWER_FILE" &>/dev/null
  chown -R "$USER_USERNAME:$USER_USERNAME" "$AUTO_ANSWER_FILE" &>/dev/null
  chmod -R 0644 "$AUTO_ANSWER_FILE" &>/dev/null
fi

#===============================================================================
# Pfad erweitern zur Sicherstellung, dass alle Systemprogramme gefunden werden
#===============================================================================
ORIGINAL_USER_PATH="$(sudo --user=${USER_USERNAME} bash -c 'echo $PATH' 2>/dev/null)"
export PATH="$PATH:/usr/sbin:/usr/bin:/sbin:/bin"

#===============================================================================
# Dateisystem-Tabelle
#===============================================================================
ETC_FSTAB="/etc/fstab"

#===============================================================================
# Datei mit Benutzern auf PI-OS, die kein sudo-Passwort brauchen
#===============================================================================
PI_NOPASS_FILE="/etc/sudoers.d/010_pi-nopasswd"

#===============================================================================
# Dateien mit Konfigurationen des GRUB-Bootloaders
#===============================================================================
GRUB_DEFAULT_FILE="/etc/default/grub"    # Standards (Defaults)
GRUB_CUSTOM_FILE="/boot/grub/custom.cfg" # Individueller Hintergrund und Farben

#===============================================================================
# Lokale Verzeichnisse für Konfiguration der Display-Manager
#===============================================================================
LDM_CONF_DIR="/etc/lightdm"
LDM_CONF_FILE="$LDM_CONF_DIR/lightdm.conf"
GDM_CONF_DIR="/etc/gdm3"
GDM_CCONF_FILE="$GDM_CONF_DIR/custom.conf"
GDM_DCONF_FILE="$GDM_CONF_DIR/greeter.dconf-defaults"

#===============================================================================
# Server-Verzeichnis, aus welchem zur Laufzeit dieses Skriptes weitere frei
# zugängliche (per URL direkt erreichbare) Ressourcen heruntergeladen werden.
# Im Gegensatz zu RESSOURCE_DOWNLOADER bleiben beim direkten Download auch die
# Zeitstempel der Original-Dateien erhalten. ACHTUNG: OHNE Slash (/) am Ende!
#===============================================================================
RESSOURCE_SERVER_DIR="https://migano.de/download/lissy/res"
# RESSOURCE_SERVER_DIR="http://localhost/entwicklung/migano.de/download/lissy/res"

#===============================================================================
# Server-Skript zum Download von nicht frei zugänglichen bzw. in individuellen
# Benutzerverzeichnissen liegenden Ressourcen. Zur Authentifizierung müssen
# Benutzername und Passwort angegeben werden. Im Gegensatz zum Download über
# RESSOURCE_SERVER_DIR erhalten die lokal erstellten Dateien dabei das aktuelle
# Datum als Zeitstempel! ACHTUNG: Angaben OHNE Slash (/) am Ende!
#===============================================================================
RESSOURCE_DOWNLOADER="https://migano.de/download.php?f=lissy/res"
# RESSOURCE_DOWNLOADER="http://localhost/entwicklung/migano.de/download.php?f=lissy/res"

#===============================================================================
# Parameter zur Steuerung der grundsätzlichen Funktionsweise des Skriptes,
# welche nicht im Auswahl-Menü enthalten sind und nur auf der Kommandozeile
# übergeben werden können.
#===============================================================================
NO_CONFIG=0
NO_MENU=0
RECALL=0
RESET_CONFIG=0
SHOW_HELP=0
for arg in $@;
do
  arg=$(printf %b "${arg}" | tr A-Z a-z)
  # ----------------------------------------------
  # Keine benutzerspezifische Konfiguration laden
  # ----------------------------------------------
  if [ "$arg" == "noconfig" ];
  then
    NO_CONFIG=1
  fi
  # -------------------
  # Kein Menu anzeigen
  # -------------------
  if [ "$arg" == "nomenu" ];
  then
    NO_MENU=1
  fi
  # ---------------------------------------------
  # Erkennung ob wir uns selbst aufgerufen haben
  # ---------------------------------------------
  if [ "$arg" == "recall" ];
  then
    RECALL=1
  fi
  # ---------------------------------------------------
  # Nur Hilfe anzeigen, sonst keine Aktion durchführen
  # ---------------------------------------------------
  if [ $(echo -n "${arg}" | grep -i -c -E "\-*help") -gt 0 ];
  then
    SHOW_HELP=1
  fi
  # ---------------------------------------
  # Alle gespeicherten Einstellung löschen
  # ---------------------------------------
  if [ "$arg" == "reset" ] &&
     [ $SHOW_HELP -eq 0 ];
  then
    RESET_CONFIG=1
  fi
done

# ==============================================================================
# Status zu Flatpak, Snap und Docker ermitteln
# ---------------------------------------------
# Achtung: Es wird unterschieden zwischen installiert (_INSTALLED) und
# aktiv (_ACTIVE), um eventuell deaktivierte Subsysteme erkennen zu können
# ==============================================================================
# --------
# Flatpak
# --------
FLATPAK_INSTALLED=$(LANG=C dpkg-query -W -f='${Status}' "flatpak" 2>/dev/null | grep -i -c -E "ok installed")
FLATPAK_ACTIVE=0
FLATPAK_SYSTEM_VERSION="$(flatpak --version 2>/dev/null | awk '{print $2}' | xargs 2>/dev/null)"
if [ "$FLATPAK_SYSTEM_VERSION" != "" ]; then FLATPAK_ACTIVE=1; fi
FLATPAK_INSTALLED_PKG_LIST="$DOWNLOAD_DIR/flatpak_installed_pkg.list"
FLATPAK_REMOTE_LIST="$DOWNLOAD_DIR/flatpak_remote_list"
# -----
# Snap
# -----
# Über den "Umweg" mit systemctl, weil snapd installiert und nur deaktiviert
# sein kann, wobei snap --version dann auch trotz Deaktivierung aufrufbar ist
# -----
SNAP_SYS_COMPONENTS=('snapd.socket' 'snapd.seeded.service' 'snapd.service' 'snapd')
SNAP_INSTALLED=$(LANG=C dpkg-query -W -f='${Status}' "snapd" 2>/dev/null | grep -i -c -E "ok installed")
SNAP_ACTIVE=$(LANG=C systemctl status snapd 2>/dev/null | grep -c -i -E "\:\s*\bactive\b")
if [ $SNAP_ACTIVE -gt 0 ];
then
  SNAP_SYSTEM_VERSION="$(snap --version 2>/dev/null | grep -i -E "^\bsnap(d)*\b" | head -n 1 | awk '{print $2}' | xargs 2>/dev/null)"
else
  SNAP_SYSTEM_VERSION=""
fi
SNAP_INSTALLED_PKG_LIST="$DOWNLOAD_DIR/snap_installed_pkg.list"
SNAP_SNAPSHOT_LIST="$DOWNLOAD_DIR/snap_snapshot.list"
SNAP_BLOCKING_FILE="$APT_PREFERENCES_DIR/nosnap.pref"
# -------
# Docker
# -------
DOCKER_INSTALLED=$(LANG=C dpkg-query -W -f='${Status}' "docker.io" 2>/dev/null | grep -i -c -E "ok installed")
DOCKER_ACTIVE=0
DOCKER_SYSTEM_VERSION="$(docker --version 2>/dev/null | sed -E "s/.*version\s([0-9\.]*).*/\1/gi" | xargs 2>/dev/null)"
if [ "$DOCKER_SYSTEM_VERSION" != "" ]; then DOCKER_ACTIVE=1; fi

#===============================================================================
# Systemarchitektur ermitteln
#===============================================================================
GNOME_VERSION=""
GNOME_PLATFORM=0
if [ $SHOW_HELP -eq 0 ];
then
  echo -e ""
  echo -e -n " Initialisierung, bitte warten ... "

  #-----------------------------------------------------------------------------
  # Hardware
  #-----------------------------------------------------------------------------
  IFS=':' MACHINE_STRING=($(LANG=C dmesg 2>/dev/null | grep -i -E "machine\s*model"))
  ANZ_ARGS=${#MACHINE_STRING[@]}
  if [ $ANZ_ARGS -gt 0 ];
  then
    MACHINE_MODEL="${MACHINE_STRING[((ANZ_ARGS-=1))]}"
  else
    IFS=':' MACHINE_STRING=($(LANG=C dmesg 2>/dev/null | grep -i -E "DMI:"))
    MACHINE_MODEL="${MACHINE_STRING[1]}"
  fi
  IFS=' '
  MACHINE_MODEL=$(echo -n "${MACHINE_MODEL:0:32}" | xargs)
  #---------------------------------
  # Prüfen ob Raspberry Pi 4 oder 5
  #---------------------------------
  IS_RASPBERRY_PI=0
  PI_MODELL=""
  if [ -f "/proc/cpuinfo" ];
  then
    IS_RASPBERRY_PI=$(grep -i -c -E "raspberry" "/proc/cpuinfo")
  fi
  if [ "$MACHINE_MODEL" != "" ];
  then
    if [ $IS_RASPBERRY_PI -eq 0 ];
    then
      IS_RASPBERRY_PI=$(echo "$MACHINE_MODEL" | grep -i -c -E "raspberry")
    fi
    if [ $IS_RASPBERRY_PI -gt 0 ];
    then
      PI_MODELL="$(echo "$MACHINE_MODEL" | sed -E "s/.*\sPi\s*([0-9]).*/\1/i")"
      if [ "$PI_MODELL" != "4" ] &&
         [ "$PI_MODELL" != "5" ];
      then
        IS_RASPBERRY_PI=0
        PI_MODELL=""
      fi
    fi
  fi

  #-----------
  # Prozessor
  #-----------
  # Bezeichnung und Taktfrequenz
  if lscpu --version &>/dev/null;
  then
    CPU_MODEL="$(LANG=C lscpu 2>/dev/null | grep -i -E "^\s*model\s*name\s*\:" | cut -d':' -f2 | xargs)"
    CPU_MIN_CLOCK="$(LANG=C lscpu 2>/dev/null | grep -i -E "^\s*CPU min MHz\s*\:" | cut -d':' -f2 | cut -d',' -f1 | cut -d'.' -f1 | xargs)"
    CPU_MAX_CLOCK="$(LANG=C lscpu 2>/dev/null | grep -i -E "^\s*CPU max MHz\s*\:" | cut -d':' -f2 | cut -d',' -f1 | cut -d'.' -f1 | xargs)"
  else
    CPU_MIN_CLOCK=""
    CPU_MAX_CLOCK=""
  fi
  if [ "$CPU_MODEL" == "" ];
  then
    CPU_MODEL=$(grep -i -E "^\s*model\s*name*\s*\:" "/proc/cpuinfo" 2>/dev/null)
  fi
  if [ "$CPU_MODEL" == "" ];
  then
    CPU_MODEL=$(grep -i -E "^\s*model\s*\:" "/proc/cpuinfo" 2>/dev/null)
  fi
  CPU_MODEL=$(echo -n "${CPU_MODEL##*\:}" | xargs)
  # Anzahl Kerne
  CPU_CORES=$(grep -i -c -E "^\s*processor\s*\:" "/proc/cpuinfo" 2>/dev/null)
  # CPU-Code
  CPU_CODE=$(grep -i -E "^\s*hardware\s*\:" "/proc/cpuinfo" 2>/dev/null)
  CPU_CODE=$(echo -n "${CPU_CODE##*\:}" | xargs)
  # Seriennummer
  CPU_SERIAL=$(grep -i -E "^\s*serial\s*\:" "/proc/cpuinfo" 2>/dev/null)
  CPU_SERIAL=$(echo -n "${CPU_SERIAL##*\:}" | xargs)

  # ----------
  # GPU-Infos
  # ----------
  # Alternative A mit lspci - nicht standardisiert
  # LSPCI_INSTALLED=$(LANG=C dpkg-query -W -f='${Status}' "pciutils" 2>/dev/null | grep -i -c -E "ok installed")
  # if [ $LSPCI_INSTALLED -eq 0 ];
  # then
  #   e_and_l " Installiere ${light_yellow}pciutils${colors_off} ... "
  #   apt install "pciutils" -y &>"$LOG_TEMP"
  #   if [ $? -eq 0 ]; then LSPCI_INSTALLED=1; fi
  # fi
  # GPU_MODEL=""
  # if [ $LSPCI_INSTALLED -eq 1 ];
  # then
  #   GPU_MODEL=$(LANG=C lspci -v 2>/dev/null | grep ' VGA ' | cut -d" " -f 1 | xargs -i lspci -v -s {} | grep -E "Subsystem")
  #   # GPU_MODEL=${GPU_MODEL/Subsystem:/}
  #   GPU_MODEL=$(echo -n "${GPU_MODEL/Subsystem:/}" | xargs)
  # fi
  # ----------
  # Alternative B mit lshw
  if lshw &>/dev/null;
  then
    GPU_MODEL=$(LANG=C lshw -short 2>/dev/null | grep display | head -n 1)
    if [ $(echo ${GPU_MODEL} | grep -c -i "integrated") -gt 0 ];
    then
      GPU_MODEL="$(echo -n ${GPU_MODEL} | sed -E "s/(.*)(integrated\s.*)/\2/i" | xargs)"
    else
      GPU_MODEL=$(echo -n "${GPU_MODEL##*display}")
    fi
    GPU_MODEL=$(echo -n "${GPU_MODEL:0:32}" | xargs)
  fi

  # -------------------------
  # Memory-Angaben und Infos
  # -------------------------
  # Reservierter Platz im Hauptspeicher für Linux selbst und weitere Programme
  # (nur zur Berechnug von verfügbarem Platz für RAM Disk und temporäre Ordner)
  MIN_LINUX_RAM=$((3 * 1024 * 1024 * 1024)) # Vorgabe 3 GB
  # -------------------------
  # Mindestgröße des Speicherplatzes (MB), der rein rechnerisch nach Abzug des
  # zuvor reservierten Platzes für Linux und Programme verbleiben muss, um die
  # Erstellung einer RAM Disk durchführen zu können
  RAMDISK_MIN_SIZE=100 # Vorgabe 100 MB
  # -------------------------
  # Mindestgröße (MB), den die RAM Disk (/media/ramdisk) mindestens haben muss,
  # um die Verlagerung des Browser-Cache auf die RAM Disk durchführen zu können
  # ACHTUNG: Bei Änderung mit Skript "browser-cache-to-ram" abgleichen!
  BROWSER_CACHE_MIN_SIZE=400 # Vorgabe 400 MB
  # -------------------------
  if [ -f "/proc/meminfo" ];
  then
    MEMORY_TOTAL=$(grep -i -E "memtotal" "/proc/meminfo" 2>/dev/null)
    MEMORY_TOTAL=${MEMORY_TOTAL##*\:}
    if [ $(echo $MEMORY_TOTAL | grep -i -c -E "G") -gt 0 ];
    then
      MEMORY_TOTAL=$(echo -n "$MEMORY_TOTAL" | sed 's/\s*GB//i' | sed 's/\s*G//i' | xargs)
      MEMORY_TOTAL=$((MEMORY_TOTAL * 1024 * 1024 * 1024))
    else
      if [ $(echo $MEMORY_TOTAL | grep -i -c -E "M") -gt 0 ];
      then
        MEMORY_TOTAL=$(echo -n "$MEMORY_TOTAL" | sed 's/\s*MB//i' | sed 's/\s*M//i' | xargs)
        MEMORY_TOTAL=$((MEMORY_TOTAL * 1024 * 1024))
      else
        if [ $(echo $MEMORY_TOTAL | grep -i -c -E "K") -gt 0 ];
        then
          MEMORY_TOTAL=$(echo -n "$MEMORY_TOTAL" | sed 's/\s*KB//i' | sed 's/\s*K//i' | xargs)
          MEMORY_TOTAL=$((MEMORY_TOTAL * 1024))
        fi
      fi
    fi
    MEMORY_AVAIL=$(grep -i -E "memavail" "/proc/meminfo" 2>/dev/null)
    MEMORY_AVAIL=${MEMORY_AVAIL##*\:}
    if [ $(echo $MEMORY_AVAIL | grep -i -c -E "G") -gt 0 ];
    then
      MEMORY_AVAIL=$(echo -n "$MEMORY_AVAIL" | sed 's/\s*GB//i' | sed 's/\s*G//i' | xargs)
      MEMORY_AVAIL=$((MEMORY_AVAIL * 1024 * 1024 * 1024))
    else
      if [ $(echo $MEMORY_AVAIL | grep -i -c -E "M") -gt 0 ];
      then
        MEMORY_AVAIL=$(echo -n "$MEMORY_AVAIL" | sed 's/\s*MB//i' | sed 's/\s*M//i' | xargs)
        MEMORY_AVAIL=$((MEMORY_AVAIL * 1024 * 1024))
      else
        if [ $(echo $MEMORY_AVAIL | grep -i -c -E "K") -gt 0 ];
        then
          MEMORY_AVAIL=$(echo -n "$MEMORY_AVAIL" | sed 's/\s*KB//i' | sed 's/\s*K//i' | xargs)
          MEMORY_AVAIL=$((MEMORY_AVAIL * 1024))
        fi
      fi
    fi
  else
    MEMORY_TOTAL=0
    MEMORY_AVAIL=0
  fi

  # -------
  # Kernel
  # -------
  CURRENT_KERNEL_NAME="$(uname -r)"
  CURRENT_KERNEL_VERSION="$(echo ${CURRENT_KERNEL_NAME} | sed -E 's/([\.0-9\-]*).*/\1/' | sed -E 's/\-$//')"

  #----------------
  # Betriebssystem
  #----------------
  IS_PIOS=0
  OS_V_CODENAME=""
  OS_U_CODENAME=""
  if [ -s '/etc/os-release' ];
  then
    OS_NAME=$(grep -i -E "^NAME\s*=" "/etc/os-release")
    OS_NAME=$(echo -n "${OS_NAME##*\=}" | xargs)

    OS_VERSION=$(grep -i -E "^VERSION\s*=" "/etc/os-release")
    OS_VERSION=$(echo -n "${OS_VERSION##*\=}" | xargs)

    OS_V_CODENAME=$(grep -i -E "^VERSION_CODENAME\s*=" "/etc/os-release" | cut -d'"' -f 2 | cut -d'"' -f 1)
    OS_V_CODENAME=$(echo -n "${OS_V_CODENAME##*\=}" | xargs)

    OS_U_CODENAME=$(grep  -i -E "^UBUNTU_CODENAME\s*=" "/etc/os-release" | cut -d'"' -f 2 | cut -d'"' -f 1)
    OS_U_CODENAME=$(echo -n "${OS_U_CODENAME##*\=}" | xargs)

    OS_PRETTY_NAME=$(grep -i -E "^PRETTY_NAME\s*=" "/etc/os-release")
    OS_PRETTY_NAME=$(echo -n "${OS_PRETTY_NAME##*\=}" | xargs)

    OPERATION_SYSTEM="$OS_NAME $OS_VERSION"

    IS_PIOS=$(grep -i -c -E "Raspberry Pi OS" "/etc/os-release")
  fi

  # Weiterer Test ob Pi OS
  if [ $IS_PIOS -eq 0 ];
  then
    IS_PIOS=$(LANG=C systemctl 2>/dev/null | grep -i -E "Raspberry Pi" | grep -i -c "active")
  fi

  DEBIAN_CODE=""
  if [ -s "/etc/debian_version" ];
  then
    DEBIAN_CODE="$(cat /etc/debian_version)"
    DEBIAN_CODE="${DEBIAN_CODE%%/*}"
    TEST_CODE=$(echo "$DEBIAN_CODE" | sed 's/[^a-z]*//gi' | xargs)
    if [ "$TEST_CODE" == "" ];
    then
      DEBIAN_CODE="$OS_V_CODENAME"
    fi
    # Von LMDE eigene Namen anpassen an die zugrunde liegende Debian-Version
    if [ $(echo "$DEBIAN_CODE" | grep -i -c -E "faye") -gt 0 ]; then DEBIAN_CODE="bookworm"; fi
    # ----
  fi

  UBUNTU_VERSION=""
  DEBIAN_VERSION=""
  if [ "$OS_U_CODENAME" != "" ];
  then
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "bionic") -gt 0 ];   then UBUNTU_VERSION="18.04"; DEBIAN_VERSION="10"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "cosmic") -gt 0 ];   then UBUNTU_VERSION="18.10"; DEBIAN_VERSION="10"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "disco") -gt 0 ];    then UBUNTU_VERSION="19.04"; DEBIAN_VERSION="10"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "eoan") -gt 0 ];     then UBUNTU_VERSION="19.10"; DEBIAN_VERSION="10"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "focal") -gt 0 ];    then UBUNTU_VERSION="20.04"; DEBIAN_VERSION="11"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "groovy") -gt 0 ];   then UBUNTU_VERSION="20.10"; DEBIAN_VERSION="11"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "hirsute") -gt 0 ];  then UBUNTU_VERSION="21.04"; DEBIAN_VERSION="11"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "impish") -gt 0 ];   then UBUNTU_VERSION="21.10"; DEBIAN_VERSION="11"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "jammy") -gt 0 ];    then UBUNTU_VERSION="22.04"; DEBIAN_VERSION="12"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "kinetic") -gt 0 ];  then UBUNTU_VERSION="22.10"; DEBIAN_VERSION="12"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "lunar") -gt 0 ];    then UBUNTU_VERSION="23.04"; DEBIAN_VERSION="12"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "mantic") -gt 0 ];   then UBUNTU_VERSION="23.10"; DEBIAN_VERSION="13"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "noble") -gt 0 ];    then UBUNTU_VERSION="24.04"; DEBIAN_VERSION="13"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "oracular") -gt 0 ]; then UBUNTU_VERSION="24.10"; DEBIAN_VERSION="13"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "plucky") -gt 0 ];   then UBUNTU_VERSION="25.04"; DEBIAN_VERSION="13"; fi
    if [ $(echo "$OS_U_CODENAME" | grep -i -c -E "quokka") -gt 0 ];   then UBUNTU_VERSION="25.10"; fi
  fi

  if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -gt 0 ] &&
     [ "$DEBIAN_VERSION" == "" ];
  then
    # Von LMDE eigene Namen anpassen an die zugrunde liegende Debian-Version
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "faye") -gt 0 ]; then OS_V_CODENAME="bookworm"; fi
    # ----
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "buster") -gt 0 ];   then DEBIAN_VERSION="10"; fi
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "bullseye") -gt 0 ]; then DEBIAN_VERSION="11"; fi
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "bookworm") -gt 0 ]; then DEBIAN_VERSION="12"; fi
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "trixie") -gt 0 ];   then DEBIAN_VERSION="13"; fi
    if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "forky") -gt 0 ];    then DEBIAN_VERSION="14"; fi
  fi
  OS_BIT_WIDTH=$(getconf LONG_BIT) 2>/dev/null
  if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -eq 0 ] &&
     [ $(uname -a 2>/dev/null | grep -i -c -E "ubuntu") -eq 0 ];
  then
    IS_DEBIAN=0
  else
    IS_DEBIAN=1
  fi

  # ------------------------
  # Systemsprache ermitteln
  # ------------------------
  CUR_SYS_LANG=$(echo -n "${LANGUAGE:0:5}" | xargs)
  if [ "$CUR_SYS_LANG" == "" ];
  then
    CUR_SYS_LANG=$(echo -n "${LANG:0:5}" | xargs)
  fi
  CUR_LANG_NAME=$(locale -k LC_IDENTIFICATION 2>/dev/null | grep -i -E "language")
  CUR_LANG_NAME="${CUR_LANG_NAME##*=}"
  CUR_LANG_NAME=$(echo -n "${CUR_LANG_NAME//\"/}" | xargs)

  # ---------------------
  # Software-Architektur
  # ---------------------
  ARCHITECTURE_MAIN=$(dpkg --print-architecture)
  ARCHITECTURE_OTHER=$(dpkg --print-foreign-architectures)
  ARCHITECTURE_ALL="all|""$ARCHITECTURE_MAIN""|""$ARCHITECTURE_OTHER"

  # ----------------
  # Display-Manager
  # ACHTUNG: Dieser Wert unterscheidet sich je nach Aufruf mit oder ohne sudo!
  # ----------------
  DISPLAY_MANAGER="$(cat /etc/X11/default-display-manager 2>/dev/null)"
  DISPLAY_MANAGER="$(echo -n "${DISPLAY_MANAGER##*/}" | tr '[:upper:]' '[:lower:]')"

  # ---------------
  # Display-Server
  # ---------------
  DISPLAY_SERVER=""
  if loginctl &>/dev/null;
  then
    DISPLAY_SERVER=$(loginctl show-session 2>/dev/null $(loginctl --no-legend 2>/dev/null | awk '{print $1}') -p Type | cut -d "=" -f 2 | xargs 2>/dev/null)
  fi
  if [ "$DISPLAY_SERVER" == "" ];
  then
    DISPLAY_SERVER="$(env | grep -E -i 'x11|xorg|wayland' | cut -d'=' -f 2 | xargs 2>/dev/null)"
  fi
  if [ "$DISPLAY_SERVER" == "" ];
  then
    DISPLAY_SERVER=$(echo $XDG_SESSION_TYPE)
  fi
  # First Character upper case with awk (ucfirst ;)
  DISPLAY_SERVER="$(echo -n ${DISPLAY_SERVER} | sed -E "s/.*(x11|xorg|wayland).*/\1/gi" | awk '{print toupper(substr($0,0,1))tolower(substr($0,2))}')"

  # ----------------------------------------------------------------------------
  # Wenn kein Desktop installiert ist, entsprechende Komponenten überspringen
  # ----------------------------------------------------------------------------
  DESKTOP_INSTALLED=1
  if [ "$DISPLAY_MANAGER" == "" ] || [ "$DISPLAY_SERVER" == "Tty" ];
  then
    DESKTOP_INSTALLED=0
  fi

  TASKSEL_AVAILABLE=$(apt list "tasksel" -a 2>/dev/null | grep -i -E "tasksel" | grep -i -v -E "[0-9]snap" | grep -i -c -E "$ARCHITECTURE_ALL")
  MATE_DESKTOP_AVAILABLE=$(apt list "mate-desktop-environment" -a 2>/dev/null | grep -i -E "mate-desktop-environment" | grep -i -v -E "[0-9]snap" | grep -i -c -E "$ARCHITECTURE_ALL")

  DESKTOP_ENVIRONMENT=""
  WINDOW_MANAGER=""
  WINDOW_THEME=""
  SYMBOL_THEME=""
  if [ $DESKTOP_INSTALLED -gt 0 ];
  then

    # --------------------
    # Desktop-Environment
    # --------------------
    MAX_ENTRIES=0
    DESKTOP_NAMES=(Budgie Cinnamon Enlightment GNOME KDE Kylin labwc Lumina LXDE LXQT MATE Plasma Unity XFCE)
    for desktop_name in ${DESKTOP_NAMES[@]};
    do
      DESKTOP_ENTRIES=$(ps -def | \
                        sed -E "s/gnome\-(keyring|session|software|terminal)//gi" | \
                        sed -E "s/\s$desktop_name$//gi" | \
                        sed -E "s/sed\s\-E.*//gi" | \
                        grep -i -c -E "\/\b$desktop_name")
      if [ ${DESKTOP_ENTRIES} -gt ${MAX_ENTRIES} ];
      then
        MAX_ENTRIES=${DESKTOP_ENTRIES}
        DESKTOP_ENVIRONMENT=$desktop_name
      fi
    done
    if [ "$DESKTOP_ENVIRONMENT" == "" ];
    then
      DESKTOP_ENVIRONMENT="$(echo $DESKTOP_SESSION)"
    fi
    if [ "$DESKTOP_ENVIRONMENT" == "" ];
    then
      DESKTOP_ENVIRONMENT="$(echo $GDMSESSION)"
    fi
    DESKTOP_ENVIRONMENT="$(echo -n "$DESKTOP_ENVIRONMENT" | xargs)"
    if [ "$DESKTOP_ENVIRONMENT" == "GNOME" ] &&
      [ -s "/usr/share/gnome/gnome-version.xml" ];
    then
      GNOME_PLATFORM=$(grep -i -E "platform" "/usr/share/gnome/gnome-version.xml" | cut -d">" -f 2 | cut -d"<" -f 1 )
      GNOME_MINOR=$(grep -i -E "minor" "/usr/share/gnome/gnome-version.xml" | cut -d">" -f 2 | cut -d"<" -f 1 )
      GNOME_MICRO=$(grep -i -E "micro" "/usr/share/gnome/gnome-version.xml" | cut -d">" -f 2 | cut -d"<" -f 1 )
      GNOME_VERSION="$GNOME_PLATFORM.$GNOME_MINOR.$GNOME_MICRO"
      GNOME_PLATFORM=printf -v int '%d\n' "$GNOME_PLATFORM" 2>/dev/null
    fi

    # ---------------
    # Window-Manager
    # ---------------
    if xprop -version &>/dev/null;
    then
      X_WINDOW_ID=$(echo -n "$(xprop -root -notype)" | awk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}')
      X_WINDOW_ATTRIBS=$(xprop -id "${X_WINDOW_ID}" -notype -f _NET_WM_NAME 8t 2>/dev/null)
      WINDOW_MANAGER=$(echo -n "${X_WINDOW_ATTRIBS}" | grep -E "_NET_WM_NAME\s*=\s*")
      WINDOW_MANAGER="${WINDOW_MANAGER##*=}"
      WINDOW_MANAGER=$(echo -n "${WINDOW_MANAGER//\"/}" | xargs 2>/dev/null)
    fi

    # -------------
    # Window-Thema
    # -------------
    WINDOW_THEME="$(gsettings_get org.mate.interface gtk-theme)"
    if [ "$WINDOW_THEME" == "" ];
    then
      WINDOW_THEME="$(gsettings_get org.gnome.desktop.interface gtk-theme)"
    fi
    if [ "$WINDOW_THEME" == "" ];
    then
      if [ -s "$USER_HOME_DIR/.gtkrc-2.0" ];
      then
        WINDOW_THEME=$(grep -i -E "gtk-theme-name" "$USER_HOME_DIR/.gtkrc-2.0")
      fi
      if [ "$WINDOW_THEME" == "" ];
      then
        if [ -s "$USER_CONFIG_DIR/gtk-3.0/settings.ini" ];
        then
          WINDOW_THEME=$(grep -i -E "gtk-theme-name" "$USER_CONFIG_DIR/gtk-3.0/settings.ini")
        fi
      fi
    fi
    WINDOW_THEME=${WINDOW_THEME##*=}
    WINDOW_THEME=${WINDOW_THEME//\"/}
    WINDOW_THEME=${WINDOW_THEME//\'/}

    # -------------
    # Symbol-Thema
    # -------------
    SYMBOL_THEME="$(gsettings_get org.mate.interface icon-theme)"
    if [ "$SYMBOL_THEME" == "" ];
    then
      SYMBOL_THEME="$(gsettings_get org.gnome.desktop.interface icon-theme)"
    fi
    if [ -s "$USER_HOME_DIR/.gtkrc-2.0" ];
    then
      SYMBOL_THEME=$(grep -i -E "gtk-icon-theme-name" "$USER_HOME_DIR/.gtkrc-2.0")
    fi
    if [ "$SYMBOL_THEME" == "" ];
    then
      if [ -s "$USER_CONFIG_DIR/gtk-3.0/settings.ini" ];
      then
        SYMBOL_THEME=$(grep -i -E "gtk-icon-theme-name" "$USER_CONFIG_DIR/gtk-3.0/settings.ini")
      fi
    fi
    SYMBOL_THEME=${SYMBOL_THEME##*=}
    SYMBOL_THEME=${SYMBOL_THEME//\"/}
    SYMBOL_THEME=${SYMBOL_THEME//\'/}

  fi

  # -------------
  # Dateimanager
  # -------------
  FILEMAN_LIST="caja nemo thunar"
  FILE_MANAGER=""
  if xdg-mime --help &>/dev/null;
  then
    # DEFAULT_FILE_MIME="$(xdg-mime query default application/x-gnome-saved-search 2>/dev/null)"
    DEFAULT_FILE_MIME="$(xdg-mime query default inode/directory 2>/dev/null)"
    DEFAULT_FILE_DESK="$GLOBAL_STARTER_DIR/$DEFAULT_FILE_MIME"
    if [ -s "$DEFAULT_FILE_DESK" ];
    then
      MIME_FILE_MAN=$(grep -i -E "^\s*exec\s*=" "$DEFAULT_FILE_DESK" 2>/dev/null | head -n 1 | sed -E "s/^\s*exec\s*=//i" | cut -d' ' -f 1)
      MIME_FILE_MAN="${MIME_FILE_MAN##*/}"
      for filemanager in ${FILEMAN_LIST[@]};
      do
        if [ "$MIME_FILE_MAN" == "$filemanager" ];
        then
          FILE_MANAGER="$filemanager"
          break
        fi
      done
    fi
  fi

  # ------
  # Shell
  # ------
  SHELL_TEXT="$("${SHELL##*/}" --version)"
  SHELL_TEXT=$(echo -n "${SHELL_TEXT%%(*}")
  SHELL_TEXT=$(echo -n "${SHELL_TEXT:0:64}" | xargs)

  # -----
  # Wine
  # -----

  WINE_VERSION=""
  WINE_VERSION_APT=""
  WINE_VERSION_FLAT=""
  if [ $(LANG=C dpkg-query -W -f='${Status}' "wine" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
  then
    WINE_VERSION_APT="$(wine --version 2>/dev/null | cut -d" " -f 1 | cut -d "-" -f 2 | xargs 2>/dev/null)"
    if [ "$WINE_VERSION_APT" != "" ];
    then
      WINE_VERSION+="$WINE_VERSION_APT (STD)"
    fi
  fi
  if [ $FLATPAK_ACTIVE -eq 1 ];
  then
    WINE_VERSION_FLAT="$(flatpak list --columns=name,version,ref | grep -i -E "^Wine[0-9]*\s+[0-9]" | tail -n 1 | cut -f 2 | xargs 2>/dev/null)"
    if [ "$WINE_VERSION_FLAT" != "" ];
    then
      if [ "$WINE_VERSION" != "" ]; then WINE_VERSION+=" + "; fi
      WINE_VERSION+="$WINE_VERSION_FLAT (FLAT)"
    fi
  fi

  ANZ_SOURCE_ENTRIES=0
  if [ -s "$APT_SOURCES_LIST_FILE" ];
  then
    # --------------------------------------------------------------------------
    # Ermittlung der Anzahl von Paket-Quellen in der Datei sources.list
    # --------------------------------------------------------------------------
    ANZ_SOURCE_ENTRIES=$(grep -i -E "^\s*deb\s" "$APT_SOURCES_LIST_FILE" 2>/dev/null | grep -i -v "security" | wc -l)
    # --------------------------------------------------------------------------
    # Deaktivieren von CD/DVD als Haupt-Paketquelle (alle zu installierenden
    # Pakete werden ausschließlich immer aktuell aus dem Internet geladen!)
    # --------------------------------------------------------------------------
    if [ $(grep -i -c -E "^\s*deb\s\s*cdrom" "$APT_SOURCES_LIST_FILE" 2>/dev/null) -gt 0 ];
    then
      echo -e ""
      echo -e -n " Deaktiviere CD/DVD als Paketquelle ... "
      create_backup_file "$APT_SOURCES_LIST_FILE"
      sed -i -E "s/^\s*deb\s\s*cdrom/# deb cdrom/gi" "$APT_SOURCES_LIST_FILE"
      if [ $? -eq 0 ];
      then
        echo -e "$OK_TAG"
      else
        echo -e "$ERROR_TAG"
      fi
    fi
  fi

  # ----------------------------------------------------------------------------
  # Ermittlung der Anzahl von Paket-Quellen in dem Ordner sources.list.d
  # ----------------------------------------------------------------------------
  ANZ_SOURCE_FILES=0
  if [ -d "$APT_SOURCES_LIST_DIR" ];
  then
    ANZ_SOURCE_FILES=$(ls -A "$APT_SOURCES_LIST_DIR" 2>/dev/null | grep -i -v "readme" | wc -w)
  fi
  # ----------------------------------------------------------------------------
  # Falls keine Paketquellen gefunden wurden, anbieten diese zu ergänzen
  # ----------------------------------------------------------------------------
  if [ $ANZ_SOURCE_ENTRIES -eq 0 ] &&
     [ $ANZ_SOURCE_FILES -eq 0 ];
  then
    echo -e ""
    echo -e ""
    echo -e " $ERROR_TAG: Es wurden keine aktiven Quellangaben zur Installation"
    echo -e " von Paketen gefunden. Bitte konfiguriere erst die gewünschten"
    echo -e " Quellen und starte $SCRIPT_NAME dann neu."
    # ----------------------------------------------------------------------
    # Für reine Debian-Systeme anbieten einen Standard-Eintrag zu erstellen
    # ----------------------------------------------------------------------
    if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -gt 0 ] &&
       [ "$OS_V_CODENAME" != "" ];
    then
      echo -e ""
      ask_yes_or_no_pure " Soll ich jetzt einen Standard-Eintrag erstellen"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Erstelle Standard-Eintrag für Paketquelle ... "
        # ---------------------
        # apt-Ordner erstellen
        # ---------------------
        if [ ! -d "$APT_SOURCES_MAIN_DIR" ];
        then
          mkdir -p "$APT_SOURCES_MAIN_DIR" &>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "root:root" "$APT_SOURCES_MAIN_DIR" &>/dev/null
            chmod -R 0755 "$APT_SOURCES_MAIN_DIR" &>/dev/null
          fi
        fi
        # ----------------
        # Datei erstellen
        # ----------------
        if [ -d "$APT_SOURCES_MAIN_DIR" ];
        then
          echo -e "deb http://deb.debian.org/debian/ $OS_V_CODENAME main non-free-firmware non-free contrib" >> "$APT_SOURCES_LIST_FILE" 2>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "root:root" "$APT_SOURCES_LIST_FILE" &>/dev/null
            chmod -R 0644 "$APT_SOURCES_LIST_FILE" &>/dev/null
            e_and_l "$OK_TAG"
            repo_update " Aktualisiere das Repository, bitte warten ... "
          else
            e_and_l "$ERROR_TAG"
          fi
        else
          e_and_l "$ERROR_TAG"
        fi
      fi
    fi
    exit 0
  fi

fi

# ==============================================================================
# Listen zur Auswahl der Kategorien definieren
# HINWEIS: Bei Änderungen auch alle Verbindungen mit CURRENT_CATEGORY und
#          Prüfungen auf KATEGORIE_FLAG anpassen!
# ==============================================================================
declare -A KATEGORIE_FLAG # Kategorie ausgewählt (1) oder nicht (0)
declare -A KATEGORIE_TEXT # Angezeigte Bezeichnung der Kategorie
declare -A KATEGORIE_PKGS # Liste mit den in der Kategorie enthaltenen Paketen

#---------------------------
# Alphabetische Reihenfolge
#---------------------------
KAT_KEYS_STD=(a b c d e f fo g i m n p q r s t u v w wg x xx z)
KAT_KEYS_ADD=(ci gx lx mt mx xf)
KAT_KEY_LIST=( ${KAT_KEYS_STD[@]} ${KAT_KEYS_ADD[@]} )
#--------------------------------------
# Reihenfolge der Verarbeitung im Menü
#--------------------------------------
KAT_ORD_LIST=(x v b i m g t z s w e a d f q c p wg u n r xx fo xlinex mt ci gx lx mx xf)

# --- CATEGORIES START ---
KATEGORIE_TEXT[a]="WEB-Server (Apache und PHP)"
KATEGORIE_TEXT[b]="Büro (Office, Publishing, E-Book- und PDF-Tools)"
KATEGORIE_TEXT[c]="Cloud-Clients (Clients für Online-Datenspeicher)"
KATEGORIE_TEXT[ci]="Cinnamon Tools (Erweiterungen für Cinnamon-Desktop)"
KATEGORIE_TEXT[d]="SMB-Server (Datei- und Druckerfreigaben / Samba)"
KATEGORIE_TEXT[e]="Entwicklung (Programmier-Werkzeuge und Editoren)"
KATEGORIE_TEXT[f]="FTP-Server (ProFTPD)"
KATEGORIE_TEXT[fo]="Forensik-Pakete (Umfangreiche Sammlung nur für Experten)"
KATEGORIE_TEXT[g]="Grafik (Bild/Foto-Bearbeitung, Vektor-Grafik, Scanner)"
KATEGORIE_TEXT[gx]="GNOME Apps (Erweiterungen für GNOME-Desktop, ohne Spiele)"
# h
KATEGORIE_TEXT[i]="Internet (Browser, Chat, Mail, Remote-Control, F-Transfer)"
# j
# k
# l
KATEGORIE_TEXT[lx]="LXDE Tools (Erweiterungen für LXDE-Desktop)"
KATEGORIE_TEXT[m]="Multimedia (TV/Media-Player, Video-Schnitt und Konverter)"
KATEGORIE_TEXT[mt]="Mint Tools (Erweiterungen für Linux Mint)"
KATEGORIE_TEXT[mx]="MATE Tools (Erweiterungen für MATE-Desktop)"
KATEGORIE_TEXT[n]="Netzwerkmanagement (Analyse und Konfiguration)"
# o
KATEGORIE_TEXT[p]="Private Netzwerkverbindungen (OpenConnect, OpenVPN, VPNC)"
KATEGORIE_TEXT[q]="Emulation und Virtualisierung (Docker, KVM, QEMU, VBox)"
KATEGORIE_TEXT[r]="Systemreparatur (Tools zur Sicherung & Wiederherstellung)"
KATEGORIE_TEXT[s]="Spiele (Michael's Auswahl)"
KATEGORIE_TEXT[t]="Tonstudio (Audio-Bearbeitung und Musikproduktion)"
KATEGORIE_TEXT[u]="USB-Firewall (Selektives Zulassen von USB-Geräten)"
KATEGORIE_TEXT[v]="Systemverwaltung (Hilfsprogramme mit Benutzeroberfläche)"
KATEGORIE_TEXT[w]="Windows API (DOSBox, Wine, Wine-Tools und PlayOnLinux)"
KATEGORIE_TEXT[wg]="WireGuard (VPN Tunnel)"
KATEGORIE_TEXT[x]="Systemergänzungen (Systemmodule und CLI-Systemprogramme)"
KATEGORIE_TEXT[xf]="XFCE Tools (Erweiterungen für XFCE-Desktop)"
KATEGORIE_TEXT[xx]="Systemerweiterungen (CLI-Programme für Administratoren)"
# y
KATEGORIE_TEXT[z]="Zubehör (Datei-Manager, Packer und diverse Desktop-Tools)"
# --- CATEGORIES END ---

# ==============================================================================
# Status des Kernel-Lockings ermitteln
# ==============================================================================
IFS=$'\n'
KERNEL_PACKS=($(apt list -a "linux-*" 2>/dev/null | grep -i -E "^linux\-(generic|headers|image|signed)" | grep -i -E "nstall" | cut -d'/' -f1))
IFS=' '
KERNEL_IS_LOCKED=0
for kp in "${KERNEL_PACKS[@]}";
do
  if [ $(apt-mark showhold 2>/dev/null | grep -c -i -E "$kp.*") -gt 0 ];
  then
    ((KERNEL_IS_LOCKED+=1))
  fi
done

# ==============================================================================
# Listen zur Auswahl der Optionen definieren
# ==============================================================================
declare -A OPTION_FLAG # Option ausgewählt (1) oder nicht (0)
declare -A OPTION_TEXT # Angezeigte Bezeichnung der Option
declare -A OPTION_MENU # Index des Menüpunktes, in dem die Option erscheint

OPTION_LIST=()
OPTION_LIST+=(extends addflat addsnap external prioflat priosnap skipsims esamesrc foreign force status listonly addstart csubdirs) # Menu 2
OPTION_LIST+=(exupdate desktop extras kuplock kunlock setutc optimize snapcont snapkill snapstop revive repair cleansys personal sysbench) # Menu 4
OPTION_LIST+=(noupdate norepo autoyorn notoall skipmesg exupdall infoonly noinfo log logfull nocolor saveconf reset cleantmp) # Menu 5
OPTION_LIST+=(dsave dload quiet instonly instlist remove) # Im Menü nicht angezeigt aber zu initialisieren

OPTION_TEXT[addflat]="Flatpak-Pakete auswählbar und installierbar machen"
OPTION_TEXT[addsnap]="Snap-Pakete auswählbar und installierbar machen"
OPTION_TEXT[addstart]="Starter (Desktop-Symbole) für Paketauswahl erstellen"
OPTION_TEXT[autoyorn]="Fragen automatisch gemäß letztem Durchlauf beantworten"
OPTION_TEXT[cleansys]="Bereinigung von veralteten und verwaisten Daten"
OPTION_TEXT[cleantmp]="Alle temporären Dateien bei Programmende löschen"
OPTION_TEXT[csubdirs]="Starter für Spiele in Unterordnern kategorisieren"
OPTION_TEXT[desktop]="Grafische Benutzeroberfläche (Desktop) installieren"
OPTION_TEXT[dload]="Gespeicherte Desktop-Einstellungen laden (dconf)"
OPTION_TEXT[dsave]="Aktuelle Desktop-Einstellungen speichern (dconf)"
OPTION_TEXT[esamesrc]="Erweiterungs-Pakete nur aus gleicher Quelle installieren"
OPTION_TEXT[extends]="Repository um individuelle Pakete und PPAs erweitern"
OPTION_TEXT[external]="Programme zum Download aus externen Quellen hinzufügen"
OPTION_TEXT[extras]="Extras (zus. Systemkomponenten und Treiber) installieren"
OPTION_TEXT[exupdate]="Programmpakete aus externen Quellen aktualisieren"
OPTION_TEXT[exupdall]="Updates für externe Pakete auch aus anderen Quellen"
OPTION_TEXT[force]="Ja/Nein-Abfrage vor jeder Installation überspringen"
OPTION_TEXT[foreign]="Auch Pakete für Fremd-Architekturen installieren"
OPTION_TEXT[infoonly]="Nur Systeminformationen anzeigen (sonst nichts tun)"
OPTION_TEXT[instonly]="Ein einzelnes Programmpaket installieren"
OPTION_TEXT[kuplock]="Aktualisierungen (Updates) des Kernels blockieren"
OPTION_TEXT[kunlock]="Aktualisierungs-Blockade des Kernels entfernen"
OPTION_TEXT[listonly]="Nur Pakete je Kategorie auflisten (sonst nichts tun)"
OPTION_TEXT[log]="Einfache Log-Datei der wichtigsten Aktionen erstellen"
OPTION_TEXT[logfull]="Vollständige Log-Datei aller Aktionen erstellen"
OPTION_TEXT[nocolor]="Textausgabe im Terminal mit weniger Farben anzeigen"
OPTION_TEXT[noinfo]="Systeminformationen am Anfang nicht anzeigen"
OPTION_TEXT[norepo]="Standard-Repository beim Start nicht aktualisieren"
OPTION_TEXT[notoall]="Alle Abfragen automatisch mit Nein beantworten"
OPTION_TEXT[noupdate]="Nicht nach Updates für dieses Skript suchen"
OPTION_TEXT[optimize]="Diverse Optimierungen des Systems durchführen"
OPTION_TEXT[personal]="Persönliche Einstellungen vom Server laden"
OPTION_TEXT[prioflat]="Bei Verfügbarkeit automatisch Flatpak-Paket auswählen"
OPTION_TEXT[priosnap]="Bei Verfügbarkeit automatisch SNAP-Paket auswählen"
OPTION_TEXT[quiet]="DERZEIT NICHT VERWENDET!"
OPTION_TEXT[remove]="Ein Programmpaket und zugehörige Daten löschen"
OPTION_TEXT[repair]="Reparatur von Bootloader, Dateisystem und Paketverwaltung"
OPTION_TEXT[reset]="Alle benutzerspezifischen Einstellungen löschen"
OPTION_TEXT[revive]="Reaktivierung vormals deaktivierter Komponenten"
OPTION_TEXT[saveconf]="Einstellungen für nächsten Aufruf speichern"
OPTION_TEXT[setutc]="Systemzeit auf Universal Time Coordinated umstellen"
OPTION_TEXT[skipmesg]="Bei wichtigen Hinweisen nicht auf Bestätigung warten"
OPTION_TEXT[skipsims]="Alternative Pakete nicht anzeigen und installieren"
OPTION_TEXT[snapcont]="Die Snap-Paketverwaltung wieder reaktivieren"
OPTION_TEXT[snapkill]="Die Snap-Paketverwaltung deaktivieren oder entfernen"
OPTION_TEXT[snapstop]="DERZEIT NICHT IM MENÜ, WIRD MIT snapkill ANGESTEUERT"
OPTION_TEXT[status]="Nur Status der Pakete anzeigen (nicht installieren)"
OPTION_TEXT[sysbench]="Referenzwerte dieses Systems erstellen (Benchmarking)"

OPTION_MENU[quiet]=0    # Wird im Menü nicht angezeigt
OPTION_MENU[instonly]=1 # Nur zur Anzeige im Menü, Prüfung erfolgt auf INST_ONLY_PKG
OPTION_MENU[instlist]=0 # Wird nicht verwendet, Prüfung erfolgt auf INST_LIST_FILE

OPTION_MENU[addstart]=2
if [ "$DESKTOP_ENVIRONMENT" == "GNOME" ];
then
  OPTION_MENU[csubdirs]=0
else
  OPTION_MENU[csubdirs]=2
fi
OPTION_MENU[addflat]=2
OPTION_MENU[addsnap]=2
OPTION_MENU[esamesrc]=2
OPTION_MENU[extends]=2
OPTION_MENU[external]=2
OPTION_MENU[force]=2
OPTION_MENU[foreign]=2
OPTION_MENU[listonly]=2
OPTION_MENU[prioflat]=2
OPTION_MENU[priosnap]=2
OPTION_MENU[skipsims]=2
OPTION_MENU[status]=2

OPTION_MENU[remove]=3 # Wird nicht tatsächlich verwendet, Prüfung erfolgt auf REMOVE_PKG_NAME

OPTION_MENU[cleansys]=4
# Die Option Desktop nur auswählbar machen, wenn tasksel zur Verfügung steht,
# oder der MATE-Desktop noch nicht installiert ist, aber zur Verfügung steht
if [ $TASKSEL_AVAILABLE -gt 0 ] ||
   [[ "$DESKTOP_ENVIRONMENT" != "MATE" && $MATE_DESKTOP_AVAILABLE -gt 0 ]];
then
  OPTION_MENU[desktop]=4
else
  OPTION_MENU[desktop]=0
fi
OPTION_MENU[dload]=0 # Derzeit nicht im Menü angeboten
OPTION_MENU[dsave]=0 # Derzeit nicht im Menü angeboten
OPTION_MENU[extras]=4
OPTION_MENU[exupdate]=4
if [ $KERNEL_IS_LOCKED -eq 0 ];
then
  OPTION_MENU[kuplock]=4
  OPTION_MENU[kunlock]=0
else
  OPTION_MENU[kuplock]=0
  OPTION_MENU[kunlock]=4
fi
OPTION_MENU[optimize]=4
OPTION_MENU[personal]=4
OPTION_MENU[repair]=4
OPTION_MENU[revive]=4
OPTION_MENU[setutc]=0
if timedatectl &>/dev/null;
then
  if [ $(LANG=C timedatectl show 2>/dev/null | grep -c -i -E "^\s*LocalRTC\s*=\s*yes") -gt 0 ];
  then
    OPTION_MENU[setutc]=4
  fi
fi
OPTION_MENU[sysbench]=4

# ----------------------------------------------------------------
# Optionen zur Snap-Paketverwaltung je nach deren Status anzeigen
# ----------------------------------------------------------------
OPTION_MENU[snapcont]=0
OPTION_MENU[snapkill]=0
OPTION_MENU[snapstop]=0
# Wenn Snap AKTIV ist, dann Optionen zur Deaktivierung und Entfernung anbieten
# (wird gemeinsam über snapkill angesteuert und erst später als Auswahl beider
# Optionen angeboten, so dass snapstop hier im Menü nicht angezeigt wird).
# Wenn Snap INAKTIV ist, dann nur Optionen zur Reaktivierung anbieten.
if [ $SNAP_INSTALLED -gt 0 ];
then
  if [ $SNAP_ACTIVE -gt 0 ];
  then
    OPTION_MENU[snapkill]=4
  else
    OPTION_MENU[snapcont]=4
  fi
fi
# ----------------------------------------------------------------

if [ ${#AUTO_ANSWERS[@]} -gt 0 ];
then
  OPTION_MENU[autoyorn]=5
else
  OPTION_MENU[autoyorn]=0
fi
OPTION_MENU[cleantmp]=5
OPTION_MENU[exupdall]=5
OPTION_MENU[infoonly]=5
OPTION_MENU[log]=5
OPTION_MENU[logfull]=5
OPTION_MENU[nocolor]=5
OPTION_MENU[noinfo]=5
OPTION_MENU[norepo]=5
OPTION_MENU[notoall]=5
OPTION_MENU[noupdate]=5
OPTION_MENU[reset]=5
OPTION_MENU[saveconf]=5
OPTION_MENU[skipmesg]=5

# ==============================================================================
# Paket-Listen definieren (Kategorisierte Listen von Programmpaketen)
# ------------------------------------------------------------------------------
# HINWEIS: Wenn vor oder nach einem Paket automatisch auch weitere Pakete
# installiert werden sollen, können diese in AUTO_ADD_PKGS angegeben werden!
# ------------------------------------------------------------------------------
# Sollen aus irgendeinem Grund Flatpak-, Snap- oder externe Pakete bevorzugt
# werden, dann können diese in FORCE_FLATPAK_LIST, FORCE_SNAPPY_LIST und
# FORCE_EXTERN_LIST eingetragen werden.
# ------------------------------------------------------------------------------
# In Namen von Flatpak-Paketen Leerzeichen durch Unterstrich ersetzen!
# ==============================================================================
# ------------------------------------------------------------------------------
# Apache und PHP (Webserver)- mit vielen PHP-Modulen in aktueller Version ;)
# ------------------------------------------------------------------------------
PHP_VERSION=$(LANG=C apt show "php" 2>/dev/null | grep -i -E "depends\:\s*")
PHP_VERSION=$(echo -n "${PHP_VERSION##* }" | xargs)
KATEGORIE_PKGS[a]="apache2 php libapache2-mod-php"
PHP_MODULES=(bcmath cli curl dev gd imap intl mbstring mysql opcache readline soap sqlite3 xml xmlrpc zip)
if [ "$PHP_VERSION" != "" ];
then
  for php_mod_name in ${PHP_MODULES[@]};
  do
    KATEGORIE_PKGS[a]+=" $PHP_VERSION-$php_mod_name"
  done
fi
# ------------------------------------------------------------------------------
# Büro
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[b]="bookletimposer calibre evolution libreoffice okular pdfarranger pdfchain pdfmod qpdfview scribus texstudio"
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]; then KATEGORIE_PKGS[b]+=" thingy xreader"; fi
# ------------------------------------------------------------------------------
# Cloud-Clients
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[c]="owncloud-client nextcloud-desktop onedrive rclone-browser"
# ------------------------------------------------------------------------------
# Datei- und Druckerfreigaben (Samba)
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[d]="samba"
# ------------------------------------------------------------------------------
# Entwicklung
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[e]="bless closure-compiler codium geany ghex idle kate kdiff3 kompare meld mu-editor python3 scratch thonny"
# ------------------------------------------------------------------------------
# FTP-Server
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[f]="proftpd-core"
# ------------------------------------------------------------------------------
# Forensik
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[fo]="forensics-full forensics-samples-all"
# ------------------------------------------------------------------------------
# Grafik
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[g]="blender darktable digikam drawing eom fraqtive freecad geeqie gimp gpicview gpick gwenview imagemagick inkscape krita mandelbulber2 mtpaint pinta rawtherapee shotwell simple-scan xnview"
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]; then KATEGORIE_PKGS[g]+=" pix xviewer"; fi
# ------------------------------------------------------------------------------
# Internet
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[i]="anydesk chromium element filezilla firefox hexchat microsoft-edge-stable opera rdesktop realvnc-vnc-server realvnc-vnc-viewer remmina rustdesk teamviewer telegram thunderbird tor-browser transmission virt-viewer x11vnc"
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]; then KATEGORIE_PKGS[i]+=" warpinator webapp-manager"; fi
# ------------------------------------------------------------------------------
# Multimedia
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[m]="asunder celluloid cheese easytag freetuxtv gnome-sound-recorder gthumb gtkpod handbrake hypnotix iptvnator k3b kdenlive kid3 kodi lame makemkv-bin mediainfo mixxx mkvtoolnix mpv mp3splt obs-studio openshot parole peek rhythmbox shotcut smplayer vlc webcamoid yt-dlp youplay"
# ------------------------------------------------------------------------------
# Netzwerkmanagement
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[n]="gnome-nettool gufw ipscan linssid nmapsi4 opensnitch packetsender putty wireshark zenmap"
# ------------------------------------------------------------------------------
# Private Netzwerkverbindungen
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[p]="dnsmasq openconnect openvpn vpnc vpnc-scripts"
# ------------------------------------------------------------------------------
# Emulation und Virtualisierung
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[q]="docker.io qemu-system-common qemu-system-data qemu-system-x86 qemu-system-arm qemu-system-gui qemu-efi-aarch64 qemu-efi-arm qemu-utils qemu-block-extra libvirt-daemon-system libvirt-clients bridge-utils virt-manager"
if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -gt 0 ] &&
   [ $(echo "$OS_V_CODENAME" | grep -i -c -E "bookworm") -gt 0 ];
then
  KATEGORIE_PKGS[q]+=" virtualbox-7.1"
  # Externes Paket => Extension-Pack wird per POST_INST_CONF nachinstalliert
else
  KATEGORIE_PKGS[q]+=" virtualbox"
  # Repo => Extensions siehe AUTO_ADD_PKGS
fi
# ------------------------------------------------------------------------------
# Systemreparatur (Sicherung und Wiederherstellung)
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[r]="backintime boot-repair grsync grub-customizer rescuezilla"
# Ohne MINT Timeshift mit in Kategorie Sicherung und Wiederherstellung
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -eq 0 ]; then KATEGORIE_PKGS[r]+=" timeshift"; fi
# ------------------------------------------------------------------------------
# Spiele
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[s]="0ad alienarena armagetronad atomix billard-gl biniax2 blockout2 briquolo brutalchess caveexpress code-the-classics criticalmass cuyo dreamchess endless-sky enigma extremetuxracer flightgear flobopuyo foobillardplus freedoom freedroidrpg freegish freetennis frogatto frozen-bubble fs-uae gbrainy gcompris gemdropx gnome-games gnome-mastermind gnubg gweled jag kapman katomic kdiamond kmahjongg knights kpat kreversi ksudoku lbreakouthd lix marsshooter megaglest morris naev neverball neverputt nexuiz numptyphysics oolite openarena openclonk open-invaders peg-e pinball pingus pokerth pybik quetoo rocksndiamonds sauerbraten sdl-ball speed_dreams steam stunt_rally supertux supertuxkart teeworlds tesseract torcs trackballs trigger-rally tuxmath ufoai wesnoth widelands xonotic ysoccer zaz"
# ------------------------------------------------------------------------------
# Tonstudio
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[t]="ardour audacity hydrogen lmms qjackctl qtractor yoshimi zynaddsubfx"
# ------------------------------------------------------------------------------
# USB-Firewall
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[u]="usbauth"
# ------------------------------------------------------------------------------
# Systemverwaltung (Hilfsprogramme mit Benutzeroberfläche)
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[v]="baobab bleachbit blueman cpu-x czkawka dconf-editor deja-dup filelight font-manager gdebi gnome-disk-utility gnome-software gparted gsmartcontrol gtkhash hardinfo isomaster kleopatra metadata-cleaner mozo qt5ct seahorse stacer synaptic system-config-printer tilda usbview xfce4-taskmanager"
if [ "$DESKTOP_ENVIRONMENT" == "KDE" ] ||
   [ "$DESKTOP_ENVIRONMENT" == "Plasma" ];
then
  KATEGORIE_PKGS[v]=" plasma-discover"
fi
# -------------------------------------------------------------------------
# Basispaket des vorinstallierten Dateimanagers hinzufügen, damit auch die
# zugehörigen Erweiterungen der AUTO_ADD_PKGS mit aufgenommen werden
# -----------------------------------------------------------
# Achtung: Die Liste FILEMAN_LIST wird weiter oben definiert
# -------------------------------------------------------------------------
for filemanager in ${FILEMAN_LIST[@]};
do
  if [ $(LANG=C dpkg-query -W -f='${Status}' "$filemanager" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ] ||
     [ "$FILE_MANAGER" == "$filemanager" ];
  then
    KATEGORIE_PKGS[v]+=" $filemanager"
  fi
done
# ------------------------------------------------
# Ggf. Einstellungen für lightdm-Login hinzufügen
# ------------------------------------------------
if [ -d "$LDM_CONF_DIR" ];
then
  KATEGORIE_PKGS[v]+=" lightdm-settings"
  if [ -s "$LDM_CONF_DIR/lightdm-gtk-greeter.conf" ];
  then
    KATEGORIE_PKGS[v]+=" lightdm-gtk-greeter-settings"
  fi
fi
# -------------------------------------------
# Ggf. vorinstallierte Mint-Tools hinzufügen
# -------------------------------------------
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ];
then
  KATEGORIE_PKGS[v]+=" bulky timeshift"
fi
# --------------------------------------------------------------------
# Ggf. Flatpak-Tools hinzufügen
# (s.a. AUTO_ADD_PKGS mit flatpak-Erweiterungen für bestimmte Pakete)
# --------------------------------------------------------------------
if [ $FLATPAK_ACTIVE -eq 1 ];
then
  KATEGORIE_PKGS[v]+=" flatseal"
fi
# ------------------------------------------------------------------------------
# Windows-API "Wine"
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[w]="dosbox"
# -----------------------------------------------------
# Wenn es den WINE-Installer gibt und WINE noch nicht
# installiert wurde, diesen statt WINE selbst anzeigen
# HINWEIS: Siehe auch AUTO_ADD_PKGS[wine]
# -----------------------------------------------------
if [ $(apt list "wine-installer" 2>/dev/null | grep -i -c -E "wine-installer") -gt 0 ] &&
   [ $(LANG=C dpkg-query -W -f='${Status}' "wine" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
then
  KATEGORIE_PKGS[w]+=" wine-installer winetricks"
else
  KATEGORIE_PKGS[w]+=" wine"
fi
KATEGORIE_PKGS[w]+=" playonlinux"
# ------------------------------------------------------------------------------
# WireGuard
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[wg]="wireguard wireguard-tools"
# ------------------------------------------------------------------------------
# Systemergänzungen (Bibliotheken & CLI-Systemprogramme)
# ------------------------------------------------------------------------------
# Standard Debian
# ----------------
KATEGORIE_PKGS[x]="bc btrfs-progs busybox bzip2 console-setup curl dconf-cli diffutils dirmngr dosfstools e2fsprogs eject exfatprogs fdisk ffmpegthumbnailer file gdisk gpg gvfs-backends gzip keyboard-configuration less libaacs0 libbluray2 libfuse2 libnss-myhostname libpam-systemd locales lshw lsof manpages nano network-manager ntfs-3g p7zip-full pciutils sane-utils sed tar unzip util-linux wpasupplicant xfsprogs xz-utils zip zstd"
# ---------------------
# Ergänzungen für alle
# ---------------------
KATEGORIE_PKGS[x]+=" apturl arj calc ccd2iso cifs-utils cryptsetup debsums ethtool exfat-fuse fail2ban firejail ftp gddrescue git hashdeep heif-gdk-pixbuf heif-thumbnailer htop hwinfo iat iftop img2pdf info inxi iotop jfsutils lftp lhasa libbluray-bdj libbluray-bin libdvd-pkg lrzip lz4 lzip lzop mtools ncompress neofetch net-tools numlockx openssh-client openssh-server plocate qpdf rsync rzip screen sharutils smartmontools smbclient sqlite3 sshguard systemd-resolved traceroute tree udftools ufw units usbutils wget whois zenity"
# ---------------------
# Ergänzungen für MINT
# ---------------------
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]; then KATEGORIE_PKGS[x]+=" lsb mint-meta-codecs"; fi
# ------------------------------------------------------------------------------
# Systemerweiterungen (CLI-Programme für Administratoren)
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[xx]="alien apt-file apt-rdepends apt-show-versions arping arp-scan bash-completion bash-doc chntpw clonezilla cpu-checker debootstrap dpkg-repack efibootmgr elinks extundelete f3 flashrom gpart growisofs hdparm hexedit iwatch kpartx memtester menu msr-tools netcat-traditional nfacct nmap nvme-cli partclone partimage pdfcrack pdfresurrect ppa-purge rfkill strace stress stress-ng stressapptest sysbench sysfsutils sysstat tcpdump tcptrack testdisk udpcast xorriso xsltproc"
# ------------------------------------------------------------------------------
# Zubehör
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[z]="balena-etcher barrier bitwarden clamav copyq doublecmd electrum engrampa file-roller freefilesync galculator gedit gnome-weather gucharmap kdeconnect keepassxc kfind klavaro ksnip ktouch magnus mousepad onboard plank pluma redshift rpi-imager unetbootin usb-creator-common veracrypt xournal"
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]; then KATEGORIE_PKGS[z]+=" sticky xed"; fi

# ------------------------------------------------------------------------------
# Cinnamon Tools
# ---------------
# Achtung: Nicht verwechseln mit ADDITIONAL_S_NAMES[vc],
# welche nur die Starter zur Systemverwaltung enthält!
# ------------------------------------------------------------------------------
KATEGORIE_PKGS[ci]="cinnamon-desktop-environment"

# ------------------------------------------------------------------------------
# GNOME Apps
# Ohne die folgenden, welche bereits in anderen Kategorien enthalten sind:
# gnome-atomix, gnome-disk-utility, gnome-games, gnome-mastermind, gnome-nettool, gnome-software, gnome-software-plugin-flatpak, gnome-sound-recorder, gnome-weather
# -----------
# Achtung: Nicht verwechseln mit ADDITIONAL_S_NAMES[vg],
# welche nur die Starter zur Systemverwaltung enthält!
# ------------------------------------------------------------------------------
GNOME_BASE_APPS=(boxes calculator calendar characters clocks commander connections contacts firmware font-viewer keyring logs maps passwordsafe screenshot snapshot system-monitor system-tools terminal text-editor tweaks usage)
KATEGORIE_PKGS[gx]=""
for pkg in ${GNOME_BASE_APPS[@]};
do
  KATEGORIE_PKGS[gx]+=" gnome-$pkg"
done
# ------------------------------------------------------------------------------
# LXDE Tools
# -----------
# Achtung: Nicht verwechseln mit ADDITIONAL_S_NAMES[vl],
# welche nur die Starter zur Systemverwaltung enthält!
# ------------------------------------------------------------------------------
LXDE_BASE_APPS=(appearance hotkey-gtk input randr session-edit task terminal)
KATEGORIE_PKGS[lx]=""
for pkg in ${LXDE_BASE_APPS[@]};
do
  KATEGORIE_PKGS[lx]+=" lx$pkg"
done
# ------------------------------------------------------------------------------
# MATE Tools
# -----------
# Achtung: Nicht verwechseln mit ADDITIONAL_S_NAMES[vm],
# welche nur die Starter zur Systemverwaltung enthält!
# ------------------------------------------------------------------------------
MATE_BASE_APPS=(applets control-center indicator-applet media sensors-applet terminal utils)
KATEGORIE_PKGS[mx]=""
for pkg in ${MATE_BASE_APPS[@]};
do
  KATEGORIE_PKGS[mx]+=" mate-$pkg"
done
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ];
then
  KATEGORIE_PKGS[mx]+=" mate-calc mate-dock-applet mate-menu mate-tweak mate-user-admin mate-user-share"
else
  KATEGORIE_PKGS[mx]+=" mate-desktop-environment-extras"
fi
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E "ubuntu") -gt 0 ]; then KATEGORIE_PKGS[mx]+=" software-boutique ubuntu-mate-welcome"; fi
# ------------------------------------------------------------------------------
# Mint Tools
# ------------------------------------------------------------------------------
MINT_BASE_APPS=(backup chat desktop drivers install locale report sources stick update welcome)
KATEGORIE_PKGS[mt]=""
for pkg in ${MINT_BASE_APPS[@]};
do
  KATEGORIE_PKGS[mt]+=" mint$pkg"
done
# ------------------------------------------------------------------------------
# XFCE Tools
# -----------
# Achtung: Nicht verwechseln mit ADDITIONAL_S_NAMES[vx],
# welche nur die Starter zur Systemverwaltung enthält!
# ------------------------------------------------------------------------------
XFCE_BASE_APPS=(appfinder dict helpers notifyd panel power-manager screenshooter settings taskmanager terminal)
KATEGORIE_PKGS[xf]=""
for pkg in ${XFCE_BASE_APPS[@]};
do
  KATEGORIE_PKGS[xf]+=" xfce4-$pkg"
done

#===============================================================================
# Pakete innerhalb der Kategorien alphabetisch sortieren
# (sicherheitshalber nicht für Wine, damit dafür in jedem Fall die gewünschte
#  Reihenfolge wine -> wine64 -> wine32 erhalten bleibt)
#===============================================================================
for k in ${KAT_KEY_LIST[@]};
do
  if [ "$k" != "w" ];
  then
    THE_PKGS_LIST=(${KATEGORIE_PKGS[$k]})
    IFS=$'\n'
    TEMP_LIST=($(sort <<<"${THE_PKGS_LIST[*]}"))
    IFS=' '
    KATEGORIE_PKGS[$k]=""
    for p in ${TEMP_LIST[@]};
    do
      KATEGORIE_PKGS[$k]+="$p "
    done
  fi
done

#===============================================================================
# Liste von Paketen, die automatisch zusätzlich zu einem Basispaket installiert
# werden. HINWEIS: Diese Funktionalität ersetzt die vorherige Logik mittels
# DEPENDS_PACK (s.u.), bei welcher alle Pakete durchlaufen werden, aber nur
# die Pakete installiert werden, deren Basispaket bereits installiert ist.
#===============================================================================
declare -A AUTO_ADD_PKGS # Liste der zusätzlichen Pakete
declare -A AUTO_ADD_PPOS # Wenn "true" zusätzliche Pakete VOR Basispaket einfügen

# AUTO_ADD_PKGS[alien-arena]="alien-arena-data" # Derzeit besser als Flatpak

if [ $(LANG=C dpkg-query -W -f='${Status}' "caja" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
then
  AUTO_ADD_PKGS[caja]=""
  CAJA_ADD_PKGS=(actions admin eiciel extensions-common gtkhash image-converter mediainfo open-terminal rename seahorse sendto share wallpaper xattr-tags)
  for pkg in ${CAJA_ADD_PKGS[@]};
  do
    AUTO_ADD_PKGS[caja]+=" caja-$pkg"
  done
fi

AUTO_ADD_PKGS[clamav]="clamav-freshclam clamdscan clamtk"

AUTO_ADD_PKGS[doublecmd-common]="doublecmd-gtk"
# AUTO_ADD_PKGS[frogatto]="frogatto-data" # Derzeit besser als Flatpak
# AUTO_ADD_PKGS[fs-uae]="fs-uae-launcher" # Derzeit nicht im Angebot, da auf
# AUTO_ADD_PPOS[fs-uae]=""                # aktuellem Debian nicht lauffähig
# AUTO_ADD_PKGS[gcompris-qt]="gcompris-qt-data" # Derzeit besser als Flatpak
AUTO_ADD_PKGS[krita]="krita-l10n"
AUTO_ADD_PKGS[libreoffice]="libreoffice-gnome libreoffice-l10n-de"
AUTO_ADD_PKGS[libreoffice-common]="libreoffice-gnome libreoffice-l10n-de"
AUTO_ADD_PKGS[mediainfo]="mediainfo-gui"
AUTO_ADD_PKGS[mkvtoolnix]="mkvtoolnix-gui"
AUTO_ADD_PKGS[mp3splt]="mp3splt-gtk"

if [ $(LANG=C dpkg-query -W -f='${Status}' "nemo" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
then
  AUTO_ADD_PKGS[nemo]=""
  NEMO_ADD_PKGS=(audio-tab compare emblems filename-repairer fileroller font-manager gtkhash image-converter media-columns pastebin preview share terminal)
  for pkg in ${NEMO_ADD_PKGS[@]};
  do
    AUTO_ADD_PKGS[nemo]+=" nemo-$pkg"
  done
fi

AUTO_ADD_PKGS[onedrive]="onedrivegui"
AUTO_ADD_PKGS[opensnitch]="python3-opensnitch-ui"
AUTO_ADD_PKGS[openvpn]="network-manager-openvpn network-manager-openvpn-gnome"
AUTO_ADD_PKGS[redshift]="redshift-gtk"
AUTO_ADD_PKGS[scribus]="scribus-template"
AUTO_ADD_PKGS[texstudio]="texstudio-l10n"

if [ $(LANG=C dpkg-query -W -f='${Status}' "thunar" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
then
  AUTO_ADD_PKGS[thunar]=""
  THUNAR_ADD_PKGS=(archive-plugin font-manager gtkhash volman)
  for pkg in ${THUNAR_ADD_PKGS[@]};
  do
    AUTO_ADD_PKGS[thunar]+=" thunar-$pkg"
  done
fi

AUTO_ADD_PKGS[transmission]="transmission-gtk"
AUTO_ADD_PKGS[transmission-common]="transmission-gtk"
AUTO_ADD_PKGS[usbauth]="usbauth-notifier"
AUTO_ADD_PKGS[usb-creator-common]="usb-creator-gtk"
AUTO_ADD_PKGS[virtualbox]="virtualbox-ext-pack virtualbox-guest-additions-iso"
AUTO_ADD_PKGS[vpnc]="network-manager-vpnc network-manager-vpnc-gnome"

# ------------------------------------------------------------------------------
# Je nach Installations-Status von Wine gibt es unterschiedliche Erweiterungen
# ------------------------------------------------------------------------------
AUTO_ADD_PKGS[wine]=""
WINE_APT_ADDONS="wine64 wine32 winetricks"
WINE_FLAT_ADDONS=""
# ---------------------------
# Wine ist nicht installiert
# ---------------------------
if [[ "$WINE_VERSION_APT" == "" && "$WINE_VERSION_FLAT" == "" ]];
then
  AUTO_ADD_PKGS[wine]="$WINE_APT_ADDONS $WINE_FLAT_ADDONS"
fi
# -----------------------------------------------------
# Wine ist nur aus dem Standard-Repository installiert
# -----------------------------------------------------
if [[ "$WINE_VERSION_APT" != "" && "$WINE_VERSION_FLAT" == "" ]];
then
  AUTO_ADD_PKGS[wine]="$WINE_APT_ADDONS"
fi
# -------------------------------------
# Wine ist nur als Flatpak installiert
# -------------------------------------
if [[ "$WINE_VERSION_APT" == "" && "$WINE_VERSION_FLAT" != "" ]];
then
  AUTO_ADD_PKGS[wine]="$WINE_FLAT_ADDONS"
fi
# -----------------------------------------------------------------
# Wine ist aus dem Standard-Repository und als Flatpak installiert
# -----------------------------------------------------------------
if [[ "$WINE_VERSION_APT" != "" && "$WINE_VERSION_FLAT" != "" ]];
then
  AUTO_ADD_PKGS[wine]="$WINE_APT_ADDONS $WINE_FLAT_ADDONS"
fi
#-------------------------------------------------------------------------------

AUTO_ADD_PKGS[yt-dlp]="youtube-dl youtubedl-gui"

# --------------------------------------------------------------------------
# Diese Spiele sollten derzeit besser nur als Flatpak installiert werden :|
# --------------------------------------------------------------------------
# AUTO_ADD_PPOS[alien-arena]="true"
# AUTO_ADD_PPOS[frogatto]="true"
# AUTO_ADD_PPOS[gcompris-qt]="true"

# -----------------------------------------------------------
# Ggf. Flatpak-Erweiterungen für bestimmte Pakete hinzufügen
# -----------------------------------------------------------
if [ $FLATPAK_ACTIVE -eq 1 ];
then
  AUTO_ADD_PKGS[gnome-software]="gnome-software-plugin-flatpak"
  AUTO_ADD_PKGS[plasma-discover]="plasma-discover-backend-flatpak"
fi

#===============================================================================
# Einige Programme sind nicht in jedem Repository enthalten und können dann
# nicht installiert werden, so dass auch Erweiterungen zu diesen Programmen
# nicht benötigt werden, obwohl diese oft unsinnigerweise installierbar sind.
# Die in der Tabelle DEPENDS_PACK aufgeführten Programme werden daher nur
# dann installiert, wenn auch das zugehörige Basispaket installiert ist.
# HINWEIS: Diese Funktionalität wurde ersetzt durch AUTO_ADD_PKGS (s.o.),
# welche quasi in umgekehrter Logik arbeitet.
#===============================================================================
# declare -A DEPENDS_PACK

# DEPENDS_PACK[doublecmd-gtk]="doublecmd-common"
# DEPENDS_PACK[krita-l10n]="krita"
# DEPENDS_PACK[mediainfo-gui]="mediainfo"
# DEPENDS_PACK[mkvtoolnix-gui]="mkvtoolnix"
# DEPENDS_PACK[scribus-template]="scribus"
# DEPENDS_PACK[usbauth-notifier]="usbauth"
# DEPENDS_PACK[usb-creator-gtk]="usb-creator-common"
# DEPENDS_PACK[virtualbox-ext-pack]="virtualbox"
# DEPENDS_PACK[virtualbox-guest-additions-iso]="virtualbox"

#===============================================================================
# Alternative ähnliche Programmpakete, welche installiert werden, wenn das
# primäre Paket aus den oben stehenden Paket-Listen nicht verfügbar ist.
# Die alternativen Programmpakete können auch aus externen Quellen sein.
# Sollen mehrere verschiedene Alternativen zu einem Paket geprüft werden,
# diese einfach kaskadierend nach gewünschter Reihenfolge notieren.
#===============================================================================
declare -A SIMILAR_PACK

SIMILAR_PACK[0ad]="zeroad"
# SIMILAR_PACK[alienarena]="alien-arena" # Derzeit besser nur als Flatpak
# SIMILAR_PACK[alien-arena]="alienarena" # Derzeit besser nur als Flatpak
SIMILAR_PACK[backintime]="backintime-common"
SIMILAR_PACK[backintime-common]="backintime"
SIMILAR_PACK[balena-etcher]="unetbootin"
SIMILAR_PACK[blender]="blender-tpaw"
SIMILAR_PACK[blender-tpaw]="blender"
SIMILAR_PACK[brasero]="xfburn"
SIMILAR_PACK[celluloid]="parole"
SIMILAR_PACK[chromium]="chromium-browser"
SIMILAR_PACK[chromium-browser]="chromium-common"
SIMILAR_PACK[chromium-common]="chromium"
SIMILAR_PACK[czkawka]="fslint"
SIMILAR_PACK[doublecmd]="doublecmd-common"
SIMILAR_PACK[doublecmd-common]="doublecmd"
SIMILAR_PACK[element]="element-desktop"
SIMILAR_PACK[element-desktop]="element"
SIMILAR_PACK[engrampa]="file-roller"
SIMILAR_PACK[exfatprogs]="exfat-utils"
SIMILAR_PACK[file-roller]="xarchiver"
SIMILAR_PACK[firefox]="firefox-esr"
SIMILAR_PACK[freetuxtv]="iptvnator"
SIMILAR_PACK[fslint]="czkawka"
# SIMILAR_PACK[gcompris]="gcompris-qt" # Derzeit besser nur als Flatpak
# SIMILAR_PACK[gcompris-qt]="gcompris" # Derzeit besser nur als Flatpak
SIMILAR_PACK[gnome-tweaks]="gnome-tweak-tool"
SIMILAR_PACK[hypnotix]="freetuxtv"
SIMILAR_PACK[iptvnator]="hypnotix"
SIMILAR_PACK[k3b]="brasero"
SIMILAR_PACK[kid3]="exfalso"
SIMILAR_PACK[lbreakouthd]="lbreakout2"
SIMILAR_PACK[libreoffice]="libreoffice-common"
SIMILAR_PACK[libreoffice-common]="libreoffice"
SIMILAR_PACK[magnus]="kmag"
SIMILAR_PACK[microsoft-edge-stable]="microsoft-edge-dev"
SIMILAR_PACK[neofetch]="neowofetch"
SIMILAR_PACK[openshot]="openshot-qt"
SIMILAR_PACK[openshot-qt]="openshot"
SIMILAR_PACK[opera]="opera-stable"
SIMILAR_PACK[opera-stable]="opera"
SIMILAR_PACK[p7zip]="p7zip-full"
SIMILAR_PACK[p7zip-full]="p7zip"
SIMILAR_PACK[parole]="mpv"
SIMILAR_PACK[pdfchain]="pdfarranger"
SIMILAR_PACK[pdfarranger]="pdfmod"
SIMILAR_PACK[pdfmod]="pdfchain"
SIMILAR_PACK[pinta]="drawing"
SIMILAR_PACK[shotcut]="openshot"
SIMILAR_PACK[steam]="steam-launcher"
SIMILAR_PACK[steam-launcher]="steam"
SIMILAR_PACK[telegram]="telegram-desktop"
SIMILAR_PACK[telegram-desktop]="telegram"
SIMILAR_PACK[transmission]="transmission-common"
SIMILAR_PACK[transmission-common]="transmission"
SIMILAR_PACK[usb-creator-common]="balena-etcher"
SIMILAR_PACK[virtualbox]="virtualbox-7.0"
SIMILAR_PACK[virtualbox-7.0]="virtualbox-7.1"
SIMILAR_PACK[virtualbox-7.1]="virtualbox"
SIMILAR_PACK[wine]="wine-installer"
SIMILAR_PACK[wine-installer]="wine"

#===============================================================================
# Alternative Quellen "ERW": Programmpakete aus den oben stehenden Paketlisten,
# die zwar nicht im Standard-Repository enthalten sind, aber durch Erweiterung
# der Quell-Listen (/etc/apt/sources.list.d) mit apt installiert werden können.
# Diese Pakete erscheinen danach auch mit apt list <PAKETNAME> als installiert.
#===============================================================================
declare -A ERW_AUTH_KEY # URLs der Authentifizierungs-Schlüssel
declare -A ERW_REPO_TXT # Repository-Einträge

# ------------------------------------------------------------------------------
# Anydesk derzeit nicht auf diesem Weg anbieten, da dies leider zu
# Signatur-Fehlern führen kann und das Paket dann nicht mehr updatebar ist
# ------------------------------------------------------------------------------
# ERW_AUTH_KEY[anydesk]="https://keys.anydesk.com/repos/DEB-GPG-KEY"
# ERW_REPO_TXT[anydesk]="deb http://deb.anydesk.com/ all main"
# ------------------------------------------------------------------------------

if [ $(echo "$OS_V_CODENAME" | grep -i -c -E "noble") -gt 0 ];
then
  ERW_AUTH_KEY[boot-repair]="https://sourceforge.net/projects/boot-repair/files/key.gpg"
  ERW_REPO_TXT[boot-repair]="deb [signed-by=$APT_SOURCES_MAIN_DIR/trusted.gpg.d/boot-repair.gpg] https://ppa.launchpadcontent.net/yannubuntu/boot-repair/ubuntu noble main"
fi

# ------------------------------------------------------------------------------
# Element(-desktop) derzeit nicht auf diesem Weg anbieten, da dies leider zu
# Signatur-Fehlern führen kann und das Paket dann nicht mehr updatebar ist
# ------------------------------------------------------------------------------
# ERW_AUTH_KEY[element-desktop]="https://packages.element.io/debian/element-io-archive-keyring.gpg"
# ERW_REPO_TXT[element-desktop]="deb [signed-by=/etc/apt/trusted.gpg.d/element-desktop.gpg] https://packages.element.io/debian/ default main"
# ------------------------------------------------------------------------------

ERW_AUTH_KEY[firefox]="https://packages.mozilla.org/apt/repo-signing-key.gpg"
ERW_REPO_TXT[firefox]="deb [signed-by=$APT_SOURCES_MAIN_DIR/trusted.gpg.d/firefox.asc] https://packages.mozilla.org/apt mozilla main"

ERW_AUTH_KEY[gerbera]="https://pkg.gerbera.io/public.asc"
ERW_REPO_TXT[gerbera]="deb [signed-by=$APT_SOURCES_MAIN_DIR/trusted.gpg.d/gerbera.asc] https://pkg.gerbera.io/debian/ $OS_V_CODENAME main"

# ------------------------------------------------------------------------------
# Opera-Stable derzeit nicht auf diesem Weg anbieten, da dies leider zu
# Signatur-Fehlern führen kann und das Paket dann nicht mehr updatebar ist
# ------------------------------------------------------------------------------
# ERW_AUTH_KEY[opera-stable]="https://deb.opera.com/archive.key"
# ERW_REPO_TXT[opera-stable]="deb https://deb.opera.com/opera-stable/ stable non-free"
# ------------------------------------------------------------------------------

ERW_AUTH_KEY[microsoft-edge-stable]="https://packages.microsoft.com/keys/microsoft.asc"
ERW_REPO_TXT[microsoft-edge-stable]="deb [arch=amd64] https://packages.microsoft.com/repos/edge/ stable main"

ERW_AUTH_KEY[microsoft-edge-dev]="https://packages.microsoft.com/keys/microsoft.asc"
ERW_REPO_TXT[microsoft-edge-dev]="deb [arch=amd64] https://packages.microsoft.com/repos/edge/ stable main"

# ------------------------------------------------------------------------------
# Steam-Launcher besser mit direkten Download (s.u. DEB) installieren, weil
# Steam-Launcher bei der Installation seine eigenen Repo-Erweiterungen anlegt
# ------------------------------------------------------------------------------
# ERW_AUTH_KEY[steam-launcher]="https://repo.steampowered.com/steam/archive/stable/steam.gpg"
# ERW_REPO_TXT[steam-launcher]="deb [arch=amd64,i386 signed-by=/etc/apt/trusted.gpg.d/steam.gpg] https://repo.steampowered.com/steam/ stable steam"
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# TeamViewer besser mit direkten Download (s.u. DEB) installieren, weil
# TeamViewer bei der Installation seine eigenen Repo-Erweiterungen anlegt
# und dadurch Redundanzen mit unserer Erweiterung enstehen würden.
# ------------------------------------------------------------------------------
# ERW_AUTH_KEY[teamviewer]="https://download.teamviewer.com/download/linux/signature/TeamViewer2017.asc"
# ERW_REPO_TXT[teamviewer]="deb https://linux.teamviewer.com/deb stable main"
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# In reinen Debian-Systemen ist VirtualBox nicht enthalten,
# aber auf den Original-Seiten von Oracle/VirtualBox downloadbar.
# ACHTUNG: Der Paketname lautet dann "virtualbox-7.1", nicht nur "virtualbox"
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# HINWEIS: Auch als externes Paket verfügbar (s.u. DEB)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -gt 0 ] &&
   [ $(echo "$OS_V_CODENAME" | grep -i -c -E "bookworm") -gt 0 ];
then
  ERW_AUTH_KEY[virtualbox-7.1]="https://www.virtualbox.org/download/oracle_vbox_2016.asc"
  ERW_REPO_TXT[virtualbox-7.1]="deb [arch=amd64] http://download.virtualbox.org/virtualbox/debian bookworm contrib"
fi

#===============================================================================
# Alternative Quellen "PPA": Programmpakete aus den oben stehenden Paketlisten,
# die zwar nicht im Standard-Repository enthalten sind, aber durch Erweiterung
# des Repository durch ein privates Repo mit apt installiert werden können.
# Diese Pakete erscheinen danach auch mit apt list <PAKETNAME> als installiert.
# HINWEIS: PPA_REPO_SRC beinhaltet soweit bekannt von Paketen selbst angelegte
# Quelldateien und dient nur zum Löschen dieser Dateien im Falle einer nicht
# erfolgreichen Installation, damit diese nicht den Update-Vorgang stören.
#===============================================================================
declare -A PPA_REPO_TXT # Repository-Einträge
declare -A PPA_REPO_SRC # Datei mit Quellangaben (siehe auch Hinweis oben!)

PPA_REPO_TXT[grub-customizer]="ppa:danielrichter2007/grub-customizer"
PPA_REPO_SRC[grub-customizer]=""

PPA_REPO_TXT[makemkv-bin]="ppa:heyarje/makemkv-beta"
PPA_REPO_SRC[makemkv-bin]="heyarje-ubuntu-makemkv-beta*"

#===============================================================================
# Liste der Architekturen, zu denen alternative Quellen (DEB und WEB)
# angeboten werden.
#===============================================================================
ARCH_NAME_LIST=('amd64' 'i386' 'arm64' 'armhf')

#===============================================================================
# Alternative Quellen "DEB": Programmpakete aus den oben stehenden Paketlisten,
# welche von Dritt-Anbietern im Format .deb zum Download zur Verfügung gestellt
# werden und mit apt installiert werden können.
# Diese Pakete erscheinen danach auch mit apt list <PAKETNAME> als installiert.
# Bei der Notation des Index kann (muss) zudem auch eine Differenzierung nach
# verschiedenen OS-Architekturen erfolgen: [<PAKETNAME>_<SYSTEMARCHITEKTUR>]
# Falls die heruntergeladenen Dateien verifiziert werden sollen, können in dem
# Feld DEB_PKG_CSUM die Prüfsummen dazu direkt (SHA256 oder SHA512), oder eine
# URL zum Download einer entsprechenden Datei mit Prüfsummen angegeben werden.
# Da die meisten Hersteller für die Programme keinen dauerhaft verlässlichen
# Download-Link zur Verfügung stellen, werden diese Programme in der möglichst
# aktuellen und in jedem Fall geprüften Version von migano.de heruntergeladen.
#===============================================================================
declare -A DEB_PKG_NAME # Angezeigter Name des Programms
declare -A DEB_PKG_VERS # Auf migano.de zum Download bereitgestellte Version
declare -A DEB_PKG_MESG # Hinweis zur Installation der neuen Version
declare -A DEB_PKG_EVAL # Kommando zum Testen der Voraussetzungen
declare -A DEB_PKG_FILE # Download-URL
declare -A DEB_PKG_CSUM # Prüfsumme ODER URL zu Prüfsummen-Datei

# Download von https://github.com/balena-io/etcher/releases/latest (https://www.balena.io/etcher/)
# ACHTUNG: Auch als WEB-Version eingetragen (s.u.)!
DEB_PKG_NAME[balena-etcher]="balenaEtcher"
DEB_PKG_VERS[balena-etcher]="2.1.4"
DEB_PKG_MESG[balena-etcher]=""
DEB_PKG_EVAL[balena-etcher]=""
DEB_PKG_FILE[balena-etcher_amd64]="$RESSOURCE_SERVER_DIR/deb/balena-etcher_2.1.4_amd64.deb"
DEB_PKG_CSUM[balena-etcher_amd64]="$RESSOURCE_SERVER_DIR/deb/balena-etcher_2.1.4_amd64.deb.sha"
 DEB_PKG_FILE[balena-etcher_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
 DEB_PKG_CSUM[balena-etcher_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
DEB_PKG_FILE[balena-etcher_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[balena-etcher_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[balena-etcher_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[balena-etcher_armhf]="" # NICHT für ARM verfügbar

# ------------------------------------------------------------------------------
# Download von https://github.com/VSCodium/vscodium
# Nicht mehr angeboten, wenn nicht direkt im Repo dann als Flatpak installieren
# ------------------------------------------------------------------------------
# DEB_PKG_NAME[codium]="VSCodium"
# DEB_PKG_VERS[codium]="1.98.0"
# DEB_PKG_MESG[codium]=""
# DEB_PKG_EVAL[codium]=""
# DEB_PKG_FILE[codium_amd64]="$RESSOURCE_SERVER_DIR/deb/codium_1.98.0.25067_amd64.deb"
# DEB_PKG_CSUM[codium_amd64]="$RESSOURCE_SERVER_DIR/deb/codium_1.98.0.25067_amd64.deb.sha"
#  DEB_PKG_FILE[codium_i386]="" # NUR für 64-bit verfügbar
#  DEB_PKG_CSUM[codium_i386]="" # NUR für 64-bit verfügbar
# DEB_PKG_FILE[codium_arm64]="$RESSOURCE_SERVER_DIR/deb/codium_1.98.0.25067_arm64.deb"
# DEB_PKG_CSUM[codium_arm64]="$RESSOURCE_SERVER_DIR/deb/codium_1.98.0.25067_arm64.deb.sha"
# DEB_PKG_FILE[codium_armhf]="" # NUR für 64-bit verfügbar
# DEB_PKG_CSUM[codium_armhf]="" # NUR für 64-bit verfügbar
# ------------------------------------------------------------------------------

# Download von https://ftp5.gwdg.de/pub/linux/debian/mint/packages/pool/main/h/hypnotix
# oder https://github.com/linuxmint/hypnotix/releases
# Nicht bei reinen Debian-Systemen, da diesen einige benötigte Libraries fehlen :(
if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -eq 0 ];
then
  DEB_PKG_NAME[hypnotix]="Hypnotix"
  DEB_PKG_VERS[hypnotix]="5.6"
  DEB_PKG_MESG[hypnotix]="Benötigt mindestens gtk-4.0!"
  DEB_PKG_EVAL[hypnotix]="[ -d /usr/share/gtk-4.0 ]"
  DEB_PKG_FILE[hypnotix_amd64]="$RESSOURCE_SERVER_DIR/deb/hypnotix_5.6_all.deb"
  DEB_PKG_CSUM[hypnotix_amd64]="$RESSOURCE_SERVER_DIR/deb/hypnotix_5.6_all.deb.sha"
  DEB_PKG_FILE[hypnotix_i386]="" # NUR für 64-bit verfügbar
  DEB_PKG_CSUM[hypnotix_i386]="" # NUR für 64-bit verfügbar
  DEB_PKG_FILE[hypnotix_arm64]="$RESSOURCE_SERVER_DIR/deb/hypnotix_5.6_all.deb"
  DEB_PKG_CSUM[hypnotix_arm64]="$RESSOURCE_SERVER_DIR/deb/hypnotix_5.6_all.deb.sha"
  DEB_PKG_FILE[hypnotix_armhf]="" # NUR für 64-bit verfügbar
  DEB_PKG_CSUM[hypnotix_armhf]="" # NUR für 64-bit verfügbar
fi

# Download von https://angryip.org/download/#linux
DEB_PKG_NAME[ipscan]="Angry IP Scanner"
DEB_PKG_VERS[ipscan]="3.9.3"
DEB_PKG_MESG[ipscan]=""
DEB_PKG_EVAL[ipscan]=""
DEB_PKG_FILE[ipscan_amd64]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_amd64.deb"
DEB_PKG_CSUM[ipscan_amd64]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_amd64.deb.sha"
 DEB_PKG_FILE[ipscan_i386]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb"
 DEB_PKG_CSUM[ipscan_i386]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb.sha"
DEB_PKG_FILE[ipscan_arm64]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb"
DEB_PKG_CSUM[ipscan_arm64]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb.sha"
DEB_PKG_FILE[ipscan_armhf]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb"
DEB_PKG_CSUM[ipscan_armhf]="$RESSOURCE_SERVER_DIR/deb/ipscan_3.9.3_all.deb.sha"

# Download von https://github.com/4gray/iptvnator
DEB_PKG_NAME[iptvnator]="IPTVnator"
DEB_PKG_VERS[iptvnator]="0.18.0"
DEB_PKG_MESG[iptvnator]=""
DEB_PKG_EVAL[iptvnator]=""
DEB_PKG_FILE[iptvnator_amd64]="$RESSOURCE_SERVER_DIR/deb/iptvnator-0.18.0-linux-amd64.deb"
DEB_PKG_CSUM[iptvnator_amd64]="$RESSOURCE_SERVER_DIR/deb/iptvnator-0.18.0-linux-amd64.deb.sha"
DEB_PKG_FILE[iptvnator_i386]="" # NUR für 64-bit verfügbar
DEB_PKG_CSUM[iptvnator_i386]="" # NUR für 64-bit verfügbar
DEB_PKG_FILE[iptvnator_arm64]="$RESSOURCE_SERVER_DIR/deb/iptvnator-0.18.0-linux-arm64.deb"
DEB_PKG_CSUM[iptvnator_arm64]="$RESSOURCE_SERVER_DIR/deb/iptvnator-0.18.0-linux-arm64.deb.sha"
DEB_PKG_FILE[iptvnator_armhf]="" # NUR für 64-bit verfügbar
DEB_PKG_CSUM[iptvnator_armhf]="" # NUR für 64-bit verfügbar

# ------------------------------------------------------------------------------
# HINWEIS: nomachine wurde wegen Kompatibilitätsproblemen mit
# NVIDIA-OpenGL-Treibern vorläufig entfernt! Wenn nomachine wieder
# angeboten werden soll, auch folgende Änderungen hinzufügen:
# - KATEGORIE_PKGS[i] um 'nomachine' erweitern
# - REJECT_STARTER erweitern um 'NoMachine-base-' 'NoMachine-status-'
# ------------------------------------------------------------------------------
# Download von https://www.nomachine.com/download/linux&id=1
# ------------------------------------------------------------------------------
# DEB_PKG_NAME[nomachine]="NoMachine"
# DEB_PKG_VERS[nomachine]="8.14.2"
# DEB_PKG_MESG[nomachine]=""
# DEB_PKG_EVAL[nomachine]=""
# DEB_PKG_FILE[nomachine_amd64]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_amd64.deb"
# DEB_PKG_CSUM[nomachine_amd64]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_amd64.deb.sha"
#  DEB_PKG_FILE[nomachine_i386]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_i386.deb"
#  DEB_PKG_CSUM[nomachine_i386]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_i386.deb.sha"
# DEB_PKG_FILE[nomachine_arm64]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_arm64.deb"
# DEB_PKG_CSUM[nomachine_arm64]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_arm64.deb.sha"
# DEB_PKG_FILE[nomachine_armhf]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_armhf.deb"
# DEB_PKG_CSUM[nomachine_armhf]="$RESSOURCE_SERVER_DIR/deb/nomachine_8.14.2_1_armhf.deb.sha"
# ------------------------------------------------------------------------------

# Download von https://github.com/evilsocket/opensnitch
DEB_PKG_NAME[opensnitch]="OpenSnitch Firewall"
DEB_PKG_VERS[opensnitch]="1.8.0"
DEB_PKG_MESG[opensnitch]=""
DEB_PKG_EVAL[opensnitch]=""
DEB_PKG_FILE[opensnitch_amd64]="$RESSOURCE_SERVER_DIR/deb/opensnitch_1.8.0-1_amd64.deb"
DEB_PKG_CSUM[opensnitch_amd64]="$RESSOURCE_SERVER_DIR/deb/opensnitch_1.8.0-1_amd64.deb.sha"
DEB_PKG_FILE[opensnitch_i386]="" # Wird nicht angeboten
DEB_PKG_CSUM[opensnitch_i386]="" # Wird nicht angeboten
DEB_PKG_FILE[opensnitch_arm64]="$RESSOURCE_SERVER_DIR/deb/opensnitch_1.8.0-1_arm64.deb"
DEB_PKG_CSUM[opensnitch_arm64]="$RESSOURCE_SERVER_DIR/deb/opensnitch_1.8.0-1_arm64.deb.sha"
DEB_PKG_FILE[opensnitch_armhf]="" # Wird nicht angeboten
DEB_PKG_CSUM[opensnitch_armhf]="" # Wird nicht angeboten

# Download von https://github.com/evilsocket/opensnitch
DEB_PKG_NAME[python3-opensnitch-ui]="OpenSnitch Firewall GUI"
DEB_PKG_VERS[python3-opensnitch-ui]="1.8.0"
DEB_PKG_MESG[python3-opensnitch-ui]=""
DEB_PKG_EVAL[python3-opensnitch-ui]=""
DEB_PKG_FILE[python3-opensnitch-ui_amd64]="$RESSOURCE_SERVER_DIR/deb/python3-opensnitch-ui_1.8.0-1_all.deb"
DEB_PKG_CSUM[python3-opensnitch-ui_amd64]="$RESSOURCE_SERVER_DIR/deb/python3-opensnitch-ui_1.8.0-1_all.deb.sha"
DEB_PKG_FILE[python3-opensnitch-ui_i386]="" # Wird nicht angeboten
DEB_PKG_CSUM[python3-opensnitch-ui_i386]="" # Wird nicht angeboten
DEB_PKG_FILE[python3-opensnitch-ui_arm64]="$RESSOURCE_SERVER_DIR/deb/python3-opensnitch-ui_1.8.0-1_all.deb"
DEB_PKG_CSUM[python3-opensnitch-ui_arm64]="$RESSOURCE_SERVER_DIR/deb/python3-opensnitch-ui_1.8.0-1_all.deb.sha"
DEB_PKG_FILE[python3-opensnitch-ui_armhf]="" # Wird nicht angeboten
DEB_PKG_CSUM[python3-opensnitch-ui_armhf]="" # Wird nicht angeboten

# ------------------------------------------------------------------------------
# Download von https://www.opera.com/de/download
# Opera-Stable derzeit nicht auf diesem Weg anbieten, da dies leider zu
# Signatur-Fehlern führen kann und das Paket dann nicht mehr updatebar ist
# ------------------------------------------------------------------------------
# DEB_PKG_NAME[opera-stable]="Opera (Stable)"
# DEB_PKG_VERS[opera-stable]="117.0.5408.197"
# DEB_PKG_MESG[opera-stable]=""
# DEB_PKG_EVAL[opera-stable]=""
# DEB_PKG_FILE[opera-stable_amd64]="$RESSOURCE_SERVER_DIR/deb/opera-stable_117.0.5408.197_amd64.deb"
# DEB_PKG_CSUM[opera-stable_amd64]="$RESSOURCE_SERVER_DIR/deb/opera-stable_117.0.5408.197_amd64.deb.sha"
#  DEB_PKG_FILE[opera-stable_i386]="" # NUR für 64-bit verfügbar
#  DEB_PKG_CSUM[opera-stable_i386]="" # NUR für 64-bit verfügbar
# DEB_PKG_FILE[opera-stable_arm64]="" # NICHT für ARM verfügbar
# DEB_PKG_CSUM[opera-stable_arm64]="" # NICHT für ARM verfügbar
# DEB_PKG_FILE[opera-stable_armhf]="" # NICHT für ARM verfügbar
# DEB_PKG_CSUM[opera-stable_armhf]="" # NICHT für ARM verfügbar
# ------------------------------------------------------------------------------

# Download von https://www.realvnc.com/de/connect/download/vnc/linux
DEB_PKG_NAME[realvnc-vnc-server]="RealVNC Server"
DEB_PKG_VERS[realvnc-vnc-server]="7.16.0"
DEB_PKG_MESG[realvnc-vnc-server]=""
DEB_PKG_EVAL[realvnc-vnc-server]=""
DEB_PKG_FILE[realvnc-vnc-server_amd64]="$RESSOURCE_SERVER_DIR/deb/VNC-Server-7.16.0-Linux-x64.deb"
DEB_PKG_CSUM[realvnc-vnc-server_amd64]="$RESSOURCE_SERVER_DIR/deb/VNC-Server-7.16.0-Linux-x64.deb.sha"
 DEB_PKG_FILE[realvnc-vnc-server_i386]="" # Ab Version 7 nicht mehr verfügbar für 32bit
 DEB_PKG_CSUM[realvnc-vnc-server_i386]="" # Ab Version 7 nicht mehr verfügbar für 32bit
DEB_PKG_FILE[realvnc-vnc-server_arm64]="$RESSOURCE_SERVER_DIR/deb/VNC-Server-7.16.0-Linux-ARM64.deb"
DEB_PKG_CSUM[realvnc-vnc-server_arm64]="$RESSOURCE_SERVER_DIR/deb/VNC-Server-7.16.0-Linux-ARM64.deb.sha"
DEB_PKG_FILE[realvnc-vnc-server_armhf]="" # Ab Version 7 nicht mehr verfügbar für 32bit
DEB_PKG_CSUM[realvnc-vnc-server_armhf]="" # Ab Version 7 nicht mehr verfügbar für 32bit

# Download von https://www.realvnc.com/de/connect/download/viewer/linux
DEB_PKG_NAME[realvnc-vnc-viewer]="RealVNC Viewer"
DEB_PKG_VERS[realvnc-vnc-viewer]="7.15.1"
DEB_PKG_MESG[realvnc-vnc-viewer]=""
DEB_PKG_EVAL[realvnc-vnc-viewer]=""
DEB_PKG_FILE[realvnc-vnc-viewer_amd64]="$RESSOURCE_SERVER_DIR/deb/VNC-Viewer-7.15.1-Linux-x64.deb"
DEB_PKG_CSUM[realvnc-vnc-viewer_amd64]="$RESSOURCE_SERVER_DIR/deb/VNC-Viewer-7.15.1-Linux-x64.deb.sha"
 DEB_PKG_FILE[realvnc-vnc-viewer_i386]="" # Ab Version 7 nicht mehr verfügbar für 32bit
 DEB_PKG_CSUM[realvnc-vnc-viewer_i386]="" # Ab Version 7 nicht mehr verfügbar für 32bit
DEB_PKG_FILE[realvnc-vnc-viewer_arm64]="$RESSOURCE_SERVER_DIR/deb/VNC-Viewer-7.15.1-Linux-ARM64.deb"
DEB_PKG_CSUM[realvnc-vnc-viewer_arm64]="$RESSOURCE_SERVER_DIR/deb/VNC-Viewer-7.15.1-Linux-ARM64.deb.sha"
DEB_PKG_FILE[realvnc-vnc-viewer_armhf]="" # Ab Version 7 nicht mehr verfügbar für 32bit
DEB_PKG_CSUM[realvnc-vnc-viewer_armhf]="" # Ab Version 7 nicht mehr verfügbar für 32bit

# Download von https://github.com/rescuezilla/rescuezilla/releases
# Achtung: Hinweise zur Version auf https://rescuezilla.com beachten
DEB_PKG_NAME[rescuezilla]="Rescuezilla"
DEB_PKG_VERS[rescuezilla]="2.6.1"
DEB_PKG_MESG[rescuezilla]=""
DEB_PKG_EVAL[rescuezilla]=""
DEB_PKG_FILE[rescuezilla_amd64]="$RESSOURCE_SERVER_DIR/deb/rescuezilla_2.6.1-1_all.deb"
DEB_PKG_CSUM[rescuezilla_amd64]="$RESSOURCE_SERVER_DIR/deb/rescuezilla_2.6.1-1_all.deb.sha"
 DEB_PKG_FILE[rescuezilla_i386]="" # NUR für 64-bit verfügbar
 DEB_PKG_CSUM[rescuezilla_i386]="" # NUR für 64-bit verfügbar
DEB_PKG_FILE[rescuezilla_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[rescuezilla_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[rescuezilla_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[rescuezilla_armhf]="" # NICHT für ARM verfügbar

# Download von https://github.com/raspberrypi/rpi-imager
# ACHTUNG: Auch als Appimage verfügbar (s.u.)
DEB_PKG_NAME[rpi-imager]="Raspberry Pi Imager"
DEB_PKG_VERS[rpi-imager]="2.0.6"
DEB_PKG_MESG[rpi-imager]=""
DEB_PKG_EVAL[rpi-imager]=""
DEB_PKG_FILE[rpi-imager_amd64]="$RESSOURCE_SERVER_DIR/deb/rpi-imager_2.0.6_amd64.deb"
DEB_PKG_CSUM[rpi-imager_amd64]="$RESSOURCE_SERVER_DIR/deb/rpi-imager_2.0.6_amd64.deb.sha"
 DEB_PKG_FILE[rpi-imager_i386]="" # NUR für 64-bit verfügbar
 DEB_PKG_CSUM[rpi-imager_i386]="" # NUR für 64-bit verfügbar
DEB_PKG_FILE[rpi-imager_arm64]="$RESSOURCE_SERVER_DIR/deb/rpi-imager_2.0.6_arm64.deb"
DEB_PKG_CSUM[rpi-imager_arm64]="$RESSOURCE_SERVER_DIR/deb/rpi-imager_2.0.6_arm64.deb.sha"
DEB_PKG_FILE[rpi-imager_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[rpi-imager_armhf]="" # NICHT für ARM verfügbar

# Download von https://github.com/rustdesk/rustdesk/releases
# Hinweis: Auch als AppImage verfügbar (s.u.)
DEB_PKG_NAME[rustdesk]="RustDesk"
DEB_PKG_VERS[rustdesk]="1.4.5"
DEB_PKG_MESG[rustdesk]=""
DEB_PKG_EVAL[rustdesk]=""
DEB_PKG_FILE[rustdesk_amd64]="$RESSOURCE_SERVER_DIR/deb/rustdesk-1.4.5-x86_64.deb"
DEB_PKG_CSUM[rustdesk_amd64]="$RESSOURCE_SERVER_DIR/deb/rustdesk-1.4.5-x86_64.deb.sha"
 DEB_PKG_FILE[rustdesk_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
 DEB_PKG_CSUM[rustdesk_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
DEB_PKG_FILE[rustdesk_arm64]="$RESSOURCE_SERVER_DIR/deb/rustdesk-1.4.5-aarch64.deb"
DEB_PKG_CSUM[rustdesk_arm64]="$RESSOURCE_SERVER_DIR/deb/rustdesk-1.4.5-aarch64.deb.sha"
DEB_PKG_FILE[rustdesk_armhf]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
DEB_PKG_CSUM[rustdesk_armhf]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)

# Downloads automatisch von der Herstellerseite
# (manuell: https://store.steampowered.com/about)
DEB_PKG_NAME[steam-launcher]="Steam Launcher"
DEB_PKG_VERS[steam-launcher]=""
DEB_PKG_MESG[steam-launcher]=""
DEB_PKG_EVAL[steam-launcher]=""
DEB_PKG_FILE[steam-launcher_amd64]="https://repo.steampowered.com/steam/archive/stable/steam_latest.deb"
DEB_PKG_CSUM[steam-launcher_amd64]=""
 DEB_PKG_FILE[steam-launcher_i368]="https://repo.steampowered.com/steam/archive/stable/steam_latest.deb"
 DEB_PKG_CSUM[steam-launcher_i368]=""
DEB_PKG_FILE[steam-launcher_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[steam-launcher_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[steam-launcher_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[steam-launcher_armhf]="" # NICHT für ARM verfügbar

# Downloads automatisch von der Herstellerseite
# (manuell: https://www.teamviewer.com/de/download/linux)
DEB_PKG_NAME[teamviewer]="TeamViewer"
DEB_PKG_VERS[teamviewer]=""
DEB_PKG_MESG[teamviewer]=""
DEB_PKG_EVAL[teamviewer]=""
DEB_PKG_FILE[teamviewer_amd64]="https://download.teamviewer.com/download/linux/teamviewer_amd64.deb"
DEB_PKG_CSUM[teamviewer_amd64]=""
 DEB_PKG_FILE[teamviewer_i386]="https://download.teamviewer.com/download/linux/teamviewer_i386.deb"
 DEB_PKG_CSUM[teamviewer_i386]=""
DEB_PKG_FILE[teamviewer_arm64]="https://download.teamviewer.com/download/linux/teamviewer_arm64.deb"
DEB_PKG_CSUM[teamviewer_arm64]=""
DEB_PKG_FILE[teamviewer_armhf]="https://download.teamviewer.com/download/linux/teamviewer_armhf.deb"
DEB_PKG_CSUM[teamviewer_armhf]=""

# Download von https://pkgs.org/download/usb-creator-common
DEB_PKG_NAME[usb-creator-common]="USB-Creator-Common"
DEB_PKG_VERS[usb-creator-common]="0.4.1"
DEB_PKG_MESG[usb-creator-common]=""
DEB_PKG_EVAL[usb-creator-common]=""
DEB_PKG_FILE[usb-creator-common_amd64]="$RESSOURCE_SERVER_DIR/deb/usb-creator-common_0.4.1_all.deb"
DEB_PKG_CSUM[usb-creator-common_amd64]="$RESSOURCE_SERVER_DIR/deb/usb-creator-common_0.4.1_all.deb.sha"
 DEB_PKG_FILE[usb-creator-common_i386]="" # NUR für 64-bit gepackt
 DEB_PKG_CSUM[usb-creator-common_i386]="" # NUR für 64-bit gepackt
DEB_PKG_FILE[usb-creator-common_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[usb-creator-common_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[usb-creator-common_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[usb-creator-common_armhf]="" # NICHT für ARM verfügbar

# Download von https://pkgs.org/download/usb-creator-gtk
DEB_PKG_NAME[usb-creator-gtk]="USB-Creator-GTK"
DEB_PKG_VERS[usb-creator-gtk]="0.4.1"
DEB_PKG_MESG[usb-creator-gtk]=""
DEB_PKG_EVAL[usb-creator-gtk]=""
DEB_PKG_FILE[usb-creator-gtk_amd64]="$RESSOURCE_SERVER_DIR/deb/usb-creator-gtk_0.4.1_all.deb"
DEB_PKG_CSUM[usb-creator-gtk_amd64]="$RESSOURCE_SERVER_DIR/deb/usb-creator-gtk_0.4.1_all.deb.sha"
 DEB_PKG_FILE[usb-creator-gtk_i386]="" # NUR für 64-bit gepackt
 DEB_PKG_CSUM[usb-creator-gtk_i386]="" # NUR für 64-bit gepackt
DEB_PKG_FILE[usb-creator-gtk_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[usb-creator-gtk_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[usb-creator-gtk_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[usb-creator-gtk_armhf]="" # NICHT für ARM verfügbar

# ------------------------------------------------------------------------------
# Download von https://veracrypt.fr/en/Downloads.html
# ACHTUNG: BEI ÄNDERUNGEN AUCH DIE DATEI "veracrypt-1.yx.z-sha256sum.txt" DOWNLOADEN
#          UND AUF DEM SERVER ALS "veracrypt-1.xy.z-sha256sum.sha" SPEICHERN !!!
# VeraCrypt bietet weiter differenzierte Pakete an -----------------------------
OPSYS_PART=""
# Zuerst testen ob Ubuntu ...
if [ $(uname -a 2>/dev/null | grep -i -c -E "ubuntu") -gt 0 ];
then
  OPSYS_PART="Ubuntu-$UBUNTU_VERSION"
else
  # ... danach ob Debian
  if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") -gt 0 ];
  then
    OPSYS_PART="Debian-$DEBIAN_VERSION"
  fi
fi
if [ "$OPSYS_PART" != "" ];
then
  DEB_PKG_NAME[veracrypt]="VeraCrypt"
  DEB_PKG_VERS[veracrypt]="1.26.24"
  DEB_PKG_MESG[veracrypt]=""
  DEB_PKG_EVAL[veracrypt]=""
  DEB_PKG_FILE[veracrypt_amd64]="$RESSOURCE_SERVER_DIR/deb/veracrypt-1.26.24-$OPSYS_PART-amd64.deb"
  DEB_PKG_CSUM[veracrypt_amd64]="$RESSOURCE_SERVER_DIR/deb/veracrypt-1.26.24-sha256sum.sha" # ACHTUNG: Liste!
   DEB_PKG_FILE[veracrypt_i386]="" # Nur als generischer Installer verfügbar (nicht aufgenommen)
   DEB_PKG_CSUM[veracrypt_i386]="" # Nur als generischer Installer verfügbar (nicht aufgenommen)
  DEB_PKG_FILE[veracrypt_arm64]="$RESSOURCE_SERVER_DIR/deb/veracrypt-1.26.24-$OPSYS_PART-arm64.deb"
  DEB_PKG_CSUM[veracrypt_arm64]="$RESSOURCE_SERVER_DIR/deb/veracrypt-1.26.24-sha256sum.sha" # ACHTUNG: Liste!
  DEB_PKG_FILE[veracrypt_armhf]="" # Nur als generischer Installer verfügbar (nicht aufgenommen)
  DEB_PKG_CSUM[veracrypt_armhf]="" # Nur als generischer Installer verfügbar (nicht aufgenommen)
fi
# ------------------------------------------------------------------------------

# Download von https://www.xnview.com/de/xnviewmp/#downloads
DEB_PKG_NAME[xnview]="XnView MP"
DEB_PKG_VERS[xnview]="1.9.10"
DEB_PKG_MESG[xnview]=""
DEB_PKG_EVAL[xnview]=""
DEB_PKG_FILE[xnview_amd64]="$RESSOURCE_SERVER_DIR/deb/XnViewMP-linux-x64.deb"
DEB_PKG_CSUM[xnview_amd64]="$RESSOURCE_SERVER_DIR/deb/XnViewMP-linux-x64.deb.sha"
 DEB_PKG_FILE[xnview_i386]="" # Wird nicht mehr angeboten
 DEB_PKG_CSUM[xnview_i386]="" # Wird nicht mehr angeboten
DEB_PKG_FILE[xnview_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[xnview_arm64]="" # NICHT für ARM verfügbar
DEB_PKG_FILE[xnview_armhf]="" # NICHT für ARM verfügbar
DEB_PKG_CSUM[xnview_armhf]="" # NICHT für ARM verfügbar

# ------------------------------------------------------------------------------
# Zusätzliche Pakete, die zwar im Standard-Repository von Ubuntu, aber nicht
# in dem von Debian enthalten sind. Da die betroffenen Pakete vermutlich nur
# auf neueren Rechnern laufen, werden diese zudem nur für amd64 angeboten.
# Manche Pakete sind obwohl nicht im Repo trotzdem auf den Debian-Servern
# verfügbar unter: https://www.debian.org/distrib/packages#search_packages
# Achtung: Da die reinen Debian-Pakete auf Ubuntu eventuell nicht laufen,
# werden diese auf Ubuntu-basierenden Systemen auch nicht angeboten.
# ------------------------------------------------------------------------------
if [ $(echo "$DEBIAN_CODE" | grep -i -c -E "bookworm") -gt 0 ] &&
   [ $(uname -a 2>/dev/null | grep -i -c -E "ubuntu") -eq 0 ];
then

# --------------------------------------------------------------------------
# Diese Spiele sollten derzeit besser nur als Flatpak installiert werden :|
# --------------------------------------------------------------------------
#   DEB_PKG_NAME[alien-arena]="Alien Arena"
#   DEB_PKG_VERS[alien-arena]="7.71.3"
#   DEB_PKG_MESG[alien-arena]=""
#   DEB_PKG_EVAL[alien-arena]=""
#   DEB_PKG_FILE[alien-arena_amd64]="$RESSOURCE_SERVER_DIR/deb/alien-arena_7.71.3+dfsg-3_amd64.deb"
#   DEB_PKG_CSUM[alien-arena_amd64]="$RESSOURCE_SERVER_DIR/deb/alien-arena_7.71.3+dfsg-3_amd64.deb.sha"
#
#   DEB_PKG_NAME[alien-arena-data]="Alien Arena Data"
#   DEB_PKG_VERS[alien-arena-data]="7.71.3"
#   DEB_PKG_MESG[alien-arena-data]=""
#   DEB_PKG_EVAL[alien-arena-data]=""
#   DEB_PKG_FILE[alien-arena-data_amd64]="$RESSOURCE_SERVER_DIR/deb/alien-arena-data_7.71.3+ds-1_all.deb"
#   DEB_PKG_CSUM[alien-arena-data_amd64]="$RESSOURCE_SERVER_DIR/deb/alien-arena-data_7.71.3+ds-1_all.deb.sha"
#
#   DEB_PKG_NAME[frogatto]="Frogatto"
#   DEB_PKG_VERS[frogatto]="1.3.1"
#   DEB_PKG_MESG[frogatto]=""
#   DEB_PKG_EVAL[frogatto]=""
#   DEB_PKG_FILE[frogatto_amd64]="$RESSOURCE_SERVER_DIR/deb/frogatto_1.3.1+dfsg-6+b2_amd64.deb"
#   DEB_PKG_CSUM[frogatto_amd64]="$RESSOURCE_SERVER_DIR/deb/frogatto_1.3.1+dfsg-6+b2_amd64.deb.sha"
#
#   DEB_PKG_NAME[frogatto-data]="Frogatto Data"
#   DEB_PKG_VERS[frogatto-data]="1.3.1"
#   DEB_PKG_MESG[frogatto-data]=""
#   DEB_PKG_EVAL[frogatto-data]=""
#   DEB_PKG_FILE[frogatto-data_amd64]="$RESSOURCE_SERVER_DIR/deb/frogatto-data_1.3.1+dfsg-3_all.deb"
#   DEB_PKG_CSUM[frogatto-data_amd64]="$RESSOURCE_SERVER_DIR/deb/frogatto-data_1.3.1+dfsg-3_all.deb.sha"
#
#   DEB_PKG_NAME[gcompris-qt]="GCompris"
#   DEB_PKG_VERS[gcompris-qt]="3.1.2"
#   DEB_PKG_MESG[gcompris-qt]=""
#   DEB_PKG_EVAL[gcompris-qt]=""
#   DEB_PKG_FILE[gcompris-qt_amd64]="$RESSOURCE_SERVER_DIR/deb/gcompris-qt_3.1-2_amd64.deb"
#   DEB_PKG_CSUM[gcompris-qt_amd64]="$RESSOURCE_SERVER_DIR/deb/gcompris-qt_3.1-2_amd64.deb.sha"
#
#   DEB_PKG_NAME[gcompris-qt-data]="GCompris Data"
#   DEB_PKG_VERS[gcompris-qt-data]="3.1.2"
#   DEB_PKG_MESG[gcompris-qt-data]=""
#   DEB_PKG_EVAL[gcompris-qt-data]=""
#   DEB_PKG_FILE[gcompris-qt-data_amd64]="$RESSOURCE_SERVER_DIR/deb/gcompris-qt-data_3.1-2_all.deb"
#   DEB_PKG_CSUM[gcompris-qt-data_amd64]="$RESSOURCE_SERVER_DIR/deb/gcompris-qt-data_3.1-2_all.deb.sha"
# --------------------------------------------------------------------------

  DEB_PKG_NAME[grub-customizer]="Grub Customizer"
  DEB_PKG_VERS[grub-customizer]="5.2.2"
  DEB_PKG_MESG[grub-customizer]=""
  DEB_PKG_EVAL[grub-customizer]=""
  DEB_PKG_FILE[grub-customizer_amd64]="$RESSOURCE_SERVER_DIR/deb/grub-customizer_5.2.2-2_amd64.deb"
  DEB_PKG_CSUM[grub-customizer_amd64]="$RESSOURCE_SERVER_DIR/deb/grub-customizer_5.2.2-2_amd64.deb.sha"

  DEB_PKG_NAME[gtkpod]="Gtkpod"
  DEB_PKG_VERS[gtkpod]="2.1.5"
  DEB_PKG_MESG[gtkpod]=""
  DEB_PKG_EVAL[gtkpod]=""
  DEB_PKG_FILE[gtkpod_amd64]="$RESSOURCE_SERVER_DIR/deb/gtkpod_2.1.5-10_amd64.deb"
  DEB_PKG_CSUM[gtkpod_amd64]="$RESSOURCE_SERVER_DIR/deb/gtkpod_2.1.5-10_amd64.deb.sha"

  DEB_PKG_NAME[isomaster]="ISO Master"
  DEB_PKG_VERS[isomaster]="1.3.13"
  DEB_PKG_MESG[isomaster]=""
  DEB_PKG_EVAL[isomaster]=""
  DEB_PKG_FILE[isomaster_amd64]="$RESSOURCE_SERVER_DIR/deb/isomaster_1.3.13-1+b2_amd64.deb"
  DEB_PKG_CSUM[isomaster_amd64]="$RESSOURCE_SERVER_DIR/deb/isomaster_1.3.13-1+b2_amd64.deb.sha"

  DEB_PKG_NAME[libdvd-pkg]="LibDVD-pkg"
  DEB_PKG_VERS[libdvd-pkg]="1.4.3"
  DEB_PKG_MESG[libdvd-pkg]=""
  DEB_PKG_EVAL[libdvd-pkg]=""
  DEB_PKG_FILE[libdvd-pkg_amd64]="$RESSOURCE_SERVER_DIR/deb/libdvd-pkg_1.4.3-1-1_all.deb"
  DEB_PKG_CSUM[libdvd-pkg_amd64]="$RESSOURCE_SERVER_DIR/deb/libdvd-pkg_1.4.3-1-1_all.deb.sha"

  DEB_PKG_NAME[mu-editor]="MU-Editor"
  DEB_PKG_VERS[mu-editor]="1.0.3"
  DEB_PKG_MESG[mu-editor]=""
  DEB_PKG_EVAL[mu-editor]=""
  DEB_PKG_FILE[mu-editor_amd64]="$RESSOURCE_SERVER_DIR/deb/mu-editor_1.0.3+dfsg-6_all.deb"
  DEB_PKG_CSUM[mu-editor_amd64]="$RESSOURCE_SERVER_DIR/deb/mu-editor_1.0.3+dfsg-6_all.deb.sha"

  DEB_PKG_NAME[pdfmod]="PDF Mod"
  DEB_PKG_VERS[pdfmod]="0.9.1"
  DEB_PKG_MESG[pdfmod]=""
  DEB_PKG_EVAL[pdfmod]=""
  DEB_PKG_FILE[pdfmod_amd64]="$RESSOURCE_SERVER_DIR/deb/pdfmod_0.9.1-8.2_all.deb"
  DEB_PKG_CSUM[pdfmod_amd64]="$RESSOURCE_SERVER_DIR/deb/pdfmod_0.9.1-8.2_all.deb.sha"

  DEB_PKG_NAME[pinta]="Pinta"
  DEB_PKG_VERS[pinta]="1.6"
  DEB_PKG_MESG[pinta]=""
  DEB_PKG_EVAL[pinta]=""
  DEB_PKG_FILE[pinta_amd64]="$RESSOURCE_SERVER_DIR/deb/pinta_1.6-2.1_all.deb"
  DEB_PKG_CSUM[pinta_amd64]="$RESSOURCE_SERVER_DIR/deb/pinta_1.6-2.1_all.deb.sha"

  DEB_PKG_NAME[playonlinux]="PlayOnLinux"
  DEB_PKG_VERS[playonlinux]="4.3.4"
  DEB_PKG_MESG[playonlinux]=""
  DEB_PKG_EVAL[playonlinux]=""
  DEB_PKG_FILE[playonlinux_amd64]="$RESSOURCE_SERVER_DIR/deb/playonlinux_4.3.4-3_all.deb"
  DEB_PKG_CSUM[playonlinux_amd64]="$RESSOURCE_SERVER_DIR/deb/playonlinux_4.3.4-3_all.deb.sha"

  DEB_PKG_NAME[rocksndiamonds]="Rocks n Diamonds"
  DEB_PKG_VERS[rocksndiamonds]="4.3.5.1"
  DEB_PKG_MESG[rocksndiamonds]=""
  DEB_PKG_EVAL[rocksndiamonds]=""
  DEB_PKG_FILE[rocksndiamonds_amd64]="$RESSOURCE_SERVER_DIR/deb/rocksndiamonds_4.3.5.1+dfsg-1_amd64.deb"
  DEB_PKG_CSUM[rocksndiamonds_amd64]="$RESSOURCE_SERVER_DIR/deb/rocksndiamonds_4.3.5.1+dfsg-1_amd64.deb.sha"

  DEB_PKG_NAME[sauerbraten]="Sauerbraten"
  DEB_PKG_VERS[sauerbraten]="0.0.20021227"
  DEB_PKG_MESG[sauerbraten]=""
  DEB_PKG_EVAL[sauerbraten]=""
  DEB_PKG_FILE[sauerbraten_amd64]="$RESSOURCE_SERVER_DIR/deb/sauerbraten_0.0.20201227-1_all.deb"
  DEB_PKG_CSUM[sauerbraten_amd64]="$RESSOURCE_SERVER_DIR/deb/sauerbraten_0.0.20201227-1_all.deb.sha"

  DEB_PKG_NAME[winetricks]="Winetricks"
  DEB_PKG_VERS[winetricks]="20230212.2"
  DEB_PKG_MESG[winetricks]=""
  DEB_PKG_EVAL[winetricks]=""
  DEB_PKG_FILE[winetricks_amd64]="$RESSOURCE_SERVER_DIR/deb/winetricks_20230212-2_all.deb"
  DEB_PKG_CSUM[winetricks_amd64]="$RESSOURCE_SERVER_DIR/deb/winetricks_20230212-2_all.deb.sha"

  DEB_PKG_NAME[youtube-dl]="YouTube-Dl"
  DEB_PKG_VERS[youtube-dl]="2021.12.17"
  DEB_PKG_MESG[youtube-dl]=""
  DEB_PKG_EVAL[youtube-dl]=""
  DEB_PKG_FILE[youtube-dl_amd64]="$RESSOURCE_SERVER_DIR/deb/youtube-dl_2021.12.17-2_all.deb"
  DEB_PKG_CSUM[youtube-dl_amd64]="$RESSOURCE_SERVER_DIR/deb/youtube-dl_2021.12.17-2_all.deb.sha"

  DEB_PKG_NAME[youtubedl-gui]="YouTube-Dl-GUI"
  DEB_PKG_VERS[youtubedl-gui]="3.0"
  DEB_PKG_MESG[youtubedl-gui]=""
  DEB_PKG_EVAL[youtubedl-gui]=""
  DEB_PKG_FILE[youtubedl-gui_amd64]="$RESSOURCE_SERVER_DIR/deb/youtubedl-gui_3.0-2_amd64.deb"
  DEB_PKG_CSUM[youtubedl-gui_amd64]="$RESSOURCE_SERVER_DIR/deb/youtubedl-gui_3.0-2_amd64.deb.sha"

  DEB_PKG_NAME[yt-dlp]="YouTube-Dlp"
  DEB_PKG_VERS[yt-dlp]="2023.03.04"
  DEB_PKG_MESG[yt-dlp]=""
  DEB_PKG_EVAL[yt-dlp]=""
  DEB_PKG_FILE[yt-dlp_amd64]="$RESSOURCE_SERVER_DIR/deb/yt-dlp_2023.03.04-1_all.deb"
  DEB_PKG_CSUM[yt-dlp_amd64]="$RESSOURCE_SERVER_DIR/deb/yt-dlp_2023.03.04-1_all.deb.sha"

  # Download von https://www.virtualbox.org/wiki/Linux_Downloads oder
  # https://download.virtualbox.org/virtualbox/
  # ACHTUNG: Der Paketname lautet dann "virtualbox-7.1", nicht nur "virtualbox"
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # HINWEIS: Auch als Repo-Erweiterung verfügbar (s.o. ERW), daher wird
  #          VirtualBox vorerst nicht mehr individuell vorgehalten!
  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # if [ $(uname -a 2>/dev/null | grep -i -c -E "debian") ];
  # then
  #   DEB_PKG_NAME[virtualbox-7.1]="VirtualBox 7.1"
  #   DEB_PKG_VERS[virtualbox-7.1]="7.1.6"
  #   DEB_PKG_MESG[virtualbox-7.1]=""
  #   DEB_PKG_EVAL[virtualbox-7.1]=""
  #   DEB_PKG_FILE[virtualbox-7.1_amd64]="$RESSOURCE_SERVER_DIR/deb/virtualbox-7.1_7.1.6-167084~Debian~bookworm_amd64.deb"
  #   DEB_PKG_CSUM[virtualbox-7.1_amd64]="$RESSOURCE_SERVER_DIR/deb/virtualbox-7.1_7.1.6-167084~Debian~bookworm_amd64.deb.sha"
  # fi

fi
# -----------------------------------------------------------------------------

#===============================================================================
# Ordner zur Einrichtung nur der kopierten Programmpakete von Dritt-Anbietern
# (siehe WEB_PKG_FILE). Je Programmpaket wird darin automatisch ein weiterer
# Unterordner mit dem in WEB_PKG_NAME definierten Namen erstellt.
# ACHTUNG: Angaben OHNE Slash (/) am Ende!
#===============================================================================
if [ "$USER_USERNAME" == "root" ];
then
  WEB_PKG_DIR="/opt"
else
  WEB_PKG_DIR="$USER_HOME_DIR/apps"
fi

#===============================================================================
# Alternative Quellen "WEB": Programmpakete aus den oben stehenden Paketlisten,
# die in Form ausführbarer Dateien von Dritt-Anbietern heruntergeladen und
# in einen lokalen Ordner (siehe WEB_PKG_DIR) entpackt/kopiert werden können.
# Diese Programme erscheinen NICHT als mit apt installierte Pakete!
# Die als Index aufgeführten Paketnamen dienen somit nur der Zuordnung zu
# einer Kategorie, sowie zur Auswahl der Installationsart in diesem Skript.
# Bei der Notation des Index kann (muss) zudem auch eine Differenzierung nach
# verschiedenen OS-Architekturen erfolgen: [<PAKETNAME>_<SYSTEMARCHITEKTUR>]
# Falls die heruntergeladenen Dateien verifiziert werden sollen, können in dem
# Feld WEB_PKG_CSUM die Prüfsummen dazu direkt (SHA256 oder SHA512), oder eine
# URL zum Download einer entsprechenden Datei mit Prüfsummen angegeben werden.
# Da die meisten Hersteller für die Programme keinen dauerhaft verlässlichen
# Download-Link zur Verfügung stellen, werden diese Programme in der möglichst
# aktuellen und in jedem Fall geprüften Version von migano.de heruntergeladen.
#===============================================================================
declare -A WEB_PKG_NAME # Angezeigter Name des Programms und zugleich der Ordnername,
                        # in welchen die jeweiligen Programm-Dateien gespeichert werden
                        # ACHTUNG: Nur der Ordnername, nicht der vollständge Pfad (siehe WEB_PKG_DIR)!
declare -A WEB_PKG_VERS # Auf migano.de zum Download bereitgestellte Version
declare -A WEB_PKG_MESG # Hinweis zur Installation der neuen Version
declare -A WEB_PKG_EVAL # Kommando zum Testen der Voraussetzungen
declare -A WEB_PKG_FILE # Download-URL
declare -A WEB_PKG_CSUM # Prüfsumme ODER URL zu Prüfsummen-Datei
declare -A WEB_PKG_CATY # Kategorie für den Linux-Menü-Eintrag (NICHT unsere Kategorien)

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
#                                                                              #
#         ACHTUNG: ÄNDERUNGEN AUCH IN DEN POST-SKRIPTEN ABGLEICHEN !!!         #
#                                                                              #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #

# Download von https://github.com/balena-io/etcher/releases/latest (https://www.balena.io/etcher/)
# ACHTUNG: Auch als DEB eingetragen (s.o.)!
WEB_PKG_NAME[balena-etcher]="balenaEtcher"
WEB_PKG_CATY[balena-etcher]="System;Utility"
WEB_PKG_VERS[balena-etcher]="2.1.0"
WEB_PKG_MESG[balena-etcher]=""
WEB_PKG_EVAL[balena-etcher]=""
WEB_PKG_FILE[balena-etcher_amd64]="$RESSOURCE_SERVER_DIR/web/balenaEtcher-2.1.0-x64.AppImage"
WEB_PKG_CSUM[balena-etcher_amd64]="$RESSOURCE_SERVER_DIR/web/balenaEtcher-2.1.0-x64.AppImage.sha"
 WEB_PKG_FILE[balena-etcher_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
 WEB_PKG_CSUM[balena-etcher_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
WEB_PKG_FILE[balena-etcher_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[balena-etcher_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[balena-etcher_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[balena-etcher_armhf]="" # NICHT für ARM verfügbar

# Eigene Zusammenstellung ;)
WEB_PKG_NAME[code-the-classics]="Code the Classics"
WEB_PKG_CATY[code-the-classics]="Games"
WEB_PKG_VERS[code-the-classics]="2.00"
WEB_PKG_MESG[code-the-classics]=""
WEB_PKG_EVAL[code-the-classics]=""
WEB_PKG_FILE[code-the-classics_amd64]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz"
WEB_PKG_CSUM[code-the-classics_amd64]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz.sha"
 WEB_PKG_FILE[code-the-classics_i386]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz"
 WEB_PKG_CSUM[code-the-classics_i386]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz.sha"
WEB_PKG_FILE[code-the-classics_arm64]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz"
WEB_PKG_CSUM[code-the-classics_arm64]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz.sha"
WEB_PKG_FILE[code-the-classics_armhf]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz"
WEB_PKG_CSUM[code-the-classics_armhf]="$RESSOURCE_SERVER_DIR/web/Code-the-Classics.tar.gz.sha"

# Download von https://github.com/qarmin/czkawka/releases
WEB_PKG_NAME[czkawka]="Czkawka"
WEB_PKG_CATY[czkawka]="System;Utility"
WEB_PKG_VERS[czkawka]="10.0.0"
WEB_PKG_MESG[czkawka]="Benötigt mindestens gtk-4.0!"
WEB_PKG_EVAL[czkawka]="[ -d /usr/share/gtk-4.0 ]"
WEB_PKG_FILE[czkawka_amd64]="$RESSOURCE_SERVER_DIR/web/linux_czkawka_gui_10.0.0_x86_64.AppImage"
WEB_PKG_CSUM[czkawka_amd64]="$RESSOURCE_SERVER_DIR/web/linux_czkawka_gui_10.0.0_x86_64.AppImage.sha"
 WEB_PKG_FILE[czkawka_i386]="" # NICHT verfügbar
 WEB_PKG_CSUM[czkawka_i386]="" # NICHT verfügbar
WEB_PKG_FILE[czkawka_arm64]="$RESSOURCE_SERVER_DIR/web/linux_czkawka_gui_10.0.0_arm64.AppImage"
WEB_PKG_CSUM[czkawka_arm64]="$RESSOURCE_SERVER_DIR/web/linux_czkawka_gui_10.0.0_arm64.AppImage.sha"
WEB_PKG_FILE[czkawka_armhf]="" # NICHT verfügbar
WEB_PKG_CSUM[czkawka_armhf]="" # NICHT verfügbar

# Download von https://freefilesync.org/download.php
WEB_PKG_NAME[freefilesync]="FreeFileSync"
WEB_PKG_CATY[freefilesync]="System;Utility"
WEB_PKG_VERS[freefilesync]="14.7"
WEB_PKG_MESG[freefilesync]=""
WEB_PKG_EVAL[freefilesync]=""
WEB_PKG_FILE[freefilesync_amd64]="$RESSOURCE_SERVER_DIR/web/FreeFileSync_14.7_Linux_x86_64.tar.gz"
WEB_PKG_CSUM[freefilesync_amd64]="$RESSOURCE_SERVER_DIR/web/FreeFileSync_14.7_Linux_x86_64.tar.gz.sha"
 WEB_PKG_FILE[freefilesync_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
 WEB_PKG_CSUM[freefilesync_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht lauffähig)
WEB_PKG_FILE[freefilesync_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[freefilesync_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[freefilesync_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[freefilesync_armhf]="" # NICHT für ARM verfügbar

# Download von https://fs-uae.net/download#linux
WEB_PKG_NAME[fs-uae]="FS-UAE"
WEB_PKG_CATY[fs-uae]="Games"
WEB_PKG_VERS[fs-uae]="3.2.35"
WEB_PKG_MESG[fs-uae]=""
WEB_PKG_EVAL[fs-uae]=""
WEB_PKG_FILE[fs-uae_amd64]="$RESSOURCE_SERVER_DIR/web/FS-UAE_3.2.35_Linux_x86-64.tar.xz"
WEB_PKG_CSUM[fs-uae_amd64]="$RESSOURCE_SERVER_DIR/web/FS-UAE_3.2.35_Linux_x86-64.tar.xz.sha"
 WEB_PKG_FILE[fs-uae_i386]=""
 WEB_PKG_CSUM[fs-uae_i386]=""
WEB_PKG_FILE[fs-uae_arm64]="$RESSOURCE_SERVER_DIR/web/FS-UAE_3.2.35_Linux_ARM64.tar.xz"
WEB_PKG_CSUM[fs-uae_arm64]="$RESSOURCE_SERVER_DIR/web/FS-UAE_3.2.35_Linux_ARM64.tar.xz.sha"
WEB_PKG_FILE[fs-uae_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[fs-uae_armhf]="" # NICHT für ARM verfügbar

# Download von https://fs-uae.net/download#linux
# Wird aktuell auf Debian bookworm leider noch nicht unterstützt :(
# ACHTUNG: Als externes Paket muss FS-USE-Launcher mit FS-UAE
# auf der selben Ordner-Ebene liegen (s.a. POST_INST_CONF)
WEB_PKG_NAME[fs-uae-launcher]="FS-UAE-Launcher"
WEB_PKG_CATY[fs-uae-launcher]="Games"
WEB_PKG_VERS[fs-uae-launcher]="3.2.35"
WEB_PKG_MESG[fs-uae-launcher]="" # FS-UAE-Launcher funktioniert nur auf älteren Debian-Versionen.
WEB_PKG_EVAL[fs-uae-launcher]="" # [ $(echo ${OS_V_CODENAME} | grep -i -c -E "bookworm") -eq 0 ]
WEB_PKG_FILE[fs-uae-launcher_amd64]="$RESSOURCE_SERVER_DIR/web/FS-UAE-Launcher_3.2.35_Linux_x86-64.tar.xz"
WEB_PKG_CSUM[fs-uae-launcher_amd64]="$RESSOURCE_SERVER_DIR/web/FS-UAE-Launcher_3.2.35_Linux_x86-64.tar.xz.sha"
 WEB_PKG_FILE[fs-uae-launcher_i386]=""
 WEB_PKG_CSUM[fs-uae-launcher_i386]=""
WEB_PKG_FILE[fs-uae-launcher_arm64]="$RESSOURCE_SERVER_DIR/web/FS-UAE-Launcher_3.2.35_Linux_ARM64.tar.xz"
WEB_PKG_CSUM[fs-uae-launcher_arm64]="$RESSOURCE_SERVER_DIR/web/FS-UAE-Launcher_3.2.35_Linux_ARM64.tar.xz.sha"
WEB_PKG_FILE[fs-uae-launcher_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[fs-uae-launcher_armhf]="" # NICHT für ARM verfügbar

# Download von https://github.com/bpozdena/OneDriveGUI (https://github.com/abraunegg/onedrive)
chk_min_apt_pkg_version "onedrive" "2.5"
CHK_VERSION=$?
if [ $CHK_VERSION -eq 1 ]; then ONEDRIVE_GUI_VER="1.0.3"; fi # Bis OneDrive 2.4.x
if [ $CHK_VERSION -eq 0 ]; then ONEDRIVE_GUI_VER="1.3.0"; fi # Ab OneDrive 2.5.0
if [ $CHK_VERSION -eq 1 ] ||
   [ $CHK_VERSION -eq 0 ];
then
  WEB_PKG_NAME[onedrivegui]="OneDriveGUI"
  WEB_PKG_CATY[onedrivegui]="Utility"
  WEB_PKG_VERS[onedrivegui]="$ONEDRIVE_GUI_VER"
  WEB_PKG_MESG[onedrivegui]=""
  WEB_PKG_EVAL[onedrivegui]=""
  WEB_PKG_FILE[onedrivegui_amd64]="$RESSOURCE_SERVER_DIR/web/OneDriveGUI-$ONEDRIVE_GUI_VER-x86_64.AppImage"
  WEB_PKG_CSUM[onedrivegui_amd64]="$RESSOURCE_SERVER_DIR/web/OneDriveGUI-$ONEDRIVE_GUI_VER-x86_64.AppImage.sha"
  WEB_PKG_FILE[onedrivegui_i386]="" # Nur für 64-bit verfügbar
  WEB_PKG_CSUM[onedrivegui_i386]="" # Nur für 64-bit verfügbar
  WEB_PKG_FILE[onedrivegui_arm64]="" # NICHT für ARM verfügbar
  WEB_PKG_CSUM[onedrivegui_arm64]="" # NICHT für ARM verfügbar
  WEB_PKG_FILE[onedrivegui_armhf]="" # NICHT für ARM verfügbar
  WEB_PKG_CSUM[onedrivegui_armhf]="" # NICHT für ARM verfügbar
fi

# Download von http://oolite.space oder https://github.com/OoliteProject
WEB_PKG_NAME[oolite]="Oolite"
WEB_PKG_CATY[oolite]="Games"
WEB_PKG_VERS[oolite]="1.92"
WEB_PKG_MESG[oolite]=""
WEB_PKG_EVAL[oolite]=""
WEB_PKG_FILE[oolite_amd64]="$RESSOURCE_SERVER_DIR/web/Oolite_1.92-x86_64.AppImage"
WEB_PKG_CSUM[oolite_amd64]="$RESSOURCE_SERVER_DIR/web/Oolite_1.92-x86_64.AppImage.sha"
 WEB_PKG_FILE[oolite_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
 WEB_PKG_CSUM[oolite_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
WEB_PKG_FILE[oolite_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[oolite_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[oolite_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[oolite_armhf]="" # NICHT für ARM verfügbar

# Download von https://www.openshot.org/de/download
WEB_PKG_NAME[openshot]="OpenShot"
WEB_PKG_CATY[openshot]="AudioVideo;Video"
WEB_PKG_VERS[openshot]="3.4.0"
WEB_PKG_MESG[openshot]="Mindestens 4GB RAM erforderlich!"
WEB_PKG_EVAL[openshot]="[ $MEMORY_TOTAL -gt 4000000000 ]"
WEB_PKG_FILE[openshot_amd64]="$RESSOURCE_SERVER_DIR/web/OpenShot-v3.4.0-x86_64.AppImage"
WEB_PKG_CSUM[openshot_amd64]="$RESSOURCE_SERVER_DIR/web/OpenShot-v3.4.0-x86_64.AppImage.sha"
 WEB_PKG_FILE[openshot_i386]="" # Für Linux nur als 64-bit verfügbar
 WEB_PKG_CSUM[openshot_i386]="" # Für Linux nur als 64-bit verfügbar
WEB_PKG_FILE[openshot_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[openshot_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[openshot_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[openshot_armhf]="" # NICHT für ARM verfügbar

# Download von https://github.com/raspberrypi/rpi-imager
# ACHTUNG: Auch als DEB eingetragen (s.o.)
WEB_PKG_NAME[rpi-imager]="Raspberry Pi Imager"
WEB_PKG_CATY[rpi-imager]="System;Utility"
WEB_PKG_VERS[rpi-imager]="2.0.6"
WEB_PKG_MESG[rpi-imager]=""
WEB_PKG_EVAL[rpi-imager]=""
WEB_PKG_FILE[rpi-imager_amd64]="$RESSOURCE_SERVER_DIR/web/Raspberry_Pi_Imager-v2.0.6-desktop-x86_64.AppImage"
WEB_PKG_CSUM[rpi-imager_amd64]="$RESSOURCE_SERVER_DIR/web/Raspberry_Pi_Imager-v2.0.6-desktop-x86_64.AppImage.sha"
 WEB_PKG_FILE[rpi-imager_i386]="" # NUR für 64-bit verfügbar
 WEB_PKG_CSUM[rpi-imager_i386]="" # NUR für 64-bit verfügbar
WEB_PKG_FILE[rpi-imager_arm64]="$RESSOURCE_SERVER_DIR/web/Raspberry_Pi_Imager-v2.0.6-desktop-aarch64.AppImage"
WEB_PKG_CSUM[rpi-imager_arm64]="$RESSOURCE_SERVER_DIR/web/Raspberry_Pi_Imager-v2.0.6-desktop-aarch64.AppImage.sha"
WEB_PKG_FILE[rpi-imager_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[rpi-imager_armhf]="" # NICHT für ARM verfügbar

# Download von https://github.com/rustdesk/rustdesk/releases
# Hinweis: Auch als .deb verfügbar (s.o.)
WEB_PKG_NAME[rustdesk]="RustDesk"
WEB_PKG_CATY[rustdesk]="Network;"
WEB_PKG_VERS[rustdesk]="1.4.5"
WEB_PKG_MESG[rustdesk]=""
WEB_PKG_EVAL[rustdesk]=""
WEB_PKG_FILE[rustdesk_amd64]="$RESSOURCE_SERVER_DIR/web/rustdesk-1.4.5-x86_64.AppImage"
WEB_PKG_CSUM[rustdesk_amd64]="$RESSOURCE_SERVER_DIR/web/rustdesk-1.4.5-x86_64.AppImage.sha"
 WEB_PKG_FILE[rustdesk_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
 WEB_PKG_CSUM[rustdesk_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
WEB_PKG_FILE[rustdesk_arm64]="$RESSOURCE_SERVER_DIR/web/rustdesk-1.4.5-aarch64.AppImage"
WEB_PKG_CSUM[rustdesk_arm64]="$RESSOURCE_SERVER_DIR/web/rustdesk-1.4.5-aarch64.AppImage.sha"
WEB_PKG_FILE[rustdesk_armhf]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
WEB_PKG_CSUM[rustdesk_armhf]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)

# Download von https://www.sarducd.it/downloads
# Hinweis: Derzeit nicht beinhaltet wegen potentiellem Trojaner in Sardu
# WEB_PKG_NAME[sardu]="Sardu"
# WEB_PKG_CATY[sardu]="System;Utility"
# WEB_PKG_VERS[sardu]="4.4.0" # Bei Änderung auch sardu_post_inst anpassen !!!
# WEB_PKG_MESG[sardu]=""
# WEB_PKG_EVAL[sardu]=""
# WEB_PKG_FILE[sardu_amd64]="$RESSOURCE_SERVER_DIR/web/sardu_4.4.0-linux.tar.gz"
# WEB_PKG_CSUM[sardu_amd64]="$RESSOURCE_SERVER_DIR/web/sardu_4.4.0-linux.tar.gz.sha"
#  WEB_PKG_FILE[sardu_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
#  WEB_PKG_CSUM[sardu_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
# WEB_PKG_FILE[sardu_arm64]="" # NICHT für ARM verfügbar
# WEB_PKG_CSUM[sardu_arm64]="" # NICHT für ARM verfügbar
# WEB_PKG_FILE[sardu_armhf]="" # NICHT für ARM verfügbar
# WEB_PKG_CSUM[sardu_armhf]="" # NICHT für ARM verfügbar

# Download von https://www.shotcut.org/download/
WEB_PKG_NAME[shotcut]="Shotcut"
WEB_PKG_CATY[shotcut]="AudioVideo;Video"
WEB_PKG_VERS[shotcut]="26.1.30"
WEB_PKG_MESG[shotcut]="Mindestens 4GB RAM erforderlich!"
WEB_PKG_EVAL[shotcut]="[ $MEMORY_TOTAL -gt 4000000000 ]"
WEB_PKG_FILE[shotcut_amd64]="$RESSOURCE_SERVER_DIR/web/shotcut-linux-x86_64-26.1.30.AppImage"
WEB_PKG_CSUM[shotcut_amd64]="$RESSOURCE_SERVER_DIR/web/shotcut-linux-x86_64-26.1.30.AppImage.sha"
 WEB_PKG_FILE[shotcut_i386]="" # Für Linux nur als 64-bit verfügbar
 WEB_PKG_CSUM[shotcut_i386]="" # Für Linux nur als 64-bit verfügbar
WEB_PKG_FILE[shotcut_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[shotcut_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[shotcut_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[shotcut_armhf]="" # NICHT für ARM verfügbar

# Download von https://www.torproject.org/de/download/
WEB_PKG_NAME[tor-browser]="Tor Browser"
WEB_PKG_CATY[tor-browser]="Network;WebBrowser"
WEB_PKG_VERS[tor-browser]="15.0.5"
WEB_PKG_MESG[tor-browser]=""
WEB_PKG_EVAL[tor-browser]=""
WEB_PKG_FILE[tor-browser_amd64]="$RESSOURCE_SERVER_DIR/web/tor-browser-linux-x86_64-15.0.5.tar.xz"
WEB_PKG_CSUM[tor-browser_amd64]="$RESSOURCE_SERVER_DIR/web/tor-browser-linux-x86_64-15.0.5.tar.xz.sha"
 WEB_PKG_FILE[tor-browser_i386]="" # Für Linux nur als 64-bit verfügbar
 WEB_PKG_CSUM[tor-browser_i386]="" # Für Linux nur als 64-bit verfügbar
WEB_PKG_FILE[tor-browser_arm64]="" # Auf ARM nur für Android verfügbar (Raspberry Pi hat kein SSE2)
WEB_PKG_CSUM[tor-browser_arm64]="" # Auf ARM nur für Android verfügbar (Raspberry Pi hat kein SSE2)
WEB_PKG_FILE[tor-browser_armhf]="" # Auf ARM nur für Android verfügbar (Raspberry Pi hat kein SSE2)
WEB_PKG_CSUM[tor-browser_armhf]="" # Auf ARM nur für Android verfügbar (Raspberry Pi hat kein SSE2)

# Download von https://unetbootin.github.io/
WEB_PKG_NAME[unetbootin]="UNetbootin"
WEB_PKG_CATY[unetbootin]="System;Utility"
WEB_PKG_VERS[unetbootin]="7.0.2"
WEB_PKG_MESG[unetbootin]=""
WEB_PKG_EVAL[unetbootin]=""
WEB_PKG_FILE[unetbootin_amd64]="$RESSOURCE_SERVER_DIR/web/unetbootin-linux64-702.bin"
WEB_PKG_CSUM[unetbootin_amd64]="$RESSOURCE_SERVER_DIR/web/unetbootin-linux64-702.bin.sha"
 WEB_PKG_FILE[unetbootin_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
 WEB_PKG_CSUM[unetbootin_i386]="" # NUR für 64-bit (32-bit verfügbar aber nicht aufgenommen)
WEB_PKG_FILE[unetbootin_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[unetbootin_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[unetbootin_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[unetbootin_armhf]="" # NICHT für ARM verfügbar

# Download von https://codeberg.org/ralfhersel/youplay/releases
WEB_PKG_NAME[youplay]="YouPlay"
WEB_PKG_CATY[youplay]="AudioVideo;Video"
WEB_PKG_VERS[youplay]="0.46"
WEB_PKG_MESG[youplay]="Benötigt mindestens gtk-4.0!"
WEB_PKG_EVAL[youplay]="[ -d /usr/share/gtk-4.0 ]"
WEB_PKG_FILE[youplay_amd64]="$RESSOURCE_SERVER_DIR/web/youplay_v0.46-GTK4-x86_64.AppImage"
WEB_PKG_CSUM[youplay_amd64]="$RESSOURCE_SERVER_DIR/web/youplay_v0.46-GTK4-x86_64.AppImage.sha"
 WEB_PKG_FILE[youplay_i386]="" # Für Linux nur als 64-bit verfügbar
 WEB_PKG_CSUM[youplay_i386]="" # Für Linux nur als 64-bit verfügbar
WEB_PKG_FILE[youplay_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[youplay_arm64]="" # NICHT für ARM verfügbar
WEB_PKG_FILE[youplay_armhf]="" # NICHT für ARM verfügbar
WEB_PKG_CSUM[youplay_armhf]="" # NICHT für ARM verfügbar

#===============================================================================
# Liste von Paketen aus externen Quellen (DEB und WEB), welche keinen eigenen
# Eintrag im Repository haben und somit von apt nicht automatisch aktualisiert
# werden. Dies dient als Basis für die Updates dieser Pakete mit der Option
# "exupdate". Dazu werden natürlich nur Pakete in die Liste aufgenommen, für
# die auch eine aktuelle Versionsnummer in DEB/WEB_PKG_VERS eingetragen ist.
#===============================================================================
EXUPDATE_PKG_LIST=""
# ------------------------------------------------------------------------------
# DEB-Pakete
# ------------------------------------------------------------------------------
for p in ${!DEB_PKG_NAME[@]};
do
  if [ $(echo "$EXUPDATE_PKG_LIST" | grep -c -i -E " $p ") -eq 0 ];
  then
    TEST_VERSION=${DEB_PKG_VERS["$p"]}
    if [ "$TEST_VERSION" != "" ];
    then
      EXUPDATE_PKG_LIST+=" $p "
    fi
  fi
done
# ------------------------------------------------------------------------------
# WEB-Pakete
# ------------------------------------------------------------------------------
for p in ${!WEB_PKG_NAME[@]};
do
  if [ $(echo "$EXUPDATE_PKG_LIST" | grep -c -i -E " $p ") -eq 0 ];
  then
    TEST_VERSION=${WEB_PKG_VERS["$p"]}
    if [ "$TEST_VERSION" != "" ];
    then
      EXUPDATE_PKG_LIST+=" $p "
    fi
  fi
done
# ------------------------------------------------------------------------------
# Liste alphabetisch sortieren
# ------------------------------------------------------------------------------
EXUPDATE_PKG_TEMP=(${EXUPDATE_PKG_LIST})
IFS=$'\n'
EXUPDATE_PKG_LIST=($(sort <<<"${EXUPDATE_PKG_TEMP[*]}"))
IFS=' '

#===============================================================================
# Pakete, die warum auch immer bevorzugt als Flatpak installiert werden sollen.
#===============================================================================
FORCE_FLATPAK_LIST=()

#===============================================================================
# Pakete, die warum auch immer bevorzugt als Snap installiert werden sollen.
#===============================================================================
FORCE_SNAPPY_LIST=('chromium')

#===============================================================================
# Pakete, die warum auch immer aus externen Quellen installiert werden sollen.
#===============================================================================
FORCE_EXTERN_LIST=()

#===============================================================================
# Auf dem Raspberry Pi grundsätzlich mangels Hardware-Support, Performance
# oder anderen Gründen sinnlose und daher auszuschließende Pakete, obwohl
# diese eventuell sogar im Repository enthalten und installierbar sind.
#===============================================================================
# Microsoft-Programme laufen nicht auf einer ARM-Architektur, es sein denn sie
# wurden dafür neu kompiliert - dann braucht man dafür aber kein Wine o.a. ;)
TMP_LIST="microsoft-edge-stable microsoft-edge-dev msr-tools"
# Steam auf dem Pi ist mangels Leistung und Auswahl an ARM-Spielen auch Unsinn
TMP_LIST+=" steam steam-launcher"
# Wine auf dem Pi ist wegen ARM-Architektur ebenfalls für nichts zu gebrauchen
TMP_LIST+=" ${KATEGORIE_PKGS[w]}"
# Aus der Liste ein Array machen
NOT_ON_RASPBERRY=(${TMP_LIST})

#===============================================================================
# Zusätzlich Pakete ausschließen, die auf Pi OS nicht verfügbar sind,
# jedoch in anderen Distribution auf dem Raspberry Pi verfügbar sein können.
#===============================================================================
NOT_ON_PIOS=('gnome-software' 'realvnc-vnc-server' 'usbview' 'ubuntu-mate-welcome')

#===============================================================================
# Wenn zu Programmpaketen VOR deren Installation eine Konfiguration des Systems
# erforderlich ist, kann diese ebenfalls automatisiert durchgeführt werden.
# Dazu kann das entsprechende Kommando entweder direkt angegeben werden, oder
# eine URL zum Download eines auszuführenden Skripts (s.a. RESSOURCE_SERVER_DIR).
# Hinweis: Nach der Ausführung eines externen Skriptes wird das Hauptskript
# (außer im Quiet-Modus) mit einer Aufforderung zum Drücken der Enter-Taste
# pausiert, um Meldungen des externen Skriptes nicht zu überlesen.
# Nach Kommandos wird das Hauptskript nicht pausiert und sofort fortgeführt.
#===============================================================================
declare -A PRE_INST_CONF

PRE_INST_CONF[anydesk]="$RESSOURCE_SERVER_DIR/scripts/anydesk_pre_inst"
PRE_INST_CONF[steam]="$RESSOURCE_SERVER_DIR/scripts/steam_pre_inst"
PRE_INST_CONF[steam-launcher]="$RESSOURCE_SERVER_DIR/scripts/steam_pre_inst"
PRE_INST_CONF[veracrypt]="$RESSOURCE_SERVER_DIR/scripts/veracrypt_pre_inst"
PRE_INST_CONF[wine]="$RESSOURCE_SERVER_DIR/scripts/wine_pre_inst"
PRE_INST_CONF[wine32]="$RESSOURCE_SERVER_DIR/scripts/wine32_pre_inst"
PRE_INST_CONF[wine64]="$RESSOURCE_SERVER_DIR/scripts/wine64_pre_inst"
PRE_INST_CONF[winetricks]="$RESSOURCE_SERVER_DIR/scripts/winetricks_pre_inst"

#===============================================================================
# Wenn zu Programmpaketen NACH deren Installation eine weitere Konfiguration
# erforderlich ist, kann diese ebenfalls automatisiert durchgeführt werden.
# Dazu kann das entsprechende Kommando entweder direkt angegeben werden, oder
# eine URL zum Download eines auszuführenden Skripts (s.a. RESSOURCE_SERVER_DIR).
# Hinweis: Nach der Ausführung eines externen Skriptes wird das Hauptskript
# (außer im Quiet-Modus) mit einer Aufforderung zum Drücken der Enter-Taste
# pausiert, um Meldungen des externen Skriptes nicht zu überlesen.
# Nach Kommandos wird das Hauptskript nicht pausiert und sofort fortgeführt.
#===============================================================================
declare -A POST_INST_CONF

POST_INST_CONF[anydesk]="$RESSOURCE_SERVER_DIR/scripts/anydesk_post_inst"
POST_INST_CONF[apache2]="$RESSOURCE_SERVER_DIR/scripts/apache2_post_inst"
POST_INST_CONF[code-the-classics]="$RESSOURCE_SERVER_DIR/scripts/code-the-classics_post_inst"
POST_INST_CONF[czkawka]="$RESSOURCE_SERVER_DIR/scripts/czkawka_post_inst"
POST_INST_CONF[freefilesync]="$RESSOURCE_SERVER_DIR/scripts/freefilesync_post_inst"
POST_INST_CONF[freetuxtv]="$RESSOURCE_SERVER_DIR/scripts/freetuxtv_post_inst"
POST_INST_CONF[fs-uae]="$RESSOURCE_SERVER_DIR/scripts/fs-uae_post_inst"
POST_INST_CONF[fs-uae-launcher]="$RESSOURCE_SERVER_DIR/scripts/fs-uae-launcher_post_inst"
POST_INST_CONF[hypnotix]="$RESSOURCE_SERVER_DIR/scripts/hypnotix_post_inst"
POST_INST_CONF[iptvnator]="$RESSOURCE_SERVER_DIR/scripts/iptvnator_post_inst"
POST_INST_CONF[keepass2]="$RESSOURCE_SERVER_DIR/scripts/keepass2_post_inst"
POST_INST_CONF[libdvd-pkg]="dpkg-reconfigure libdvd-pkg"
POST_INST_CONF[makemkv-bin]="$RESSOURCE_SERVER_DIR/scripts/makemkv-bin_post_inst"
POST_INST_CONF[microsoft-edge-stable]="rm -f $APT_SOURCES_LIST_DIR/microsoft-edge-stable.list"
POST_INST_CONF[microsoft-edge-dev]="rm -f $APT_SOURCES_LIST_DIR/microsoft-edge-dev.list"
POST_INST_CONF[nextcloud-desktop]="$RESSOURCE_SERVER_DIR/scripts/nextcloud_post_inst"
POST_INST_CONF[oolite]="$RESSOURCE_SERVER_DIR/scripts/oolite_post_inst"
POST_INST_CONF[openssh-server]="echo -n Starte SSH-Dienste ... && service ssh restart &>/dev/null && systemctl enable ssh &>/dev/null && echo ok"
POST_INST_CONF[owncloud-client]="$RESSOURCE_SERVER_DIR/scripts/owncloud_post_inst"
POST_INST_CONF[php]="$RESSOURCE_SERVER_DIR/scripts/php_post_inst"
POST_INST_CONF[proftpd-core]="$RESSOURCE_SERVER_DIR/scripts/proftpd_post_inst"
# Workaround für VNC-Server auf Linux Mint
if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ];
then
  POST_INST_CONF[realvnc-vnc-server]="apt install xterm -y"
fi
POST_INST_CONF[rocksndiamonds]="dpkg-reconfigure rocksndiamonds"
POST_INST_CONF[samba]="$RESSOURCE_SERVER_DIR/scripts/samba_post_inst"
# POST_INST_CONF[sardu]="$RESSOURCE_SERVER_DIR/scripts/sardu_post_inst"
POST_INST_CONF[teamviewer]="$RESSOURCE_SERVER_DIR/scripts/teamviewer_post_inst"
POST_INST_CONF[tor-browser]="$RESSOURCE_SERVER_DIR/scripts/tor-browser_post_inst"
POST_INST_CONF[unetbootin]="$RESSOURCE_SERVER_DIR/scripts/unetbootin_post_inst"
POST_INST_CONF[usbauth-notifier]="$RESSOURCE_SERVER_DIR/scripts/usbauth-notifier_post_inst"
POST_INST_CONF[virtualbox]="usermod -a -G vboxusers $USER_USERNAME"
POST_INST_CONF[virtualbox-7.0]="$RESSOURCE_SERVER_DIR/scripts/virtualbox-7.0_post_inst"
POST_INST_CONF[virtualbox-7.1]="$RESSOURCE_SERVER_DIR/scripts/virtualbox-7.1_post_inst"
POST_INST_CONF[wine]="$RESSOURCE_SERVER_DIR/scripts/wine_post_inst"
POST_INST_CONF[wine-installer]="$RESSOURCE_SERVER_DIR/scripts/wine_post_inst"
POST_INST_CONF[wireguard]="$RESSOURCE_SERVER_DIR/scripts/wireguard_post_inst"

#===============================================================================
# Wenn zu Programmpaketen VOR deren Entfernung eine Konfiguration des Systems
# erforderlich ist, kann diese ebenfalls automatisiert durchgeführt werden.
# Dazu kann das entsprechende Kommando entweder direkt angegeben werden, oder
# eine URL zum Download eines auszuführenden Skripts (s.a. RESSOURCE_SERVER_DIR).
# Hinweis: Nach der Ausführung eines externen Skriptes wird das Hauptskript
# (außer im Quiet-Modus) mit einer Aufforderung zum Drücken der Enter-Taste
# pausiert, um Meldungen des externen Skriptes nicht zu überlesen.
# Nach Kommandos wird das Hauptskript nicht pausiert und sofort fortgeführt.
#===============================================================================
declare -A PRE_REMOVE_CONF

PRE_REMOVE_CONF[veracrypt]="$RESSOURCE_SERVER_DIR/scripts/veracrypt_pre_remove"

#===============================================================================
# Für Progamme, deren Starter nicht den gleichen Dateinamen haben wie das
# Programm selbst, oder für Programmpakete, zu denen mehrere Starter angelegt
# werden sollen, können deren Dateinamen in den folgenden Listen angegeben
# werden (gesucht werden diese in /usr/share/applications).
# ACHTUNG: Die Starter-Dateien (.desktop) werden dazu nur kopiert und nicht
# neu erzeugt, d.h. diese müssen dazu natürlich vorhanden sein.
#===============================================================================
declare -A PKG_STARTER_LIST
declare -A PKG_STARTER_XDIR # Extra Ordner, falls dieser angelegt werden soll

PKG_STARTER_LIST[code-the-classics]="avenger beatstreets boing bunner cavern eggzy kinetix leadingedge myriapod soccer"
PKG_STARTER_XDIR[code-the-classics]="Code the Classics"
PKG_STARTER_LIST[extremetuxracer]="etr"
PKG_STARTER_XDIR[extremetuxracer]=""
PKG_STARTER_LIST[freedoom]="io.github.freedoom.Phase1 io.github.freedoom.Phase2"
PKG_STARTER_XDIR[freedoom]=""
PKG_STARTER_LIST[gnome-games]="aisleriot sol org.gnome.Chess org.gnome.five-or-more org.gnome.Four-in-a-row org.gnome.Hitori org.gnome.Klotski org.gnome.LightsOff org.gnome.Mahjongg org.gnome.Mines org.gnome.Nibbles org.gnome.Quadrapassel org.gnome.Reversi org.gnome.Robots org.gnome.Sudoku org.gnome.SwellFoop org.gnome.Tali org.gnome.Taquin org.gnome.Tetravex org.gnome.TwentyFortyEight"
PKG_STARTER_XDIR[gnome-games]="Gnome Games"
PKG_STARTER_LIST[kdeconnect]=""
PKG_STARTER_XDIR[kdeconnect]="KDE Connect"
PKG_STARTER_LIST[libreoffice]=""
PKG_STARTER_XDIR[libreoffice]="LibreOffice"
PKG_STARTER_LIST[oolite]="oolite.org"
PKG_STARTER_XDIR[oolite]=""
PKG_STARTER_LIST[wine]="wine-browsedrive wine-control wine-explorer wine-iexplore wine-regedit wine-taskmgr wine-uninstaller wine-winecfg wine-wineconsole wine-winemine"
# ---------------------------------------------------------------
# Für Wine individuelle Listen je nach Installations-Art anlegen
# ---------------------------------------------------------------
WINE_STARTER_LIST_APT="${PKG_STARTER_LIST[wine]}"
WINE_STARTER_LIST_FLAT="wine-winetricks-flatpak wine-regedit-flatpak wine-winecfg-flatpak wine-wineconsole-flatpak wine-winemine-flatpak"
# ---------------------------------------------------------------
PKG_STARTER_XDIR[wine]=""
PKG_STARTER_LIST[wine-installer]="${PKG_STARTER_LIST[wine]}"
PKG_STARTER_XDIR[wine-installer]=""
PKG_STARTER_LIST[zynaddsubfx]=""
PKG_STARTER_XDIR[zynaddsubfx]="ZynAddSubFX"

#===============================================================================
# Zusätzliche Unterordner für Starter von Spielen
#===============================================================================
declare -A GAME_DIR_SUB_NAME # Name des Unterordners
declare -A GAME_DIR_SUB_LIST # Liste der Pakete (Starter) für in den Unterordner
# Index-Liste (Kategorien) der Daten zu den Unterordnern
GAME_DIR_CAT_LIST=( 'action' 'adventure' 'blocksnmarbles' 'breakout' 'cardsnboards' 'emulator' 'jumpnrun' 'logic' 'race' 'role' 'shooter' 'simulation' 'sports' 'strategy' )

GAME_DIR_SUB_NAME[action]="Action"
GAME_DIR_SUB_LIST[action]="criticalmass marsshooter open-invaders"

GAME_DIR_SUB_NAME[adventure]="Abenteuer"
GAME_DIR_SUB_LIST[adventure]=""

GAME_DIR_SUB_NAME[blocksnmarbles]="Blöcke und Murmeln"
GAME_DIR_SUB_LIST[blocksnmarbles]="blockout2 biniax2 cuyo flobopuyo frozen-bubble gemdropx gweled jag kdiamond zaz"

GAME_DIR_SUB_NAME[breakout]="Breakout"
GAME_DIR_SUB_LIST[breakout]="briquolo lbreakout2 lbreakouthd sdl-ball"

GAME_DIR_SUB_NAME[cardsnboards]="Karten- und Brettspiele"
GAME_DIR_SUB_LIST[cardsnboards]="brutalchess dreamchess gnubg kmahjongg knights kpat kreversi morris pokerth"

GAME_DIR_SUB_NAME[emulator]="Emulatoren"
GAME_DIR_SUB_LIST[emulator]="fs-uae"

GAME_DIR_SUB_NAME[jumpnrun]="Laufen und Springen"
GAME_DIR_SUB_LIST[jumpnrun]="caveexpress freedroidrpg freegish frogatto kapman lix neverball openclonk pingus rocksndiamonds supertux teeworlds trackballs"

GAME_DIR_SUB_NAME[logic]="Logik- und Denkspiele"
GAME_DIR_SUB_LIST[logic]="atomix enigma gbrainy gcompris gcompris-qt gnome-mastermind katomic numptyphysics peg-e ksudoku pybik tuxmath"

GAME_DIR_SUB_NAME[race]="Rennen"
GAME_DIR_SUB_LIST[race]="armagetronad extremetuxracer speed_dreams stunt_rally supertuxkart torcs trigger-rally"

GAME_DIR_SUB_NAME[role]="Rollenspiele"
GAME_DIR_SUB_LIST[role]=""

GAME_DIR_SUB_NAME[shooter]="Shooter"
GAME_DIR_SUB_LIST[shooter]="alien-arena alienarena freedoom nexuiz openarena quetoo sauerbraten tesseract xonotic"

GAME_DIR_SUB_NAME[simulation]="Simulation"
GAME_DIR_SUB_LIST[simulation]="flightgear"

GAME_DIR_SUB_NAME[sports]="Sport"
GAME_DIR_SUB_LIST[sports]="billard-gl foobillardplus freetennis neverputt pinball ysoccer"

GAME_DIR_SUB_NAME[strategy]="Strategie"
GAME_DIR_SUB_LIST[strategy]="0ad endless-sky megaglest naev oolite ufoai wesnoth widelands zeroad"

#===============================================================================
# Zusätzliche Starter zur Ergänzung von Kategorien.
# ------------------------------------------------------------------------------
# Starter, die nur dann erstellt werden, wenn das entsprechende Programmpaket
# bereits installiert ist. Das betrifft Programme aus Systemerweiterungen oder
# Tools für die Konfiguration von Systemeinstellungen, Kernel-Modulen etc.
# Es werden zudem nur Starter erstellt, die nicht über eine gegebenenfalls
# vorhandene Steuerzentrale zu erreichen sind.
# ------------------------------------------------------------------------------
# Achtung: Die Einträge sind die DATEINAMEN der Starter (ohne Pfadangabe und
# ohne die Endung .desktop), NICHT die Paketnamen!
#===============================================================================
declare -A ADDITIONAL_STARTER # Listen der zusätzlichen Starter je Kategorie
declare -A ADDITIONAL_S_NAMES # Listen der Systemverwaltungs-Starter je Desktop
declare -A ADDITIONAL_DIRNAME # Namen der Sytemverwaltungs-Unterordner je Desktop

# ------------------------------------------------------------------------------
# Netzwerkmanagement
# ------------------------------------------------------------------------------
ADDITIONAL_STARTER[n]="nm-connection-editor"

# ------------------------------------------------------------------------------
# Emulation und Virtualisierung
# ------------------------------------------------------------------------------
ADDITIONAL_STARTER[q]="org.gnome.Boxes"

# ------------------------------------------------------------------------------
# Zusätzliche Starter zu Systemverwaltung allgemein
# --------------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[v],
# welches alle Pakete der Systemverwaltung enthält
# ------------------------------------------------------------------------------
ADDITIONAL_STARTER[v]="ayatana-settings debian-xterm caja-file-management-properties ccsm htop lightdm-settings nvidia-settings software-properties-gtk software-properties-qt time-admin update-manager users users-admin xarchiver xpra-gui xscreensaver-properties xscreensaver-settings xterm"

# ---------------------------------------------------
# Starter nur zur Systemverwaltung von Cinnamon
# ---------------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[ci],
# welches alle Pakete der Cinnamon Tools enthält
# ---------------------------------------------------
ADDITIONAL_S_NAMES[vc]="cinnamon-menu-editor cinnamon-settings"
ADDITIONAL_DIRNAME[vc]="Cinnamon"
# -------------------------------------------
# Starter nur zur Systemverwaltung von GNOME
# -------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[gx],
# welches alle Pakete der GNOME Apps enthält
# -------------------------------------------
ADDITIONAL_S_NAMES[vg]="gparted"
ADDITIONAL_PKG_LIST="disk-image-mounter disk-image-writer language-selector system-monitor system-monitor-kde"
for add_pkg in ${ADDITIONAL_PKG_LIST[@]};
do
  ADDITIONAL_S_NAMES[vg]+=" gnome-$add_pkg"
done
ADDITIONAL_PKG_LIST="baobab DejaDup DiskUtility Firmware FontManager font-viewer Logs PowerStats seahorse.Application Shell Settings Software SystemMonitor Terminal tweaks Usage"
for add_pkg in ${ADDITIONAL_PKG_LIST[@]};
do
  ADDITIONAL_S_NAMES[vg]+=" org.gnome.$add_pkg"
done
ADDITIONAL_DIRNAME[vg]="GNOME"
# ------------------------------------------
# Starter nur zur Systemverwaltung von LXDE
# ------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[lx],
# welches alle Pakete der LXDE Tools enthält
# ------------------------------------------
ADDITIONAL_S_NAMES[vl]=""
ADDITIONAL_DIRNAME[vl]="LXDE"
# ------------------------------------------
# Starter nur zur Systemverwaltung von MATE
# --------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[mx],
# welches alle Pakete der MATE Tools enthält
# ------------------------------------------
ADDITIONAL_S_NAMES[vm]="matecc"
ADDITIONAL_PKG_LIST="control-center disk-image-mounter disk-usage-analyzer font-viewer power-statistics search-tool system-log system-monitor terminal"
for add_pkg in ${ADDITIONAL_PKG_LIST[@]};
do
  ADDITIONAL_S_NAMES[vm]+=" mate-$add_pkg"
done
ADDITIONAL_DIRNAME[vm]="MATE"
# ------------------------------------------
# Starter nur zur Systemverwaltung von XFCE
# ------------------------------------------
# Achtung: Nicht verwechseln mit KATEGORIE_PKGS[xf],
# welches alle Pakete der XFCE Tools enthält
# ------------------------------------------
ADDITIONAL_S_NAMES[vx]="xfce-settings-manager xfce4-taskmanager xfce4-terminal"
ADDITIONAL_DIRNAME[vx]="XFCE"

#===============================================================================
# Pi OS Tools - Namen der Starter (vollständige Dateinamen ohne Pfadangabe
# und Endung, NICHT Paketnamen!), welche auf Pi OS vorinstalliert sind und
# zusätzlich in einen separaten Ordner auf dem Desktop kopiert werden.
#===============================================================================
PIOS_EXT_STARTER=( 'agnostics' 'alacarte' 'arandr' 'Node-RED' 'obconf' 'pcmanfm' 'pcmanfm-desktop-pref' 'piclone' 'pi-gpk-prefs' 'pi-gpk-log' 'pi-gpk-update-viewer' 'pi-packages' 'pipanel' 'rc_gui' 'realvnc-vncviewer' 'rp-bookshelf' 'rp-prefapps' 'sense_emu_gui' 'smartsim' 'sonic-pi' 'wolfram-mathematica' 'wolfram-language' )

#===============================================================================
# Beim Erstellen der Starter werden alle passenden .desktop-Dateien
# berücksichtigt, die keinen Eintrag "NoDisplay=true" haben, oder wenn doch
# zudem einen Eintrag "OnlyShowIn=<DESKTOP_NAME>" enthalten. Letzterer fehlt
# jedoch zuweilen - damit diese Starter trotzdem angelegt werden, können deren
# Paketnamen (NICHT Dateinamen!) in dem Array "FORCE_STARTER" angegeben werden.
#===============================================================================
FORCE_STARTER=( 'caja' 'nemo' 'thunar' 'pi-gpk-prefs' 'pi-gpk-log' 'pi-gpk-update-viewer' )

#===============================================================================
# Auszulassende Starter (nur DATEI-Name ohne Pfadangabe und Endung .desktop),
# welche von vorne herein nicht mit auf den Desktop kopiert werden sollen.
# ------------------------------------------------------------------------------
# ACHTUNG: Bei Einsatz von Wildcards (*) darauf achten, dass diese mit
#          "find -iname" und mit "grep -E" die gleichen Ergebnisse liefern!
#===============================================================================
REJECT_STARTER=('alacarte-made' 'caja-autorun-software' 'caja-browser' 'caja-computer' 'caja-folder-handler' 'caja-home' 'chromium_daemon' 'cinnamon-wayland' 'clamtk-kde' 'idle-python*' 'mate-panel' 'mate-network-scheme' 'mate-theme-installer' 'mozo-made' 'nemo-autostart' 'nemo-autorun-software' 'org.gnome.Evolution-alarm-notify' 'panel-desktop-handler' 'xfce4-run')

#===============================================================================
# Starter die bspw. aufgrund ihres Dateinamens unvermeidbar zusätzlich oder
# falsch angelegt werden und am Ende des Skriptes gelöscht werden sollen.
# Dateinamen werden ebenfalls ohne die Endung ".desktop" angegeben.
#===============================================================================
WRONG_STARTER=('Entwicklung/org.gnome.Keysign' 'Internet/chromium-bsu' 'Spiele/Laufen und Springen/org.neverball.Neverball.Neverputt' 'Spiele/Simulation/flightgear')

#===============================================================================
# Ordner mit systemweiten Startern (.desktop-Dateien)
#===============================================================================
GLOBAL_STARTER_DIR="/usr/share/applications"

#===============================================================================
# Zu manchen Programmpaketen werden keine Symbolbilder (Icons) installiert,
# oder nicht an einem Ort abgelegt, an welchem das System diese finden kann
# (unterhalb von /usr/share/icons/hicolor).
# Zu diesen wird eine gleichnamige Bilddatei im Format .png heruntergeladen
# und in /usr/share/pixmaps abgelegt.
#===============================================================================
PKG_ICON_DIR="/usr/share/icons"
PKG_IPIX_DIR="/usr/share/pixmaps"

#===============================================================================
# Namen der Benutzer-Ordner zur gegenseitigen Verlinkung oder Anpassung
#===============================================================================
declare -A FOLDER_NAME_DE # deutsch
declare -A FOLDER_NAME_EN # englisch
FOLDER_NAME_DE[0]="Schreibtisch"
FOLDER_NAME_EN[0]="Desktop"
FOLDER_NAME_DE[1]="Vorlagen"
FOLDER_NAME_EN[1]="Templates"
FOLDER_NAME_DE[2]="Öffentlich"
FOLDER_NAME_EN[2]="Public"
FOLDER_NAME_DE[3]="Dokumente"
FOLDER_NAME_EN[3]="Documents"
FOLDER_NAME_DE[4]="Musik"
FOLDER_NAME_EN[4]="Music"
FOLDER_NAME_DE[5]="Bilder"
FOLDER_NAME_EN[5]="Pictures"

#===============================================================================
# Desktop-Ordner des Benutzers (zur Erstellung der Starter / Programm-Symbole)
# ----------------------------------------------------------------------------
# Der Übersicht halber werden die Starter nicht alle direkt auf den Desktop
# kopiert, sondern in Ordnern mit den jeweiligen Kategorienamen abgelegt
# (außer bei GNOME-Desktops - da auf diesen leider keine ausführbaren Dateien
# in Unterordnern liegen dürfen, liegen da alle Starter direkt auf dem Desktop)
# ACHTUNG: Angaben OHNE Slash (/) am Ende!
#===============================================================================
DESKTOP_DIR=""
if [ -d "$USER_HOME_DIR/Schreibtisch" ] &&
   [ ! -L "$USER_HOME_DIR/Schreibtisch" ];
then
  DESKTOP_DIR="$USER_HOME_DIR/Schreibtisch"
else
  if [ -d "$USER_HOME_DIR/Desktop" ] &&
     [ ! -L "$USER_HOME_DIR/Desktop" ];
  then
    DESKTOP_DIR="$USER_HOME_DIR/Desktop"
  fi
fi
DESKTOP_STARTER_DIR="$DESKTOP_DIR"
if [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
then
  DESKTOP_STARTER_DIR+="/Neue Starter"
fi

#===============================================================================
# Zähler
#===============================================================================
PAKETS_COUNTER=0       # Zähler der Pakete (Laufende Nummer)
PAKETS_EXIST=0         # Bereits installierte Pakete
PAKETS_AVAIL=0         # Neu installierte bzw. zur Installation verfügbare Pakete
PAKETS_NOAVAIL=0       # Nicht verfügbare Pakete
PAKETS_SIMILAR_EXIST=0 # Bereits installierte alternative Pakete
PAKETS_SIMILAR_AVAIL=0 # Neu installierte bzw. zur Installation verfügbare alternative Pakete
PAKETS_SIMILAR_NOAVA=0 # Nicht verfügbare alternative Pakete
PAKETS_SKIP=0          # Übersprungene Pakete (bspw. weil Raspberry Pi oder Nein nach Abfrage)

################################################################################
#                                                                              #
#                                Here we go ...                                #
#                                                                              #
################################################################################
# ==============================================================================
# Boot-Informationen ermitteln
# ==============================================================================
#------------
# Boot-Modus
#------------
if [ $(dmesg 2>/dev/null | grep -c -i -E "\befi\b") -gt 0 ] &&
   [ -d "/sys/firmware/efi" ];
then
  BOOT_MODE="EFI"
else
  BOOT_MODE="BIOS"
fi
#------------------
# Boot-Partitionen
#------------------
root_partition="$(findmnt -n / 2>/dev/null | awk '{ print $2 }' | xargs 2>/dev/null)"
root_partition_name=$(lsblk -l -n -o label ${root_partition} 2>/dev/null | xargs 2>/dev/null)
root_partition_label=$(lsblk -l -n -o partlabel ${root_partition} 2>/dev/null | xargs 2>/dev/null)
boot_device="$(echo ${root_partition} | sed -E "s/p*[0-9]*$//" | xargs 2>/dev/null)"
#----------------------
# EFI-System-Partition
#----------------------
get_esp_uuids

# ==============================================================================
# Listen zur Auswahl der Kategorien und Optionen initialisieren
# ==============================================================================
reset_categories_selection
reset_options_selection 0

# ==============================================================================
# Kopfzeile anzeigen
# ==============================================================================
show_headlines

# ==============================================================================
# Benutzerspezifische Konfiguration löschen
# (nach Aufruf mit Parameter "reset" und vor der Anzeige des Menüs)
# ==============================================================================
if [ $RESET_CONFIG -eq 1 ];
then
  reset_user_config
fi

# ==============================================================================
# Starter für uns selbst auf dem Desktop anlegen
# ==============================================================================
STARTER_FILE="$DESKTOP_DIR/$SCRIPT_NAME.desktop"
if [ -e "$DESKTOP_DIR" ] &&
   [ ! -s "$STARTER_FILE" ];
then
  e_and_l " $HINWEIS_TAG: Es scheint kein ${light_cyan}Starter${colors_off} für Lissy v$VERSION angelegt zu sein."
  ask_yes_or_no_plus "desktop_starter" " Jetzt Starter (Symbol) auf dem Desktop anlegen" "" "j"
  if [ $? -eq 1 ];
  then
    e_and_l -n " Erstelle Starter ... "
    echo -e "[Desktop Entry]" > "$STARTER_FILE" 2>/dev/null
    if [ $? -eq 0 ];
    then
      echo -e "Type=Application" >> "$STARTER_FILE" 2>/dev/null
      # echo -e "Name=Lissy\\\n(Terminal)" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Name=Lissy" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Comment=Linux System Setup Utility" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Exec=bash -c 'cd $SCRIPT_PATH && sudo --preserve-env=XDG_SESSION_TYPE ./$SCRIPT_NAME;\$SHELL'" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Icon=lissy" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Categories=System;" >> "$STARTER_FILE" 2>/dev/null
      echo -e "Terminal=true" >> "$STARTER_FILE" 2>/dev/null
      echo -e "StartupNotify=true" >> "$STARTER_FILE" 2>/dev/null
      echo -e "NoDisplay=false" >> "$STARTER_FILE" 2>/dev/null
      chown -R "$USER_USERNAME:$USER_USERNAME" "$STARTER_FILE" &>/dev/null
      chmod -R 0755 "$STARTER_FILE" &>/dev/null
      make_starter_trusted "$STARTER_FILE"
      e_and_l "$OK_TAG"
    else
      e_and_l "$ERROR_TAG"
    fi
  fi
  show_headlines
fi

# ==============================================================================
# Zuvor erstellten Starter für uns selbst auch im System-Menü anlegen
# Auf diese Weise, damit die vom System automatisch eingefügten Steuerzeichen
# dabei entfernt werden können, da Letztere die Menü-Darstellung unterbinden.
# ==============================================================================
STARTMENU_FILE="$STARTMENU_DIR/$SCRIPT_NAME.desktop"
if [ -s "$STARTER_FILE" ] &&
   [ -d "$STARTMENU_DIR" ] &&
   [ ! -s "$STARTMENU_FILE" ];
then
  cat "$STARTER_FILE" | tr -dc '[:print:]\n' > "$STARTMENU_FILE" 2>/dev/null
  sed -i -E "s/\\\n\(Terminal\)//i" "$STARTMENU_FILE"
  chown -R "$USER_USERNAME:$USER_USERNAME" "$STARTMENU_FILE" &>/dev/null
  chmod -R 0644 "$STARTMENU_FILE" &>/dev/null
fi

# ------------------------------------------
# Aktuelles Icon für den Starter downloaden
# ------------------------------------------
download_icon_file "lissy" 1

# ==============================================================================
# Laufzeit-Parameter ermitteln
# Reihenfolge: 1. Einlesen der Konfigurations-Datei
#              2. Analyse der Kommandozeilen-Argumente
#              3. Menü (Dialog)
# ==============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 1. Individuell (benutzerspezifisch) gespeicherte Konfigurations-Dateien
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if [ $NO_CONFIG -eq 0 ] &&
   [ $RESET_CONFIG -eq 0 ];
then
  # ----------------------------------------------------------------------------
  # Einstellungen
  # ----------------------------------------------------------------------------
  if [ -s "$USER_SCRIPT_CONFIG" ];
  then
    . "$USER_SCRIPT_CONFIG"
    # -----------------------------------------------------------------------
    # Sicherheitshalber die Flags für die Optionen "Nur Status anzeigen" und
    # "Überspringen der Ja/Nein-Abfrage vor Installation" auf inaktiv setzen
    # -----------------------------------------------------------------------
    OPTION_FLAG[status]=0
    OPTION_FLAG[force]=0
  fi
  # ----------------------------------------------------------------------------
  # Paket-Listen und Skip-Liste
  # ----------------------------------------------------------------------------
  if [ -s "$USER_PAKET_LIST" ];
  then
    . "$USER_PAKET_LIST"
    # ---------------------------------------------------------------------
    # Die Skip-Liste in der Datei USER_PAKET_LIST ist eine Text-Zeile, die
    # vor der Verarbeitung in eine "echte" Liste umgewandelt werden muss:
    # ---------------------------------------------------------------------
    if [ "$SKIP_LIST" != "" ];
    then
      SKIP_LIST=(${SKIP_LIST})
    fi
  else
    SKIP_LIST=()
  fi
fi

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 2. Als Kommandozeilen-Argumente angegebene Paketauswahl und Optionen
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ARGUMENT_LIST=()
if [ $RESET_CONFIG -eq 0 ];
then
  for arg in $@;
  do
    arg=$(printf %b "${arg}" | tr A-Z a-z)
    ARGUMENT_LIST+=("$arg")
  done
fi
ARG_ANZ=${#ARGUMENT_LIST[@]}
# -------------------------------------------------------------
# Ermitteln ob ein einzelnes Paket installiert werden soll
# -------------------------------------------------------------
ARG_POS=1
INST_ONLY_PKG=""
for arg in ${ARGUMENT_LIST[@]};
do
  # Erstes Argument hinter "instonly" als zu installierendes Paket ermitteln
  ((ARG_POS+=1))
  if [ "$arg" == "instonly" ];
  then
    # Hinweis: In regulärem Ausdruck für sed die Leerzeichen NICHT ans Ende und
    # - (minus) IMMER ans Ende setzen, da sed diese sonst falsch interpretiert!
    INST_ONLY_PKG=$(echo "${!ARG_POS}" | tr A-Z a-z | sed -E "s/[^a-z0-9 \.\_\-]//gi" | sed -E "s/ /\_/g" | xargs)
    break
  fi
done
# ----------------------------------------------------------
# Ermitteln ob ein einzelnes Paket entfernt werden soll
# ----------------------------------------------------------
ARG_POS=1
OPTION_FLAG[remove]=0
REMOVE_PKG_NAME=""
for arg in ${ARGUMENT_LIST[@]};
do
  # Erstes Argument hinter "remove" als zu entfernendes Paket ermitteln
  ((ARG_POS+=1))
  if [ "$arg" == "remove" ];
  then
    # Hinweis: In regulärem Ausdruck für sed die Leerzeichen NICHT ans Ende und
    # - (minus) IMMER ans Ende setzen, da sed diese sonst falsch interpretiert!
    REMOVE_PKG_NAME=$(echo "${!ARG_POS}" | tr A-Z a-z | sed -E "s/[^a-z0-9 \.\_\-]//gi" | sed -E "s/ /\_/g" | xargs)
    if [ "$REMOVE_PKG_NAME" != "" ];
    then
      OPTION_FLAG[remove]=1
      break
    fi
  fi
done
# -------------------------------------------------------------
# Ermitteln ob eine Liste von Paketen installiert werden soll
# -------------------------------------------------------------
ARG_POS=1
INST_LIST_FILE=""
USE_ILIST_FILE=0
for arg in ${ARGUMENT_LIST[@]};
do
  # Erstes Argument hinter "instlist" der Dateiname der Liste
  ((ARG_POS+=1))
  if [ "$arg" == "instlist" ];
  then
    INST_LIST_FILE=$(echo "${!ARG_POS}" | sed -E "s/[^a-z0-9 \~\/\.\_\-]//gi" | xargs)
    if [ "$INST_LIST_FILE" != "" ];
    then
      if [ -s "$INST_LIST_FILE" ] &&
         [ ! -d "$INST_LIST_FILE" ];
      then
        USE_ILIST_FILE=1
        break
      fi
    fi
  fi
done

# -----------------------------------------------------------------------------------
# Auswahl (+) der Kategorien (nur wenn kein individuelles Paket angegeben wurde)
# -----------------------------------------------------------------------------------
if [ "$INST_ONLY_PKG" == "" ];
then
  # Zunächst auf die Option "all" prüfen
  for arg in ${ARGUMENT_LIST[@]};
  do
    if [ "$arg" == "all" ] ||
       [ "$arg" == "+all" ];
    then
      for k in ${KAT_KEYS_STD[@]};
      do
        KATEGORIE_FLAG[$k]=1
      done
      # "all" beinhaltet jedoch nicht die zusätzlichen Desktop-Tools
      for k in ${KAT_KEYS_ADD[@]};
      do
        KATEGORIE_FLAG[$k]=0
      done
    fi
  done
  # Danach "restliche" bzw. individuelle Kategorie-Auswahl (+) einlesen
  # (Nach "all", damit die Desktop-Tools separat ausgewählt werden können)
  for arg in ${ARGUMENT_LIST[@]};
  do
    for k in ${KAT_KEY_LIST[@]};
    do
      if [ "$arg" == "+$k" ];
      then
        KATEGORIE_FLAG["$k"]=1
        break
      fi
    done
  done
fi
# ------------------------------------------------------------------
# Abwahl (-) der Kategorien sowie ggf. zu überspringende Pakete
# ------------------------------------------------------------------
# Liste der Argumente (Parameter) erzeugen, welche die Auflistung
# der auszulassenden Pakete nach dem Argumente "skippkgs" unterbrechen
SKIP_BREAK_ARGS=()
for k in ${KAT_KEY_LIST[@]};
do
  SKIP_BREAK_ARGS+=("+$k")
  SKIP_BREAK_ARGS+=("-$k")
done
SKIP_BREAK_ARGS+=("+all" "all")
for opt in ${OPTION_LIST[@]};
do
  SKIP_BREAK_ARGS+=("$opt")
done
SKIP_BREAK_ARGS+=("noconfig")
SKIP_BREAK_ARGS+=("nomenu")
SKIP_BREAK_ARGS+=("recall")
SKIP_BREAK_ARGS+=("reset")
# -----------------------------
ARG_POS=1
for arg in ${ARGUMENT_LIST[@]};
do
  # Alle Argumente hinter "skippkgs" bis zu einem anderen gültigen Argument (siehe
  # SKIP_BREAK_ARGS) als auszulassendes Paket in die Skip-Liste übernehmen
  if [ "$arg" == "skippkgs" ];
  then
    BREAK_FOUND=0
    s=$((ARG_POS+1))
    while [ $s -le $ARG_ANZ ] && [ $BREAK_FOUND -eq 0 ]
    do
      ARG_TXT=$(printf %b "${!s}" | tr A-Z a-z)
      for exclude_arg in ${SKIP_BREAK_ARGS[@]};
      do
        if [ "$ARG_TXT" == "$exclude_arg" ];
        then
          BREAK_FOUND=1
          break
        fi
      done
      if [ $BREAK_FOUND -eq 0 ];
      then
        # Bereits in der Skip-Liste vorhandene Pakete nicht nochmals aufnehmen
        IS_ALREADY_SKIPPED=0
        for skipped_pkg in ${SKIP_LIST[@]};
        do
          if [ "$skipped_pkg" == "$ARG_TXT" ];
          then
            IS_ALREADY_SKIPPED=1
            break
          fi
        done
        if [ $IS_ALREADY_SKIPPED -eq 0 ];
        then
          SKIP_LIST=("${SKIP_LIST[@]}" "$ARG_TXT")
        fi
      fi
      ((s+=1))
    done
  else # ... sonst - sofern das Argument eine Kategorie ist - diese abwählen
    for k in ${KAT_KEY_LIST[@]};
    do
      if [ "$arg" == "-$k" ];
      then
        KATEGORIE_FLAG["$k"]=0
        break
      fi
    done
  fi
  ((ARG_POS+=1))
done

# -------------
# Optionen
# -------------
for arg in ${ARGUMENT_LIST[@]};
do
  for opt in ${OPTION_LIST[@]};
  do
    if [ "$arg" == "$opt" ];
    then
      OPTION_FLAG["$opt"]=1
      break
    fi
  done
  # Sonderfälle
  if [ "$arg" == "kuplock" ] && [ $KERNEL_IS_LOCKED -gt 0 ]; then OPTION_FLAG[kuplock]=0; fi
  if [ "$arg" == "kunlock" ] && [ $KERNEL_IS_LOCKED -eq 0 ]; then OPTION_FLAG[kunlock]=0; fi
done

# Sonderfall Quiet-Modus, der aus Sicherheitsgründen aktuell immer deaktiviert ist!
OPTION_FLAG[quiet]=0

# ------------------------------------------------------------------------------
# Neueste Version von diesem Skript runterladen, prüfen und ggf. einrichten
# Wichtig: NACH der Kommandozeilen-Analyse und VOR dem Menü (damit diese
# Prüfung vom Benutzer mit "noupdate" übersprungen werden kann)
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[noupdate]} -eq 0 ];
then
  LOCAL_DOWNLOAD_FILE="./$SCRIPT_NAME.new"
  wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$THIS_SCRIPT_URL" &>/dev/null
  if [ $? -eq 0 ] &&
     [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
     [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
  then
    chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
    chmod -R 0755 "$LOCAL_DOWNLOAD_FILE" &>/dev/null
    NEW_VERSION=$(grep -i -E "^\s*version=" "$LOCAL_DOWNLOAD_FILE" | sed -E "s/^\s*version=//i" | sed -E "s/\"//g" | xargs)
    OLD_VERSION_VALUE=$(get_version_value ${VERSION})
    NEW_VERSION_VALUE=$(get_version_value ${NEW_VERSION})
    if [ $OLD_VERSION_VALUE -lt $NEW_VERSION_VALUE ];
    then
      # show_headlines
      e_and_l " Version ${light_yellow}$NEW_VERSION${colors_off} ist verfügbar. Es wird empfohlen, die neue Version zu verwenden."
      ask_yes_or_no_plus "" " Alte Version sichern und neue Version verwenden" "$LOCAL_DOWNLOAD_FILE" "j"
      if [ $? -eq 1 ];
      then
        mv -f "${0}" "${0}.bak" &>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l " Alte Version gesichert als ${bold_magenta}${0}.bak${colors_off}"
          if [ -s "$USER_PAKET_LIST" ];
          then
            e_and_l " $ACHTUNG_TAG: Es sind individuell angepasste Paket-Listen/Kategorien gespeichert."
            e_and_l " Dadurch werden die in den Kategorien eventuell neu hinzu gekommenen sowie"
            e_and_l " weggefallenen Programmpakete bei diesen Kategorien nicht berücksichtigt."
            ask_yes_or_no_plus "" " Individuelle Listen sichern und neue Listen verwenden" "" "j"
            if [ $? -eq 1 ];
            then
              mv -f "$USER_PAKET_LIST" "$USER_PAKET_LIST.bak" &>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l " Alte Listen gesichert in ${bold_magenta}$USER_PAKET_LIST.bak${colors_off}"
              fi
            fi
          fi
          mv -f "$LOCAL_DOWNLOAD_FILE" "${0}"
          if [ $? -eq 0 ];
          then
            # e_and_l " ${bold_white}$SCRIPT_NAME${colors_off} wurde aktualisiert und beendet - bitte jetzt neu aufrufen ... $OK_TAG"
            e_and_l " ${bold_white}Lissy${colors_off} wurde erfolgreich aktualisiert ... $OK_TAG"
            e_and_l -n " Bitte eine beliebige Taste drücken zum Neustart von Lissy ... "
            read -N 1 -r -s ANSWER
            $0 "$@"
          else
            e_and_l " $ERROR_TAG: Die Aktualisierung konnte leider ${bold_red}nicht${colors_off} korrekt durchgeführt werden."
            e_and_l " Zum Überspringen der Aktualisierung bitte die Option ${light_cyan}noupdate${colors_off} verwenden."
          fi
          exit 0
        else
          e_and_l "$ERROR_TAG: Sicherung konnte nicht angelegt werden"
        fi
      else
        remove_file "$LOCAL_DOWNLOAD_FILE"
      fi
    else
      remove_file "$LOCAL_DOWNLOAD_FILE"
    fi
  else
    remove_file "$LOCAL_DOWNLOAD_FILE"
  fi
fi # Ende [noupdate]

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 3. Auswahlmenü anzeigen
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MENU_INFO_TEXT=""
MENU_ERROR_TEXT=""
if [ $SHOW_HELP -eq 0 ] &&
   [ $NO_MENU -eq 0 ];
then
  # "dialog" installieren, wenn es das noch nicht ist
  if [ $(LANG=C dpkg-query -W -f='${Status}' "dialog" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
  then
    if [ $(apt list "dialog" 2>/dev/null | grep -i -c -E "dialog") -gt 0 ];
    then
      do_log -n " Installiere dialog ... "
      apt install "dialog" -y &>/dev/null
      if [ $? -eq 0 ];
      then
        do_log "ok"
      else
        do_log "Fehler"
        NO_MENU=1
      fi
    else
      NO_MENU=1
    fi
  fi
  # ----------------------------------------------------------------------------
  # Menü nur anzeigen, wenn "dialog" verfügbar ist
  # ----------------------------------------------------------------------------
  if [ $NO_MENU -eq 0 ];
  then
    # -------------------------
    # Menü-Titel zusammenbauen
    # -------------------------
    MENU_TITLE=" "
    MENU_TILE_TEXT="  $HEADLINE_TITLE v $VERSION  "
    MENU_TITLE_LENGTH=${#MENU_TILE_TEXT}
    MENU_SPACES=$((USE_COLUMNS - $MENU_TITLE_LENGTH - 4))
    MENU_PREV=$((MENU_SPACES / 2))
    MENU_POST=$((MENU_SPACES - $MENU_PREV))
    for ((i=0; i<$MENU_PREV; i++)); do MENU_TITLE+="─"; done;
    MENU_TITLE+="$MENU_TILE_TEXT"
    for ((i=0; i<$MENU_POST; i++)); do MENU_TITLE+="─"; done;
    # -------------------------------------------------------------------
    # Konfigurations-Datei für "dialog" anlegen, wenn es noch keine gibt
    # -------------------------------------------------------------------
    DIALOG_RC_FILE="$DOWNLOAD_DIR/dialogrc"
    REMOVE_DIALOG_RC=0
    if [ ! -f "$DIALOG_RC_FILE" ];
    then
# START ---------------------------------------------
cat > "$DIALOG_RC_FILE" <<EOF
aspect = 0
separate_widget = ""
tab_len = 0
visit_items = OFF
use_shadow = ON
use_colors = ON
screen_color = (WHITE,BLUE,OFF)
shadow_color = (BLACK,BLACK,OFF)
dialog_color = (BLACK,WHITE,ON)
title_color = (BLUE,WHITE,ON)
border_color = (WHITE,WHITE,OFF)
button_active_color = (WHITE,WHITE,OFF)
button_inactive_color = (WHITE,WHITE,OFF)
button_key_active_color = (WHITE,BLUE,ON)
button_key_inactive_color = (BLACK,WHITE,ON)
button_label_active_color = (WHITE,BLUE,ON)
button_label_inactive_color = (BLACK,WHITE,ON)
inputbox_color = (WHITE,BLUE,ON)
inputbox_border_color = (BLACK,WHITE,OFF)
searchbox_color = (BLACK,WHITE,OFF)
searchbox_title_color = (BLUE,WHITE,ON)
searchbox_border_color = (WHITE,WHITE,ON)
position_indicator_color = (BLUE,WHITE,ON)
menubox_color = (BLACK,WHITE,OFF)
menubox_border_color = (WHITE,WHITE,ON)
item_color = (BLACK,WHITE,ON)
item_selected_color = (WHITE,BLUE,ON)
tag_color = (BLACK,WHITE,ON)
tag_selected_color = (WHITE,BLUE,ON)
tag_key_color = (BLACK,WHITE,ON)
tag_key_selected_color = (WHITE,BLUE,ON)
check_color = (BLACK,WHITE,ON)
check_selected_color = (WHITE,BLUE,ON)
uarrow_color = (BLUE,WHITE,ON)
darrow_color = (BLUE,WHITE,ON)
itemhelp_color = (YELLOW,BLACK,OFF)
form_active_text_color = (WHITE,BLUE,ON)
form_text_color = (WHITE,CYAN,ON)
form_item_readonly_color = (CYAN,WHITE,ON)
EOF
# ENDE ---------------------------------------------
      if [ $? -eq 0 ];
      then
        chown -R "$USER_USERNAME:$USER_USERNAME" "$DIALOG_RC_FILE" &>/dev/null
        REMOVE_DIALOG_RC=1
      fi
    fi
    if [ -s "$DIALOG_RC_FILE" ];
    then
      export DIALOGRC="$DIALOG_RC_FILE"
    fi
    clear
    setterm -cursor off 2>/dev/null
    # ---------------------------------------------
    # Hinweis falls kein Debian-basierendes System
    # ---------------------------------------------
    if [ $IS_DEBIAN -eq 0 ];
    then
      MENU_ERROR_TEXT="\Z5\ZbAchtung\Zn: Dieses Tool ist nicht für dieses Betriebssystem entwickelt worden.\nDie Benutzung erfolgt auf eigene Gefahr!"
      dialog --backtitle "$MENU_TITLE" --defaultno --no-mouse --no-lines --no-shadow --colors --msgbox "$MENU_ERROR_TEXT" 7 50 3>&1 1>&2 2>&3
    fi
    dialog --clear
    clear
    MAIN_MENU_HELP="[Enter]=Auswahl [ESC]=Ende"
    SUB_MENU_HELP="[Leertaste]=Auswahl [Enter]=Bestätigen"
    # --------------------------------------------
    # Überschriften der Seite und der Menü-Punkte
    # --------------------------------------------
    declare -A MENU_NAME
    MENU_NAME[0]="Individuelles Programmpaket installieren"
    MENU_NAME[1]="Auswahl der zu installierenden Kategorien"
    MENU_NAME[2]="Optionen zur Installation von Paketen"
    MENU_NAME[3]="Programmpaket wahlweise mit Daten löschen"
    MENU_NAME[4]="Erweiterungen und optionale Aktionen"
    MENU_NAME[5]="Einstellungen des Programms"
    # --------------------------------------------
    MENU_OK=1
    while [ $MENU_OK -ne 0 ];
    do
      MENU_AUSWAHL=-1
      if [ "$INST_ONLY_PKG" == "" ];
      then
        LAST_MENU_AUSWAHL=6 # Markierung (Cursor) steht auf Menü-Trennlinie
      else
        LAST_MENU_AUSWAHL=0 # Markierung (Cursor) steht auf erstem Menü-Eintrag
      fi
      while [ $MENU_AUSWAHL -lt 7 ];
      do
        # ----------------------------------------------------------------------
        # Hauptmenü
        # ACHTUNG: Bei Änderung der Reihenfolge auch die Zuordnung von
        #          OPTION_MENU zu MENU_AUSWAHL anpassen!
        # ----------------------------------------------------------------------
        IND_PKG_I_STAR=""
        if [ "$INST_ONLY_PKG" != "" ]; then IND_PKG_I_STAR=" +"; fi
        IND_PKG_R_STAR=""
        if [ "$REMOVE_PKG_NAME" != "" ]; then IND_PKG_R_STAR=" +"; fi
         MAIN_MENU_LIST=(0 "${MENU_NAME[0]}$IND_PKG_I_STAR" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(1 "${MENU_NAME[1]}" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(2 "${MENU_NAME[2]}" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(3 "${MENU_NAME[3]}$IND_PKG_R_STAR" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(4 "${MENU_NAME[4]}" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(5 "${MENU_NAME[5]}" "$MAIN_MENU_HELP")
        MAIN_MENU_LIST+=(6 "──────────────────" "Bitte oben gewünschte Aktion(en) auswählen und dann die Ausführung starten")
        MAIN_MENU_LIST+=(7 "Ausführung starten" "$MAIN_MENU_HELP")
        MENU_AUSWAHL=$(dialog --backtitle "$MENU_TITLE" --item-help --default-item "$LAST_MENU_AUSWAHL" --no-tags --no-ok --no-cancel --no-mouse --no-lines --no-shadow --colors --menu "\Z4\Zb Hauptmenü\Zn" 0 0 0 "${MAIN_MENU_LIST[@]}" 3>&1 1>&2 2>&3)
        if [ $? -ne 0 ]; then MENU_AUSWAHL=-1; fi
        MENU_AUSWAHL=$(echo "$MENU_AUSWAHL" | sed -E 's/[^0-9\-]//g' | xargs)
        LAST_MENU_AUSWAHL="$MENU_AUSWAHL"
        dialog --clear
        clear
        # ----------------------------------------------------------------------
        # Eingabe eines individuellen Pakets
        # ----------------------------------------------------------------------
        if [ $MENU_AUSWAHL -eq 0 ];
        then
          setterm -cursor on 2>/dev/null
          NEW_INST_ONLY=$(dialog --backtitle "$MENU_TITLE" --no-mouse --no-lines --no-shadow --colors --inputbox "Name des zu installierenden Pakets:" 8 50 "$INST_ONLY_PKG" 3>&1 1>&2 2>&3)
          if [ $? -eq 0 ];
          then
            # Flatpak-Paketnamen können Leerzeichen enthalten,
            # Leerzeichen daher als Eingabe erlauben und maskieren
            # Hinweis: In regulärem Ausdruck für sed die Leerzeichen NICHT ans Ende und
            # - (minus) IMMER ans Ende setzen, da sed diese sonst falsch interpretiert!
            INST_ONLY_PKG=$(echo "$NEW_INST_ONLY" | tr A-Z a-z | sed -E "s/[^a-z0-9 \.\_\-]//gi" | sed -E "s/ /\_/g" | xargs)
            if [ "$INST_ONLY_PKG" != "" ];
            then
              OPTION_FLAG[instonly]=1
            else
              OPTION_FLAG[instonly]=0
            fi
          fi
          setterm -cursor off 2>/dev/null
          dialog --clear
          clear
        fi
        # ----------------------------------------------------------------------
        # Auswahl der Paket-Kategorien
        # ----------------------------------------------------------------------
        if [ $MENU_AUSWAHL -eq 1 ];
        then
          if [ "$INST_ONLY_PKG" == "" ];
          then
            ANZ_KATEGORIES=0
            KAT_MENU_LIST=()
            for k in ${KAT_ORD_LIST[@]};
            do
              # ------------------------------------------------------------
              # Menüpunkt nur anzeigen, wenn die System-Umgebung dazu passt
              # ------------------------------------------------------------
              if [[ "$k" != "mt" || $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ]] &&
                 [[ "$k" != "ci" || "$DESKTOP_ENVIRONMENT" == "Cinnamon" ]];
              # ------------------------------------------------------------
              then
                if [ "$k" == "xlinex" ];
                then
                  KAT_MENU_LIST+=("$k" "──────────────────────────────" "off" "[Enter]=Bestätigen")
                else
                  KAT_MENU_LIST+=("$k" "${KATEGORIE_TEXT[$k]}")
                  if [ ${KATEGORIE_FLAG[$k]} -eq 1 ];
                  then
                    KAT_MENU_LIST+=("on")
                  else
                    KAT_MENU_LIST+=("off")
                  fi
                  KAT_MENU_LIST+=("Kommandozeilen-Parameter: $k $SUB_MENU_HELP")
                fi
                ((ANZ_KATEGORIES+=1))
              fi
            done
            # -------------------------------------
            # Auswahlliste der Kategorien anzeigen
            # -------------------------------------
            SELECT_AUSWAHL=$(dialog --backtitle "$MENU_TITLE" --item-help --no-tags --no-cancel --no-mouse --no-lines --no-shadow --output-separator " " --colors --checklist "\Z4\Zb ${MENU_NAME[$MENU_AUSWAHL]}\Zn" 0 0 ${ANZ_KATEGORIES} "${KAT_MENU_LIST[@]}" 3>&1 1>&2 2>&3)
            # -------------------------------------------------
            # Alte Kategorie-Auswahl löschen und neue einlesen
            # -------------------------------------------------
            if [ $? -eq 0 ];
            then
              reset_categories_selection
              for k in ${SELECT_AUSWAHL[@]};
              do
                KATEGORIE_FLAG[$k]=1
              done
            fi
          else
            MENU_ERROR_TEXT="Bei Auswahl eines individuellen Pakets können keine weiteren Pakete mehr ausgewählt werden."
            dialog --backtitle "$MENU_TITLE" --defaultno --no-mouse --no-lines --no-shadow --colors --msgbox "$MENU_ERROR_TEXT" 8 50 3>&1 1>&2 2>&3
          fi
          dialog --clear
          clear
        fi
        # ----------------------------------------------------------------------
        # Eingabe eines Paket-Namens zur Deinstallation und Bereinigung
        # ----------------------------------------------------------------------
        if [ $MENU_AUSWAHL -eq 3 ];
        then
          setterm -cursor on 2>/dev/null
          NEW_REMOVE_PKG=$(dialog --backtitle "$MENU_TITLE" --no-mouse --no-lines --no-shadow --colors --inputbox "Name des zu löschenden Pakets:" 8 50 "$REMOVE_PKG_NAME" 3>&1 1>&2 2>&3)
          if [ $? -eq 0 ];
          then
            # Hinweis: In regulärem Ausdruck für sed die Leerzeichen NICHT ans Ende und
            # - (minus) IMMER ans Ende setzen, da sed diese sonst falsch interpretiert!
            REMOVE_PKG_NAME=$(echo "$NEW_REMOVE_PKG" | tr A-Z a-z | sed -E "s/[^a-z0-9 \.\_\-]//gi" | sed -E "s/ /\_/g" | xargs)
            if [ "$REMOVE_PKG_NAME" != "" ];
            then
              OPTION_FLAG[remove]=1
            else
              OPTION_FLAG[remove]=0
            fi
          fi
          setterm -cursor off 2>/dev/null
          dialog --clear
          clear
        fi
        # ----------------------------------------------------------------------
        # Optionen
        # ----------------------------------------------------------------------
        if [ $MENU_AUSWAHL -eq 2 ] ||
           [ $MENU_AUSWAHL -eq 4 ] ||
           [ $MENU_AUSWAHL -eq 5 ];
        then
          # --------------------------------------------------------------------
          # Liste der Optionen erzeugen und nach (Vor-)Einstellung aktivieren
          # --------------------------------------------------------------------
          ANZ_OPTIONS=0
          OPT_MENU_LIST=()
          for i in ${OPTION_LIST[@]};
          do
            if [ $MENU_AUSWAHL -eq ${OPTION_MENU[$i]} ];
            then
              THE_OPT_TEXT="${OPTION_TEXT[$i]}"
              OPT_MENU_LIST+=("$i" "$THE_OPT_TEXT")
              if [ ${OPTION_FLAG[$i]} -eq 1 ];
              then
                OPT_MENU_LIST+=("on")
              else
                OPT_MENU_LIST+=("off")
              fi
              OPT_MENU_LIST+=("Kommandozeilen-Parameter: $i $SUB_MENU_HELP")
              ((ANZ_OPTIONS+=1))
            fi
          done
          # -----------------------------------
          # Auswahlliste der Optionen anzeigen
          # -----------------------------------
          SELECT_MENU_TILE="${MENU_NAME[$MENU_AUSWAHL]}"
          SELECT_AUSWAHL=$(dialog --backtitle "$MENU_TITLE" --item-help --no-tags --no-cancel --no-mouse --no-lines --no-shadow --output-separator " " --colors --checklist "\Z4\Zb $SELECT_MENU_TILE\Zn" 0 0 ${ANZ_OPTIONS} "${OPT_MENU_LIST[@]}" 3>&1 1>&2 2>&3)
          # -----------------------------------------------
          # Alte Options-Auswahl löschen und neue einlesen
          # -----------------------------------------------
          if [ $? -eq 0 ];
          then
            reset_options_selection $MENU_AUSWAHL
            for thekey in ${SELECT_AUSWAHL[@]};
            do
              OPTION_FLAG[$thekey]=1
            done
          fi
          dialog --clear
          clear
        fi
        # ----------------------------------------------------------------------
        # Escape im Hauptmenü
        # ----------------------------------------------------------------------
        if [ $MENU_AUSWAHL -lt 0 ];
        then
          dialog --backtitle "$MENU_TITLE" --defaultno --no-mouse --no-lines --no-shadow --yesno "Programm beenden?" 0 0 3>&1 1>&2 2>&3
          if [ $? -eq 0 ];
          then
            exit_from_menu
            clean_on_exit
            exit 0
          fi
        fi
        # ----------------------------------------------------------------------
      done
      # ------------------------------------------------------------------------
      # Auswahl auf Konflikte prüfen
      # ------------------------------------------------------------------------
      check_options
      # ----------------
      # "nichts zu tun"
      # ----------------
      if ! ready_for_action;
      then
        MENU_ERROR_TEXT="\Z4\ZbNicht so schnell\Zn\nEs ist noch keine Aktion ausgewählt, die ich sinnvoll bearbeiten könnte ..."
      fi
      # ---------------------------------------------------
      # Wenn bei der Auswahl ein Konflikt aufgetreten ist,
      # Meldung dazu anzeigen ...
      # ---------------------------------------------------
      if [ "$MENU_ERROR_TEXT" != "" ];
      then
        dialog --backtitle "$MENU_TITLE" --defaultno --no-mouse --no-lines --no-shadow --colors --msgbox "$MENU_ERROR_TEXT" 8 50 3>&1 1>&2 2>&3
      else
        # ....................................................
        # ... sonst abschließende Sicherheitsabfrage anzeigen
        # ....................................................
        CONTINUE_QUESTION=""
        if [ "$MENU_INFO_TEXT" != "" ];
        then
          CONTINUE_QUESTION+="$MENU_INFO_TEXT\n"
          CONTINUE_TROTZDEM=" trotzdem"
        else
          CONTINUE_QUESTION+="Ich bin bereit. "
          CONTINUE_TROTZDEM=""
        fi
        CONTINUE_QUESTION+="Soll ich die Ausführung jetzt$CONTINUE_TROTZDEM mit den eingestellten Parametern starten?"
        dialog --backtitle "$MENU_TITLE" --no-mouse --no-lines --no-shadow --colors --yesno "$CONTINUE_QUESTION" 10 50 3>&1 1>&2 2>&3
        MENU_OK=$?
      fi
    done
    exit_from_menu
  fi
fi

if [ "$INST_ONLY_PKG" != "" ];
then
  reset_categories_selection
fi

# ==============================================================================
# Benutzerspezifische Konfiguration löschen
# (nach Auswahl des entsprechenden Punktes im Menü)
# ==============================================================================
if [ ${OPTION_FLAG[reset]} -eq 1 ];
then
  RESET_CONFIG=1
  reset_user_config
  reset_categories_selection
  reset_options_selection 0
fi

#===============================================================================
# Kommandozeilen-Aufruf erstellen
#===============================================================================
create_command_line

#===============================================================================
# Farb-Definitionen löschen, wenn keine Farben erwünscht
#===============================================================================
if [ ${OPTION_FLAG[nocolor]} -eq 1 ];
then
  COL_VAR_LIST=(black red green yellow blue magenta cyan white
                dark_gray light_red light_green light_yellow light_blue light_magenta light_cyan light_gray
                bold_black bold_red bold_green bold_yellow bold_blue bold_magenta bold_cyan bold_white
                uline_black uline_red uline_green uline_yellow uline_blue uline_magenta uline_cyan uline_white
                bg_black bg_red bg_green bg_yellow bg_blue bg_magenta bg_cyan bg_white
                colors_off colors_invers full_line_color half_line_color)
  for i in ${COL_VAR_LIST[@]};
  do
    declare $i="" # Besser als eval "${i}=''"
  done
fi

#===============================================================================
# Startzeit merken
#===============================================================================
SCRIPT_TIME_START=$(date +%s)

#===============================================================================
# Log-Datei eröffnen
#===============================================================================
if [ ${OPTION_FLAG[logfull]} -eq 1 ]; then OPTION_FLAG[log]=1; fi
if [ ${OPTION_FLAG[log]} -eq 1 ]; then echo -n "" > "$LOG_FILE"; fi
if [ ${OPTION_FLAG[log]} -eq 1 ];
then
  do_log "$FULL_LINE"
  do_log " $SCRIPT_NAME Log $(date +%d.%m.%Y) $(date +%H:%M:%S)"
  do_log "$FULL_LINE"
  PARAMETER="$@"
  PARAMETER=$(printf %b "${PARAMETER}" | tr A-Z a-z)
  do_log " Aufruf : ${PARAMETER[@]}"
  do_log " Auswahl: $COMMAND_LINE_STRING"
  do_log "$FULL_LINE"
fi

#===============================================================================
# Wenn das Menü angezeigt wurde, dann die Kopfzeile neu ausgeben
#===============================================================================
if [ $SHOW_HELP -eq 0 ] &&
   [ $NO_MENU -eq 0 ];
then
  show_headlines
else
  # -------------------------------------------------------------------
  # Wenn das Menü nicht angezeigt wurde, dann die angegebenen Optionen
  # auf Konflikte prüfen (erfolgt sonst auch im Menü)
  # -------------------------------------------------------------------
  check_options
  if [ "$MENU_ERROR_TEXT" != "" ];
  then
    ERROR_TEXT="$(echo -e -n ${MENU_ERROR_TEXT} | tr '\n' ' ')"
    ERROR_TEXT="$(echo -e -n ${ERROR_TEXT} | sed -E 's/\\Zb//g')"
    ERROR_TEXT="$(echo -e -n ${ERROR_TEXT} | sed -E 's/\\Zn/\\033[0m/g')"
    ERROR_TEXT="$(echo -e -n ${ERROR_TEXT} | sed -E 's/\\Z0/\\033[0m/g')"
    ERROR_TEXT="$(echo -e -n ${ERROR_TEXT} | sed -E 's/\\Z([1-9])/\\033[1;3\1m/g')"
    e_and_l " $ERROR_TEXT"
    e_and_l ""
    e_and_l -n " Drücke Taste ${bold_yellow}H${colors_off} für Hilfe oder andere Taste zum Beenden: "
    read -N 1 -r -s ANSWER
    e_and_l ""
    if [[ "$ANSWER" != "h" && "$ANSWER" != "H" ]]; then exit 0; fi
    e_and_l ""
  fi
fi
if [ ${OPTION_FLAG[infoonly]} -eq 0 ] &&
   [ "$MENU_INFO_TEXT" != "" ];
then
  INFO_TEXT="$(echo -e -n ${MENU_INFO_TEXT} | tr '\n' ' ')"
  INFO_TEXT="$(echo -e -n ${INFO_TEXT} | sed -E 's/\\Zb//g')"
  INFO_TEXT="$(echo -e -n ${INFO_TEXT} | sed -E 's/\\Zn/\\033[0m/g')"
  INFO_TEXT="$(echo -e -n ${INFO_TEXT} | sed -E 's/\\Z0/\\033[0m/g')"
  INFO_TEXT="$(echo -e -n ${INFO_TEXT} | sed -E 's/\\Z([1-9])/\\033[1;3\1m/g')"
  e_and_l " $INFO_TEXT"
  e_and_l ""
fi

#===============================================================================
# Wenn keine ausführbare Auswahl erfolgt ist (kein Paket und keine Option)
# oder die Hilfe explizit angefordert wurde, dann Programm-Syntax anzeigen
#===============================================================================
if ! ready_for_action ||
   [ "$MENU_ERROR_TEXT" != "" ] ||
   [ $SHOW_HELP -eq 1 ];
then
  e_and_l " Aufruf: $SCRIPT_NAME [Kategorien] [Optionen]"
  e_and_l ""
  e_and_l "$FULL_LINE"
  e_and_l ""
  e_and_l " Dieses Skript ermöglicht die automatisierte Installation von Programmpaketen"
  e_and_l " aus verschiedenen Quellen einschließlich der Konfiguration der Programme und"
  e_and_l " Erstellung von Startern (Programm-Symbolen / Icons) auf dem Desktop."
  e_and_l " Die zur Verfügung stehenden Programmpakete sind dazu in Kategorien geordnet,"
  e_and_l " welche individuell aus- oder abgewählt und beliebig angepasst werden können."
  e_and_l " Darüber hinaus stehen diverse Optionen zur Verfügung, mit denen sich Auswahl"
  e_and_l " von Programmpaketen und Ablauf des Skriptes individuell anpassen lassen."
  e_and_l " Optional können weitere System-Komponenten wie Treiber installiert werden,"
  e_and_l " sowie diverse Optimierungen und Reparaturen des Systems durchgeführt werden."
  e_and_l " $HALF_LINE"
  e_and_l "  ${bold_white}Kategorien${colors_off}"
  e_and_l " $HALF_LINE"
  e_and_l "  Auswahl durch vorangestelltes + (plus)"
  e_and_l "  Abwahl durch vorangestelltes - (minus)"
  e_and_l ""
  for k in ${KAT_KEY_LIST[@]};
  do
    e_and_l -n "     $k   "
    if [ ${#k} -lt 2 ]; then e_and_l -n " "; fi
    e_and_l "${KATEGORIE_TEXT[$k]}"
  done
  e_and_l ""
  e_and_l "    all   Auswahl aller vorstehenden Kategorien, jedoch ohne"
  e_and_l "          die Desktop-spezifischen Tool-Pakete"
  e_and_l ""
  e_and_l "  Hinweis: Die Zuordnung der Programmpakete und Kategorien entspricht"
  e_and_l "           nicht immer der Zuordnung im Hauptmenü der Betriebssysteme."
  e_and_l "           Eine Abwahl (-) überschreibt eine entsprechende Auswahl (+)"
  e_and_l ""
  e_and_l " $HALF_LINE"
  e_and_l "  ${bold_white}Optionen${colors_off}"
  e_and_l " $HALF_LINE"
  e_and_l ""
  # --- OPTIONS START ---
  e_and_l "   addflat  Erlaubt die Auswahl und Installation von Flatpak-Paketen."
  e_and_l ""
  e_and_l "   addsnap  Erlaubt die Auswahl und Installation von Snap-Paketen."
  e_and_l ""
  e_and_l "  addstart  Erstellt Starter (Programm-Symbole) für alle ausgewählten"
  e_and_l "            Pakete auf dem Schreibtisch (Desktop) des Benutzers."
  e_and_l ""
  e_and_l "  autoyorn  Alle Ja/Nein-Abfragen vor der Installation von Programmen"
  e_and_l "            und vor der Durchführung von Optionen werden automatisch"
  e_and_l "            so beantwortet, wie sie im vorherigen Programm-Durchlauf"
  e_and_l "            ausgewählt wurden."
  e_and_l "            Hinweis: Bei Verwendung dieser Option überlagern ggf. die"
  e_and_l "            Antworten zur Installation von Paketen die Option force."
  e_and_l "            Darüber hinaus Wird diese Option durch notoall überlagert."
  e_and_l ""
  e_and_l "  cleansys  Löscht veraltete und verwaiste Daten des Benutzers sowie"
  e_and_l "            ebensolche Dateien des Systems."
  e_and_l ""
  e_and_l "  cleantmp  Alle temporären Dateien von Lissy werden automatisch wieder"
  e_and_l "            gelöscht. Heruntergeladene Dateien wie Setups und Skripte"
  e_and_l "            sowie Listen bleiben hingegen zur Nachvollziehbarkeit auch"
  e_and_l "            nach Ende des Programms im Download-Ordner erhalten."
  e_and_l "            Bei Verwendung dieser Option werden auch diese Dateien"
  e_and_l "            alle vollständig aus dem Download-Ordner entfernt."
  e_and_l ""
  e_and_l "  csubdirs  Starter für Spiele mit Unterordnern weiter kategorisieren."
  e_and_l ""
  e_and_l "   desktop  Installiert eine grafische Benutzeroberfläche (Desktop)."
  e_and_l ""
  # e_and_l "     dload  Stellt gespeicherte Desktop- und Anwendungs-Einstellungen"
  # e_and_l "            aus einer Sicherung wieder her (dconf)."
  # e_and_l ""
  # e_and_l "     dsave  Erstellt eine Sicherung der Einstellungen des Benutzers"
  # e_and_l "            von Desktop und verschiedenen Anwendungen (dconf)."
  # e_and_l ""
  e_and_l "  esamesrc  Erweiterungen von Paketen werden nur aus der gleichen"
  e_and_l "            Quelle wie der des Basis-Paketes installiert, und wenn"
  e_and_l "            nicht aus gleicher Quelle verfügbar übersprungen."
  e_and_l ""
  e_and_l "   extends  Erweitert das Repository um Einträge von individuellen"
  e_and_l "            Anbietern sowie PPAs."
  e_and_l ""
  e_and_l "  external  Erweitert die Paketauswahl um Prgramme von Drittanbietern,"
  e_and_l "            welche aus externen Quellen heruntergeladen werden."
  e_and_l ""
  e_and_l "    extras  Ergänzt das System jeweils wahlweise um einige Extras:"
  e_and_l "            zusätzliche Treiber, fehlende Sprach-Unterstützung, ein"
  e_and_l "            großes Schriftarten-Paket, weitere Mauszeiger und mehr."
  e_and_l ""
  e_and_l "  exupdate  Aktualisiert bestimmte Programmpakete, sofern für diese"
  e_and_l "            eine neuere Version aus einer externen Quelle existiert,"
  e_and_l "            und diese nicht als Flatpak oder Snap installiert sind."
  e_and_l "            Aktiviert automatisch die Option external."
  e_and_l ""
  e_and_l "  exupdall  Sucht in Verbindung mit der Option exupdate trotzdem auch"
  e_and_l "            nach Aktualisierungen für bestimmte Programmpakete, wenn"
  e_and_l "            diese zuvor aus einer anderen Quelle, bspw. als Flatpak"
  e_and_l "            oder als Snap installiert worden sind."
  e_and_l ""
  e_and_l "     force  Überspringt die Ja/Nein-Abfrage vor der Installation jedes"
  e_and_l "            einzelnen Programmpakets, sofern diese nicht in Konflikt"
  e_and_l "            mit einem bereits installierten Paket steht, oder bei der"
  e_and_l "            zusätzlichen Verwendung der Option autoyorn deren eventuell"
  e_and_l "            gespeicherte Antwort zur Paket-Installation anders lautet."
  e_and_l "            Darüber hinaus wird diese Option durch notoall überlagert."
  # e_and_l "            (Diese Option ist nicht identisch mit apt-get --force)"
  e_and_l ""
  e_and_l "   foreign  Erlaubt auch die Installation von Programmpaketen für"
  e_and_l "            sekundäre (Fremd-)Software-Architekturen."
  e_and_l ""
  e_and_l "      help  Zeigt diese Hilfe-Seite an."
  e_and_l ""
  e_and_l "  infoonly  Zeigt nur die Liste der Systeminformationen an und führt"
  e_and_l "            keine weiteren Aktionen durch."
  e_and_l ""
  e_and_l "  instlist  Installiert alle Pakete, die zeilenweise in der direkt"
  e_and_l "            danach angegebenen Datei aufgelistet sind. Diese Pakete"
  e_and_l "            werden ggf. zusätzlich zur Kategorie-Auswahl installiert."
  e_and_l ""
  e_and_l "  instonly  Installiert oder listet nur das direkt danach angegebene"
  e_and_l "            Programmpaket. Diese Option setzt die Kategorie-Auswahl"
  e_and_l "            sowie die individuelle Paketliste (instlist) außer Kraft."
  e_and_l ""
  e_and_l "   kuplock  Blockiert alle Aktualisierungen des Linux-Kernels bis"
  e_and_l "            die Sperre durch kunlock wieder aufgehoben wird. Alle"
  e_and_l "            anderen Programmpakete werden weiterhin aktualisiert."
  e_and_l ""
  e_and_l "   kunlock  Hebt die Sperre der Kernel-Aktualisierungen wieder auf."
  e_and_l ""
  e_and_l "  listonly  Zeigt alle in den ausgewählten Kategorien enthaltenen"
  e_and_l "            Programmpakete unabhängig von deren Status an, ohne"
  e_and_l "            Programmpakete zu installieren oder zu konfigurieren."
  e_and_l ""
  e_and_l "       log  Protokolliert alle Aktionen und deren Ergebnisse ohne"
  e_and_l "            weitere detaillierte Ausgaben in einer Log-Datei."
  e_and_l ""
  e_and_l "   logfull  Protokolliert alle Aktionen sowie detailliert sämtliche"
  e_and_l "            Ausgaben der Installationsroutinen in einer Log-Datei."
  e_and_l ""
  e_and_l "   nocolor  Die Ausgabe erfolgt nur in Systemschrift ohne Farben."
  e_and_l ""
  e_and_l "    noinfo  Die Systeminformationen zu Anfang werden nicht angezeigt."
  e_and_l ""
  e_and_l "  noconfig  Überspringt das Laden der benutzerspezifisch gepeicherten"
  e_and_l "            Konfiguration (Einstellungen, Optionen und Paket-Listen)."
  e_and_l ""
  e_and_l "    nomenu  Überspringt das Menü zur Kategorie- und Options-Auswahl"
  e_and_l "            und berücksichtigt so nur die Kommandozeilen-Parameter."
  e_and_l ""
  e_and_l "    norepo  Überspringt die Aktualisierung des Repository beim Start"
  e_and_l "            dieses Skriptes."
  e_and_l ""
  e_and_l "   notoall  Alle Abfragen werden automatisch mit Nein beantwortet."
  e_and_l "            Diese Option überlagert die Optionen autoyorn und force."
  e_and_l ""
  e_and_l "  noupdate  Prüft nicht auf eine neuere Version dieses Skripts."
  e_and_l ""
  e_and_l "  optimize  Aktiviert und optimiert einige System-Einstellungen für"
  e_and_l "            Firewall, Swapping, Festplattenzugriffe und vieles mehr."
  e_and_l ""
  e_and_l "  personal  Führt individuelle persönliche Einstellungen durch, welche"
  e_and_l "            dazu vom Server geladen werden. Zur Nutzung dieser Option"
  e_and_l "            ist ein geschütztes Verzeichnis bei migano.de erforderlich."
  e_and_l ""
#   e_and_l "     quiet  Unterdrückt alle Ausgaben der Installationsroutinen und"
#   e_and_l "            bestätigt ggf. soweit dies möglich ist auch automatisch"
#   e_and_l "            deren Abfragen mit den jeweiligen Standard-Einstellungen."
#   e_and_l "            Diese Option sollte daher nur verwendet werden, wenn man"
#   e_and_l "            genau weiß, dass die ausgewählten Programmpakete auch so"
#   e_and_l "            installiert werden sollen! Bei auftretenden Sicherheits-"
#   e_and_l "            Problemen wie bspw. falschen Prüfsummen erfolgt trotzdem"
#   e_and_l "            ein entsprechender Hinweis mit Abfrage zur Fortführung."
#   e_and_l "            Individuelle Konfigurationen vor oder nach Installation"
#   e_and_l "            von Paketen werden natürlich aufgrund der erforderlichen"
#   e_and_l "            Eingaben auch immer vollständig sichtbar durchgeführt."
#   e_and_l "            Hinweis: Diese Option ist nicht identisch mit der von"
#   e_and_l "            apt-get --quiet (siehe dazu auch Option \"force\")!"
#   e_and_l ""
  e_and_l "  prioflat  Wenn ein Programmpaket aus mehreren Quellen einschließlich"
  e_and_l "            Flatpak verfügbar ist, automatisch das Flatpak auswählen"
  e_and_l "            (nur in Verbindung mit der Option addflat). Diese Option"
  e_and_l "            hat Vorrang vor der Option priosnap."
  e_and_l ""
  e_and_l "  priosnap  Wenn ein Programmpaket aus mehreren Quellen einschließlich"
  e_and_l "            als SNAP verfügbar ist, automatisch SNAP-Paket auswählen"
  e_and_l "            (nur in Verbindung mit der Option addsnap). Diese Option"
  e_and_l "            ist nachrangig zu der Option prioflat."
  e_and_l ""
  e_and_l "    remove  Entfernt ein Programmpaket und löscht optional all dessen"
  e_and_l "            hinterbliebene Daten wie Konfiguration, Starteinträge etc."
  e_and_l ""
  e_and_l "    repair  Repariert einfache Fehler im Dateisystem und Bootloader."
  e_and_l "            Überprüft, bereinigt und erneuert Paketquellen."
  e_and_l ""
  e_and_l "     reset  Löscht alle benutzerspezifischen Einstellungen."
  e_and_l ""
  e_and_l "    revive  Reaktiviert vormals deaktivierte Komponenten."
  e_and_l ""
  e_and_l "  saveconf  Speichert alle per Kommandozeile oder im Menü ausgewählten"
  e_and_l "            Kategorien und Optionen und stellt diese beim nächsten"
  e_and_l "            Aufruf des Programms wieder als Vorauswahl ein."
  e_and_l ""
  e_and_l "    setutc  Stellt die Systemzeit auf Universal Time Coordinated (UTC)."
  e_and_l ""
  e_and_l "  skipmesg  Wartet bei wichtigen Hinweisen vor dem Weitermachen nicht"
  e_and_l "            auf eine Bestätigung durch Drücken der Enter-Taste."
  e_and_l ""
  e_and_l "  skippkgs  Überspringt die Installation bestimmter Programmpakete,"
  e_and_l "            mehrere Paketnamen sind durch Leerzeichen zu trennen"
  e_and_l "            (Paketnamen kann man mit der Option listonly ermitteln)."
  e_and_l ""
  e_and_l "  skipsims  Unterdrückt die Anzeige und Installation vordefinierter"
  e_and_l "            alternativer (ähnlicher) Programme."
  e_and_l ""
  e_and_l "  snapcont  Reaktiviert eine deaktivierte Snap-Paketverwaltung."
  e_and_l ""
  e_and_l "  snapkill  Entfernt die Snap-Paketverwaltung und alle als Snap"
  e_and_l "            installierten Programme vollständig von diesem System."
  e_and_l ""
  e_and_l "  snapstop  Deaktiviert die Snap-Paketverwaltung wahlweise mit"
  e_and_l "            Beibehaltung der als Snap installierten Programme."
  e_and_l ""
  e_and_l "    status  Zeigt den Status der ausgewählten Programmpakete an."
  e_and_l "            Sofern die Option extends angegeben ist, werden dabei ggf."
  e_and_l "            auch Paketquellen für individuelle Programmpakete ergänzt,"
  e_and_l "            jedoch ohne irgendwelche Programmpakete zu installieren."
  e_and_l ""
  e_and_l "  sysbench  Erstellt Referenzwerte für die Performance dieses Systems,"
  e_and_l "            die zum Benchmarking / Vergleich verwendet werden können."
  e_and_l ""
  # --- OPTIONS END ---
  e_and_l ""
  e_and_l " $HALF_LINE"
  e_and_l "  ${bold_white}Beispiele${colors_off}"
  e_and_l " $HALF_LINE"
  e_and_l "  Beispiele für die Verwendung finden sich unter:"
  e_and_l "  https://migano.de/lissy"
  e_and_l ""
  exit 1;
fi

#===============================================================================
# Dateien zur Speicherung von dconf-Daten
#===============================================================================
DCONF_BASE_NAME="dconf_$(hostname)_${OS_V_CODENAME}"

# Sicherungsdatei zum Speichern UND Laden von benutzerdefinierten Einstellungen
DCONF_USER_FILE="$DOWNLOAD_DIR/$DCONF_BASE_NAME.conf"
# Zusätzliches Backup der aktuellen dconf-Einstellungen
DCONF_USER_BACKUP="$DOWNLOAD_DIR/$DCONF_BASE_NAME.save"
# Wenn dconf-Daten geändert werden können und noch kein Backup der gesamten
# dconf-Datenbank existiert, davon auch noch ein separates Backup erstellen
DCONF_NEEDED=0
if [ ${OPTION_FLAG[dload]} -eq 1 ] ||
   [ ${OPTION_FLAG[dsave]} -eq 1 ];
   # || [ ${OPTION_FLAG[personal]} -eq 1 ];
then
  DCONF_NEEDED=1
  create_backup_file "$USER_CONFIG_DIR/dconf/user"
fi

#===============================================================================
# Systeminformationen ermitteln und anzeigen
#===============================================================================
if [ ${OPTION_FLAG[noinfo]} -eq 0 ];
then
  do_log "$FULL_LINE"
  e_and_l "$(system_info_summary)"
fi

if [ ${OPTION_FLAG[infoonly]} -eq 1 ];
then
  show_full_bg_line
  exit 0
fi

#===============================================================================
# Überprüfung auf passendes Betriebssystem
#===============================================================================
if [ $NO_MENU -eq 1 ] &&
   [ $IS_DEBIAN -eq 0 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " $ACHTUNG_TAG: Dieses Tool ist nicht für dieses Betriebssystem entwickelt worden!"
  e_and_l " Auf Debian-basierten Systemen werden die meisten Punkte zwar funktionieren,"
  e_and_l " auf anderen Systemen werden die Funktionen jedoch eher eingeschränkt sein!"
  ask_yes_or_no_plus "other_os" " Trotzdem weitermachen" "" "n"
  if [ $? -ne 1 ];
  then
    exit 0
  fi
fi

#===============================================================================
# Wenn der Aufruf als root erfolgt ist, Warnhinweis dazu ausgeben
# und sofern vorhanden andere Benutzer optional zum Sudoer machen
#===============================================================================
if [ $USER_USERNAME = "root" ];
then
  e_and_l "$FULL_LINE"
  e_and_l " $ACHTUNG_TAG: Du bist als ${bold_yellow}root${colors_off} angemeldet. Einige zu installierende Komponenten"
  e_and_l " und automatisch durchgeführte Einstellungen sind jedoch benutzerspezifisch,"
  e_and_l " so dass diese für andere Benutzer nicht verfügbar wären bzw. von diesen bei"
  e_and_l " Bedarf erst noch selbst installiert und manuell konfiguriert werden müssten."
  # -------------------------------------------------------------------------
  # Wenn es noch andere Benutzer gibt, darunter aber noch keine Sudoer sind,
  # anbieten Benutzer zum Sudoer zu machen
  # -------------------------------------------------------------------------
  get_user_list
  if [ $ANZAHL_USER -gt 0 ] &&
     [ $SUDOER_EXIST -eq 0 ];
  then
    e_and_l " Es sind allerdings noch keine Benutzer als ${light_cyan}Superuser${colors_off} (Sudoer) eingerichtet."
    ask_yes_or_no_plus "" " Willst Du andere Benutzer als Sudoer einrichten" "" "j"
    if [ $? -eq 1 ];
    then
      NEW_SUDOER=0
      for userdir in ${HOME_DIR_LIST[@]};
      do
        TEST_USER_NAME=${userdir/\/home\//}
        id "$TEST_USER_NAME" &>/dev/null
        if [ $? -eq 0 ];
        then
          if [ $(id $TEST_USER_NAME 2>/dev/null | grep -i -c -E "\(sudo\)") -eq 0 ];
          then
            ask_yes_or_no_plus "" " Benutzer ${bold_yellow}$TEST_USER_NAME${colors_off} zum Superuser machen?" "" "j"
            if [ $? -eq 1 ];
            then
              e_and_l -n " Erhebe Benutzer ${bold_white}$TEST_USER_NAME${colors_off} zum Superuser ... "
              usermod -a -G sudo "$TEST_USER_NAME" &>/dev/null
              if [ $? -eq 0 ];
              then
                ((NEW_SUDOER+=1))
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
          fi
        fi
      done
      if [ $NEW_SUDOER -gt 0 ];
      then
        e_and_l " Das Skript wird jetzt beendet, so dass Du es mit einem Superuser in"
        e_and_l " dessen Namen und Arbeitsumgebung neu ausführen kannst. Viel Erfolg!"
        e_and_l " $HINWEIS_TAG: Der Superuser-Status wird erst nach einem Neustart wirksam."
      else
        e_and_l " Es wurde ${bold_red}kein${colors_off} Benutzer zum Superuser erhoben. Das Skript wird daher"
        e_and_l " jetzt aus Sicherheitsgründen beendet."
      fi
      exit 0
    fi
  fi
  e_and_l ""
fi # Ende username root

#===============================================================================
# Wenn der Aufruf als alter Standard-Benutzer pi auf Pi OS erfolgt ist,
# Abfrage ob weiterer Superuser angelegt werden soll
#===============================================================================
if [ $IS_PIOS -gt 0 ] &&
   [ $USER_USERNAME = "pi" ];
then
  e_and_l "$FULL_LINE"
  e_and_l " $ACHTUNG_TAG: Du bist als Raspberry Pi OS Standardbenutzer ${bold_yellow}pi${colors_off} angemeldet."
  e_and_l " Aus Sicherheitsgründen sollte man als ein anderer Benutzer arbeiten!"
  get_user_list
  if [ $SUDOER_EXIST -eq 0 ];
  then
    ask_yes_or_no_plus "" " Soll ein neuer Benutzer/Superuser angelegt werden" "" "j"
    if [ $? -eq 1 ];
    then
      NEW_USERNAME=""
      while [ "$NEW_USERNAME" == "" ];
      do
        e_and_l -n " Bitte neuen Benutzernamen eingeben: "
        read -r NEW_USERNAME
        if [ "$NEW_USERNAME" != "" ];
        then
          NEW_USERNAME=$(echo $NEW_USERNAME | tr -d -c '[:alnum:]_' | tr '[:upper:]' '[:lower:]')
          id "$NEW_USERNAME" &>/dev/null
          if [ $? -ne 0 ];
          then
            ask_yes_or_no_pure " Neuer Benutzername: ${bold_yellow}$NEW_USERNAME${colors_off} - OK"
            if [ $? -eq 1 ];
            then
              e_and_l " Erstelle Superuser $NEW_USERNAME ... "
              adduser "$NEW_USERNAME"
              if [ $? -eq 0 ];
              then
                PI_SUDOER_FILE="/etc/sudoers.d/010_$NEW_USERNAME-nopasswd"
                echo "$NEW_USERNAME ALL=(ALL) PASSWD: ALL" >  "$PI_SUDOER_FILE"
                if [ $? -eq 0 ];
                then
                  chown root:root "$PI_SUDOER_FILE" &>/dev/null
                  chmod -R 0440 "$PI_SUDOER_FILE" &>/dev/null
                  usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi,pi,lpadmin "$NEW_USERNAME"
                  if [ $? -eq 0 ];
                  then
                    e_and_l -n " Fertig. Superuser ${bold_green}$NEW_USERNAME${colors_off} wurde mit ID "
                    e_and_l -n $(id -u ${NEW_USERNAME})
                    e_and_l " angelegt."
                    # Für den Benutzer pi die Passwort-Eingabe für sudo-Aktivitäten reaktivieren
                    e_and_l -n " Reaktiviere jetzt das Passwort für sudo des Benutzers pi ... "
                    create_backup_file "$PI_NOPASS_FILE"
                    echo -e "pi ALL=(ALL) PASSWD: ALL" > "$PI_NOPASS_FILE" 2>"$LOG_TEMP"
                    if [ $? -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      restore_backup_file "$PI_NOPASS_FILE"
                      e_and_l "$ERROR_TAG"
                      add_full_log
                    fi
                    e_and_l " Bitte als neuer Benutzer anmelden und $SCRIPT_NAME erneut aufrufen."
                    e_and_l " $HINWEIS_TAG: Der Superuser-Status wird erst nach einem Neustart wirksam."
                    ask_yes_or_no_pure " System neu starten [${bold_yellow}J${colors_off}] oder Skript beenden [${bold_yellow}N${colors_off}]"
                    if [ $? -eq 1 ];
                    then
                      reboot
                    else
                      e_and_l " Das Skript wird nun beendet."
                      exit 0
                    fi
                  fi
                fi
              fi
              e_and_l " $ERROR_TAG: Der neue Benutzer konnte nicht angelegt werden!"
              exit 1
            else
              NEW_USERNAME=""
            fi
          else
            e_and_l " $ERROR_TAG: Diesen Benutzernamen gibt es leider schon!"
            NEW_USERNAME=""
          fi
        fi
      done
    fi
  fi
fi # Ende username pi

#===============================================================================
# Hinweis auf mehrere Software-Architekturen
#===============================================================================
if [ $TOTAL_PACKS -gt 0 ] &&
   [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[foreign]} -eq 0 ] &&
   [ "$ARCHITECTURE_OTHER" != "" ];
then
  e_and_l "$FULL_LINE"
  e_and_l " $HINWEIS_TAG: Auf diesem System sind mehrere Software-Architekturen eingerichtet."
  e_and_l " Um die Stabilität des Systems nicht zu gefährden, werden alle Programmpakete"
  e_and_l " nur für die Haupt-Architektur ${bold_yellow}$ARCHITECTURE_MAIN${colors_off} installiert, sofern mit Angabe der Option"
  e_and_l " \"foreign\" nicht auch Pakete für die Sekundär-Architekturen erlaubt werden."
fi

#===============================================================================
# Hinweis auf die Verwendung gespeicherter Einstellungen
#===============================================================================
if [ $NO_CONFIG -eq 0 ] &&
   [ $RESET_CONFIG -eq 0 ];
then
  if [ -s "$USER_SCRIPT_CONFIG" ] ||
     [ -s "$USER_PAKET_LIST" ];
  then
    e_and_l "$FULL_LINE"
    if [ -s "$USER_PAKET_LIST" ];
    then
      e_and_l -n " $ACHTUNG_TAG:"
    else
      e_and_l -n " $HINWEIS_TAG:"
    fi
    e_and_l " Es werden zuvor gespeicherte individuelle Einstellungen verwendet."
    # e_and_l -n " Diese können sich auf die bei Aufruf angegebenen Optionen auswirken"
    e_and_l -n " Diese können sich auf die per Kommandozeile angegebenen Optionen auswirken"
    if [ -s "$USER_PAKET_LIST" ];
    then
      e_and_l ","
      e_and_l -n " und beinhalten zudem auch individuelle benutzerspezifische Paket-Listen"
    fi
    e_and_l "."
    e_and_l " ${light_cyan}Tipp${colors_off}: Mit Option ${light_cyan}noconfig${colors_off} werden keine individuellen Einstellungen geladen."
  fi
fi

#===============================================================================
# Sicherheitssabfrage für quiet, sofern relevante Aktionen durchgeführt werden
# Derzeit nicht verwendet
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[quiet]} -eq 1 ] &&
   [ ${OPTION_FLAG[status]} -eq 0 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " $ACHTUNG_TAG: Die Option ${bold_yellow}quiet${colors_off} ist aktiviert!"
  e_and_l " Dadurch werden alle Ausgaben der Installationsroutinen unterdrückt und"
  e_and_l " Programmpakete OHNE Rückfrage nach deren Standard-Vorgabe installiert!"
  e_and_l " Wenn das gewünscht ist, die folgende Frage mit [${bold_yellow}J${colors_off}]a beantworten, sonst"
  e_and_l " wird bei Eingabe von [${bold_yellow}N${colors_off}]ein ohne Quiet-Modus weitergemacht (empfohlen)."
  ask_yes_or_no_plus "use_quiet" " Wirklich im Quiet-Modus weitermachen" "" "n"
  if [ $? -eq 0 ]; then OPTION_FLAG[quiet]=0; fi
fi

#===============================================================================
# Alte gespeicherte Einstellungen löschen
#===============================================================================
remove_file "$USER_SCRIPT_CONFIG"
remove_file "$USER_PAKET_LIST"

#===============================================================================
# Neue Einstellungen speichern
#===============================================================================
if [ ${OPTION_FLAG[saveconf]} -eq 1 ] &&
   [ $RESET_CONFIG -eq 0 ];
then
  SCRIPT_CONFIG_HEADLINE="Konfigurations-Datei für $SCRIPT_NAME"'\n'
  # ----------------------------------------------------
  # Konfiguration (Ausgewählte Kategorien und Optionen)
  # ----------------------------------------------------
  echo -e "# $SCRIPT_CONFIG_HEADLINE" > "$USER_SCRIPT_CONFIG" 2>/dev/null
  echo -e "# Kategorien" >> "$USER_SCRIPT_CONFIG" 2>/dev/null
  for k in ${KAT_KEY_LIST[@]};
  do
    echo -e "KATEGORIE_FLAG[$k]=${KATEGORIE_FLAG[$k]}" >> "$USER_SCRIPT_CONFIG" 2>/dev/null
  done
  echo -e "" >> "$USER_SCRIPT_CONFIG" 2>/dev/null
  echo -e "# Optionen" >> "$USER_SCRIPT_CONFIG" 2>/dev/null
  for o in ${OPTION_LIST[@]};
  do
    echo -e "OPTION_FLAG[$o]=${OPTION_FLAG[$o]}" >> "$USER_SCRIPT_CONFIG" 2>/dev/null
  done
  chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_SCRIPT_CONFIG" &>/dev/null
  # ----------------------------
  # Paket-Listen und Skip-Liste
  # ----------------------------
  echo -e "# $SCRIPT_CONFIG_HEADLINE" > "$USER_PAKET_LIST" 2>/dev/null
  echo -e "# Paket-Listen" >> "$USER_PAKET_LIST" 2>/dev/null
  for k in ${KAT_KEY_LIST[@]};
  do
    echo -e "KATEGORIE_PKGS[$k]=\"${KATEGORIE_PKGS[$k]}\"" >> "$USER_PAKET_LIST" 2>/dev/null
  done
  echo -e "" >> "$USER_PAKET_LIST" 2>/dev/null
  echo -e "# Skip-Liste" >> "$USER_PAKET_LIST" 2>/dev/null
  echo -e "SKIP_LIST=\"${SKIP_LIST[@]}\"" >> "$USER_PAKET_LIST" 2>/dev/null
  chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_PAKET_LIST" &>/dev/null
fi # Ende Neue Einstellungen speichern

#===============================================================================
# Prüfen ob die Paketverwaltung zur Verwendung frei ist
#===============================================================================
if [ $TOTAL_PACKS -gt 0 ] ||
   [ $USE_ILIST_FILE -eq 1 ] ||
   [ ${OPTION_FLAG[desktop]} -eq 1 ] ||
   [ ${OPTION_FLAG[extends]} -eq 1 ] ||
   [ ${OPTION_FLAG[external]} -eq 1 ] ||
   [ ${OPTION_FLAG[extras]} -eq 1 ] ||
   [ ${OPTION_FLAG[exupdate]} -eq 1 ] ||
   [ ${OPTION_FLAG[instlist]} -eq 1 ] ||
   [ ${OPTION_FLAG[instonly]} -eq 1 ] ||
   [ ${OPTION_FLAG[kuplock]} -eq 1 ] ||
   [ ${OPTION_FLAG[kunlock]} -eq 1 ] ||
   [ ${OPTION_FLAG[optimize]} -eq 1 ] ||
   [ ${OPTION_FLAG[remove]} -eq 1 ] ||
   [ ${OPTION_FLAG[repair]} -eq 1 ] ||
   [ ${OPTION_FLAG[snapcont]} -eq 1 ] ||
   [ ${OPTION_FLAG[snapkill]} -eq 1 ] ||
   [ ${OPTION_FLAG[snapstop]} -eq 1 ] ||
   [ ${OPTION_FLAG[status]} -eq 1 ];
then
  # ----------------------------------------------------------------------------
  # apt-Sperre prüfen
  # ----------------------------------------------------------------------------
  APT_IS_BLOCKED=0
  if [ -s "/var/lib/apt/lists/lock" ] ||
     [ -s "/var/lib/dpkg/lock" ] ||
     [ -s "/var/lib/dpkg/lock-frontend" ];
  then
    APT_IS_BLOCKED=1
    e_and_l "$FULL_LINE"
    e_and_l " $ACHTUNG_TAG: ${bold_white}apt${colors_off} ist gerade durch einen anderen Prozess geblockt (Updates?)."
    e_and_l " Die Sperre kann eventuell aufgehoben werden, dies wird jedoch ${bold_yellow}nicht empfohlen${colors_off}!"
    ask_yes_or_no_plus "" " Soll ich trotzdem versuchen die Sperre aufzuheben" "" "n"
    if [ $? -eq 1 ];
    then
      e_and_l -n " Versuche ${bold_yellow}apt${colors_off} zu entsperren ... "
      if [ -f "/var/lib/apt/lists/lock" ]; then echo -n "" > "/var/lib/apt/lists/lock" &>/dev/null; fi
      if [ -f "/var/lib/dpkg/lock" ]; then echo -n "" > "/var/lib/dpkg/lock" &>/dev/null; fi
      if [ -f "/var/lib/dpkg/lock-frontend" ]; then echo -n "" > "/var/lib/dpkg/lock-frontend" &>/dev/null; fi
      if [ ! -s "/var/lib/apt/lists/lock" ] &&
         [ ! -s "/var/lib/dpkg/lock" ] &&
         [ ! -s "/var/lib/dpkg/lock-frontend" ];
      then
        e_and_l "$OK_TAG"
        APT_IS_BLOCKED=0
      else
        e_and_l "$ERROR_TAG, Sperre konnte ${bold_white}nicht${colors_off} aufgehoben werden."
      fi
    else
      e_and_l -n " OK."
    fi
  fi
  # ----------------------------------------------------------------------------
  # Wenn apt gesperrt ist Skript beenden
  # ----------------------------------------------------------------------------
  if [ $APT_IS_BLOCKED -ne 0 ];
  then
    e_and_l " Das Skript wird jetzt beendet - bitte später nochmals versuchen."
    exit 1
  fi
fi # Ende Prüfen der Paketverwaltung

#===============================================================================
# Hinweis bei Auswahl konkurrierender Optionen zu Sicherheits-Abfragen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  AUTO_ANSWER_FLAGS=0
  if [ ${OPTION_FLAG[autoyorn]} -gt 0 ];
  then
    ((AUTO_ANSWER_FLAGS+=1))
  fi
  if [ ${OPTION_FLAG[force]} -gt 0 ] &&
     [ ${OPTION_FLAG[status]} -eq 0 ] &&
     [[ $TOTAL_PACKS -gt 0 || $USE_ILIST_FILE -ne 0 ]];
  then
    ((AUTO_ANSWER_FLAGS+=1))
  fi
  if [ ${OPTION_FLAG[notoall]} -gt 0 ];
  then
    ((AUTO_ANSWER_FLAGS+=1))
  fi
  if [ $AUTO_ANSWER_FLAGS -gt 1 ];
  then
    i=1
    e_and_l "$FULL_LINE"
    e_and_l " $HINWEIS_TAG: Es sind mehrere Optionen zur Behandlung von Abfragen ausgewählt,"
    e_and_l " welche situativ miteinander konkurrieren können. Die Priorisierung ist:"
    if [ ${OPTION_FLAG[notoall]} -gt 0 ];
    then
      e_and_l " $i. notoall  - Alle Abfragen immer mit Nein beantworten"
      ((i+=1))
    fi
    if [ ${OPTION_FLAG[autoyorn]} -gt 0 ];
    then
      e_and_l " $i. autoyorn - Abfragen wie im Lauf zuvor beantworten (falls gespeichert)"
      ((i+=1))
    fi
    if [ ${OPTION_FLAG[force]} -gt 0 ];
    then
      e_and_l " $i. force    - Vor der Installation von Paketen nicht nachfragen"
      e_and_l "               (sofern keine Mehrfachauswahl oder ein Konflikt besteht)"
    fi
  fi
fi
# ---------------------------------------------------------------------

#===============================================================================
# Überprüfung und Installation von zur korrekten Ausführung
# dieses Skriptes zwingend benötigten System-Komponenten
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Überprüfung benötigter Systemkomponenten${colors_off}"
  e_and_l "$FULL_LINE"
  # ----------------------------------------------------------------------------
  # Zum Downloaden und Entpacken von Dateien benötigte Komponenten
  # ----------------------------------------------------------------------------
  ALL_COMPONENTS_AVAIL=1
  COMPONENTS_REQUIRED=(coreutils diffutils lshw p7zip-full sed tar util-linux wget)
  if [ $DCONF_NEEDED -eq 1 ];
  then
    COMPONENTS_REQUIRED+=('dconf-cli')
  fi
  # ----------------------------------------------------------------------------
  # Schnell-Test
  # ----------------------------------------------------------------------------
  ALL_COMPONENTS_INSTALLED=1
  for required_pkg in ${COMPONENTS_REQUIRED[@]};
  do
    ((ANZ_SPACES=12-${#required_pkg}))
    if [ $(LANG=C dpkg-query -W -f='${Status}' "$required_pkg" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
    then
      ALL_COMPONENTS_INSTALLED=0
      break
    fi
  done
  # ----------------------------------------------------------------------------
  # Wenn alle benötigten Komponenten (sowie Flatpak und Snap - falls diese
  # verwendet werden sollen) installiert sind, nur eine kurze Meldung anzeigen
  # ----------------------------------------------------------------------------
  if [ $ALL_COMPONENTS_INSTALLED -eq 1 ];
  then
    if [[ ${OPTION_FLAG[addflat]} -eq 0 || $FLATPAK_ACTIVE -eq 1 ]] &&
       [[ ${OPTION_FLAG[addsnap]} -eq 0 || $SNAP_ACTIVE -gt 0 ]];
    then
      e_and_l " Alle benötigten Komponenten sind installiert ... $OK_TAG"
    fi
  # ----------------------------------------------------------------------------
  # ... sonst alle Komponenten anzeigen und fehlende installieren ...
  # ----------------------------------------------------------------------------
  else
    for required_pkg in ${COMPONENTS_REQUIRED[@]};
    do
      ((ANZ_SPACES=11-${#required_pkg}))
      if [ $(LANG=C dpkg-query -W -f='${Status}' "$required_pkg" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
      then
        e_and_l -n " Modul ${bold_yellow}$required_pkg${colors_off}"
        insert_spaces $ANZ_SPACES
        e_and_l -n " wird installiert  ... "
        apt install "$required_pkg" -y &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
          ALL_COMPONENTS_AVAIL=0
        fi
        add_full_log
      else
        e_and_l -n " Modul ${light_cyan}$required_pkg${colors_off}"
        insert_spaces $ANZ_SPACES
        e_and_l -n " ... "
        e_and_l "$OK_TAG"
      fi
    done
  fi
  # ----------------------------------------------------------------------------
  # Cross-Build Pakete zur Ausführung von armhf-Programmen auf arm64
  # ----------------------------------------------------------------------------
  if [ $(echo "$ARCHITECTURE_MAIN" | grep -i -c -E "arm64") -gt 0 ] &&
     [ $(echo "$ARCHITECTURE_OTHER" | grep -i -c -E "armhf") -gt 0 ];
  then
    ACTION_MESSAGE=" ${light_cyan}Cross-Build-Pakete${colors_off}"
    e_and_l "$HALF_LINE"
    e_and_l " ${bold_blue}Erweiterungen für die Architektur armhf auf arm64${colors_off}"
    e_and_l "$HALF_LINE"
    if [ $(LANG=C dpkg-query -W -f='${Status}' "crossbuild-essential-armhf" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
    then
      if [ $(apt list "crossbuild-essential-armhf" 2>/dev/null | grep -i -c -E "crossbuild-essential-armhf") -gt 0 ];
      then
        ask_yes_or_no_plus "crossbuild" "$ACTION_MESSAGE für armhf auf arm64 installieren" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m} werden installiert, bitte warten ... "
          apt install "crossbuild-essential-armhf" -y &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
          add_full_log
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE " "$NV_TXT")"
      fi
    else
      e_and_l "$ACTION_MESSAGE ... $OK_TAG"
    fi
  fi
  # ----------------------------------------------------------------------------
  # Wenn eine benötigte Komponente fehlt, Programm beenden
  # ----------------------------------------------------------------------------
  if [ $ALL_COMPONENTS_AVAIL -eq 0 ];
  then
    e_and_l " $ERROR_TAG: Leider sind benötigte Systemkomponenten ${bold_red}nicht${colors_off} verfügbar :("
    e_and_l " Das Skript wird daher jetzt beendet!"
    exit 1
  fi
fi

#===============================================================================
# Die Flatpak- und Snap-Verwaltung installieren, wenn noch nicht installiert
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  if [ $TOTAL_PACKS -gt 0 ] ||
     [ $USE_ILIST_FILE -eq 1 ];
  then
    # --------------------------------------------------------------------------
    # FLATPAK
    # --------------------------------------------------------------------------
    if [ ${OPTION_FLAG[addflat]} -eq 1 ] &&
       [ $FLATPAK_INSTALLED -eq 0 ] &&
       [ $(apt list "flatpak" 2>/dev/null | grep -i -c "flatpak") -gt 0 ];
    then
      e_and_l " $ACHTUNG_TAG: Die Flatpak-Paketverwaltung ist nicht installiert."
      ask_yes_or_no_plus "install_flatpak" " Die ${light_cyan}Flatpak-Paketverwaltung${colors_off} jetzt installieren" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Installiere die ${light_yellow}Flatpak-Paketverwaltung${colors_off}, bitte warten ... "
        apt install flatpak -y &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          FLATPAK_INSTALLED=1
          FLATPAK_SYSTEM_VERSION="$(flatpak --version 2>/dev/null | awk '{print $2}' | xargs 2>/dev/null)"
          if [ "$FLATPAK_SYSTEM_VERSION" != "" ];
          then
            FLATPAK_ACTIVE=1
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
        else
          e_and_l "$ERROR_TAG"
        fi
        add_full_log
      fi
      e_and_l ""
    fi
    # --------------------------------------------------------------------------
    # SNAP (sinnvollerweise nur wenn Snap nicht deaktiviert werden soll)
    # --------------------------------------------------------------------------
    if [[ ${OPTION_FLAG[snapkill]} -eq 0 || ${OPTION_FLAG[snapstop]} -eq 0 ]] &&
       [ ${OPTION_FLAG[addsnap]} -eq 1 ];
    then
      # --------------------------------------------------------------
      # Wenn Snap nicht installiert ist aber installiert werden kann,
      # dann zur Installation anbieten
      # --------------------------------------------------------------
      if [ $SNAP_INSTALLED -eq 0 ] &&
         [ $(apt list "snapd" 2>/dev/null | grep -i -c "snapd") -gt 0 ];
      then
        e_and_l " $ACHTUNG_TAG: Die Snap-Paketverwaltung ist nicht installiert."
        install_snap
      fi
      # ---------------------------------------------------------
      # Wenn Snap zwar installiert aber deaktiviert ist und auch
      # nicht aktiviert werden soll, dann Hinweis dazu anzeigen
      # ---------------------------------------------------------
      if [ $SNAP_INSTALLED -gt 0 ] &&
         [ $SNAP_ACTIVE -eq 0 ] &&
         [ ${OPTION_FLAG[snapcont]} -eq 0 ];
      then
        e_and_l " $ACHTUNG_TAG: Die Snap-Paketverwaltung ist deaktiviert. Um Programmpakete als Snap"
        e_and_l " installieren zu können, muss zuerst die Snap-Paketverwaltung aktiviert werden."
      fi
      # ------------------------------------------------
    fi
  fi
fi # Ende Flatpak- und Snap-Verwaltung installieren

#===============================================================================
# Paketlisten der Repositories aktualisieren
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then

  if [ ${OPTION_FLAG[norepo]} -eq 0 ] ||
     [ $FLATPAK_ACTIVE -eq 1 ];
  then
    e_and_l "$FULL_LINE"
    e_and_l " ${bold_blue}Aktualisierung der Paketlisten${colors_off}"
    e_and_l "$FULL_LINE"
  fi

  #=============================================================================
  # Standard-Repo aktualisieren
  #=============================================================================
  REPO_UPDATE_TEXT=" Aktualisierung des Standard-Repository"
  if [ ${OPTION_FLAG[norepo]} -eq 0 ];
  then
    if [ $TOTAL_PACKS -gt 0 ] ||
       [ $USE_ILIST_FILE -eq 1 ] ||
       [ ${OPTION_FLAG[desktop]} -eq 1 ] ||
       [ ${OPTION_FLAG[extras]} -eq 1 ] ||
       [ ${OPTION_FLAG[exupdate]} -eq 1 ] ||
       [ ${OPTION_FLAG[remove]} -eq 1 ] ||
       [ ${OPTION_FLAG[repair]} -eq 1 ];
    then
      repo_update "$REPO_UPDATE_TEXT, bitte warten ... "
    else
      e_and_l "${dark_gray}$REPO_UPDATE_TEXT übersprungen  ... (nicht benötigt)${colors_off}"
    fi
  else
    e_and_l "${dark_gray}$REPO_UPDATE_TEXT übersprungen  ... (manuell abgewählt)${colors_off}"
  fi

  #=============================================================================
  # Das Flatpak-Repo und die Flatpak-Listen aktualisieren
  #=============================================================================
  if [ $FLATPAK_ACTIVE -eq 1 ];
  then
    # --------------------------------------------------------------------------
    # Standard-Flatpak-Repo (Flathub) hinzufügen
    # --------------------------------------------------------------------------
    if [ $(flatpak remotes | grep -c -i -E "flathub") -eq 0 ];
    then
      flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo &>/dev/null
    fi
    if [ ${OPTION_FLAG[addflat]} -eq 1 ];
    then
      e_and_l -n " Aktualisierung des Flatpak-Repository, bitte warten  ... "
      # Flatpak-Repo-Updates nur einmal täglich durchführen
      if [ $(find "$DOWNLOAD_DIR" -type f -iname "flatpak_appstream_update_blocker" -mtime -1 -print0 2>/dev/null | grep -i -c -E "flatpak_appstream_update_blocker") -eq 0 ];
      then
        echo -e $(date) > "$DOWNLOAD_DIR/flatpak_appstream_update_blocker" 2>/dev/null
        flatpak update --appstream flathub 2>/dev/null
        remove_file "$FLATPAK_REMOTE_LIST"
      fi
      # Liste der verfügbaren Flatpaks erstellen
      if [ ! -s "$FLATPAK_REMOTE_LIST" ];
      then
        flatpak remote-ls --app --columns=name,version,ref > "$FLATPAK_REMOTE_LIST" 2>/dev/null
      fi
      e_and_l "$OK_TAG"
    fi
    e_and_l -n " Aktualisierung der Flatpak-Statusinfos, bitte warten ... "
    update_flatpak_list
    e_and_l "$OK_TAG"
  fi # Ende Flatpak-Repo und die Flatpak-Listen aktualisieren

fi

# ==============================================================================
# Deaktivierung und Entfernung der Snap-Paketverwaltung
# ==============================================================================
# ------------------------------------------------------------------------------
# Abfrage ob Deaktivierung oder Entfernung gewünscht wird
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [[ ${OPTION_FLAG[snapkill]} -eq 1 || ${OPTION_FLAG[snapstop]} -eq 1 ]];
then
  e_and_l "$FULL_LINE"
  if [ ${OPTION_FLAG[snapkill]} -eq 1 ];
  then
    e_and_l " ${bold_blue}Entfernung der Snap-Paketverwaltung${colors_off} ${dark_gray}[snapkill]${colors_off}"
  else
    e_and_l " ${bold_blue}Deaktivierung der Snap-Paketverwaltung${colors_off} ${dark_gray}[snapstop]${colors_off}"
  fi
  e_and_l "$FULL_LINE"

  SNAP_STOP_SUCCESS=0
  SNAP_STOP_ACTION_TEXT_1=""
  SNAP_STOP_ACTION_TEXT_2=""

  if [ $SNAP_INSTALLED -gt 0 ];
  then

    SNAP_REMOVE_TEXT=" Bei der ${bold_yellow}Entfernung${colors_off} der Snap-Paketverwaltung werden sämtliche dazu gehörigen"$'\n'
    SNAP_REMOVE_TEXT+=" Komponenten und als Snap installierten Programme sowie deren Benutzer-Daten"$'\n'
    SNAP_REMOVE_TEXT+=" vollständig gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden,"$'\n'
    SNAP_REMOVE_TEXT+=" das Snap-System und alle Snaps müssten bei Bedarf neu installiert werden."

    # --------------------------------------------------------------------
    # Wenn Snap aktiv ist, dann Deaktivierung und Entfernung anbieten ...
    # --------------------------------------------------------------------
    if [ $SNAP_ACTIVE -gt 0 ];
    then
      e_and_l " Die ${bold_white}Snap-Paketverwaltung${colors_off} führt aufgrund ihrer Architektur schnell zu sehr"
      e_and_l " großen Mengen redundanter Daten und Einschränkungen der freien Paket-Auswahl,"
      e_and_l " sowie zu ganz erheblichen Performance-Einbußen beim Starten von Anwendungen."
      create_backup_file "$SNAP_INSTALLED_PKG_LIST"
      update_snap_list "$SNAP_INSTALLED_PKG_LIST"
      declare -A SNAP_PKG_LIST
      if [ -s "$SNAP_INSTALLED_PKG_LIST" ];
      then
        e_and_l " Folgende ${bold_white}Anwendungen${colors_off} sind derzeit als ${bold_white}Snap${colors_off} installiert:"
        e_and_l "$HALF_MINUS_LINE"
        i=0
        while read snap_name;
        do
          if [ "$snap_name" != "" ];
          then
            e_and_l " - $snap_name"
            SNAP_PKG_LIST[$i]="$snap_name"
            ((i+=1))
          fi
        done < "$SNAP_INSTALLED_PKG_LIST"
        e_and_l "$HALF_MINUS_LINE"
      fi
      e_and_l " Die Snap-Paketverwaltung kann einschließlich sämtlicher als Snap installierten"
      e_and_l " Anwendungen (Snaps) vollständig entfernt oder optional nur deaktiviert werden."
      e_and_l " Sämtliche Snaps können danach als reguläre Programmpakete aus anderen Quellen"
      e_and_l " bezogen und installiert werden."
      e_and_l ""
      e_and_l " Bei der ${bold_yellow}Deaktivierung${colors_off} der Snap-Paketverwaltung werden sämtliche Komponenten"
      e_and_l " dieser deaktiviert und können ebenso schnell wieder aktiviert werden. Die als"
      e_and_l " Snap installierten Programme können dabei funktionslos erhalten werden, oder "
      e_and_l " zur Vermeidung von Konflikten auch individuell gelöscht werden."
      e_and_l ""
      e_and_l "$SNAP_REMOVE_TEXT"
      e_and_l ""
      e_and_l " $HINWEIS_TAG: Selbstverständlich sollte in jedem Fall vorher eine ${bold_white}Vollsicherung${colors_off} des"
      e_and_l " gesamten Systems gemacht worden sein!"
      e_and_l ""
      e_and_l " Was soll ich jetzt tun?"
      e_and_l " [${bold_yellow}0${colors_off}] Abbrechen, die Snap-Paketverwaltung nicht entfernen oder deaktivieren"
      e_and_l " [${bold_yellow}1${colors_off}] Die Snap-Paketverwaltung nur ${light_yellow}deaktivieren${colors_off} und wahlweise Snaps löschen"
      e_and_l " [${bold_yellow}2${colors_off}] Die Snap-Paketverwaltung und alle Snaps ${light_yellow}vollständig entfernen${colors_off}"
      user_choice_012
      SNAP_DEACTIVATE_MODE=$?
      OPTION_FLAG[snapkill]=0
      OPTION_FLAG[snapstop]=0
      if [ $SNAP_DEACTIVATE_MODE -eq 1 ]; then OPTION_FLAG[snapstop]=1; fi
      if [ $SNAP_DEACTIVATE_MODE -eq 2 ]; then OPTION_FLAG[snapkill]=1;  fi
    # --------------------------------------------------------------------
    # ... sonst, wenn Snap installiert, aber inaktiv ist ...
    # --------------------------------------------------------------------
    else
      # Wenn Snap entfernt werden soll, dann Sicherheitsabfrage durchführen
      if [ ${OPTION_FLAG[snapkill]} -eq 1 ];
      then
        e_and_l "$SNAP_REMOVE_TEXT"
        ask_yes_or_no_plus "" " Die ${light_cyan}Snap-Paketverwaltung${colors_off} vollständig entfernen" "" "n"
        OPTION_FLAG[snapkill]=$?
        OPTION_FLAG[snapstop]=0
      fi
      # Wenn Snap deaktiviert werden soll, dann Hinweis darauf anzeigen,
      # dass es das schon ist und Fortführung blockieren
      if [ ${OPTION_FLAG[snapstop]} -eq 1 ];
      then
        e_and_l " ${bold_green}Glückwunsch${colors_off}, die ${light_cyan}Snap-Paketverwaltung${colors_off} scheint nicht aktiv zu sein ... $OK_TAG"
        # OPTION_FLAG[snapcont]=0
        OPTION_FLAG[snapkill]=0
        OPTION_FLAG[snapstop]=0
      fi
    fi
    # --------------------------------------------------------------------
  else
    e_and_l " ${bold_green}Glückwunsch${colors_off}, die ${light_cyan}Snap-Paketverwaltung${colors_off} scheint nicht installiert zu sein ... $OK_TAG"
    # OPTION_FLAG[snapcont]=0
    OPTION_FLAG[snapkill]=0
    OPTION_FLAG[snapstop]=0
  fi
fi

# ------------------------------------------------------------------------------
# Deaktivierung der Snap-Paketverwaltung
# ---------------------------------------
# ACHTUNG: Reihenfolge mit vorgeschalteter Abfrage (s.o.) nicht ändern!
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[snapstop]} -eq 1 ];
then
  e_and_l "$HALF_MINUS_LINE"
  e_and_l " ${bold_white}Deaktivierung der Snap-Paketverwaltung${colors_off}"
  e_and_l " Im nächsten Schritt können wahlweise alle Anwendungen vollständig gelöscht"
  e_and_l " werden, welche als Snap installiert sind, sowie die Snap-Paketverwaltung"
  e_and_l " selbst deaktiviert und deren automatischer Neustart verhindert werden."
  ask_yes_or_no_plus "" " Snaps wahlweise entfernen und ${light_cyan}Snap-Verwaltung deaktivieren${colors_off}" "" "n"
  if [ $? -eq 1 ];
  then
    e_and_l "$HALF_MINUS_LINE"
    # --------------------------------------------------------------------
    # 1. Installierte Snaps (Anwendungen) deinstallieren
    # --------------------------------------------------------------------
    e_and_l " ${bold_white}Schritt 1${colors_off} - Installierte Snaps (Anwendungen) deinstallieren"
    SNAP_REMOVE_RESULT=0
    ANZAHL_SNAPS=${#SNAP_PKG_LIST[@]}
    if [ $ANZAHL_SNAPS -gt 0 ];
    then
      e_and_l " Es wird dringend empfohlen, vor der Deaktivierung der Snap-Paketverwaltung"
      e_and_l " alle als Snap installierten Anwendungen zu deinstallieren, zumal diese danach"
      e_and_l " ohnehin nicht mehr ausführbar sind, um eventuell Konfigurations-Konflikte mit"
      e_and_l " den später aus anderer Quelle installierten gleichen Anwendungen zu vermeiden!"
      e_and_l " Zur Deinstallation stehen folgende Optionen zur Verfügung:"
      e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, keine Snaps löschen"
      e_and_l " [${bold_yellow}1${colors_off}] Jedes Snap einzeln jeweils mit Abfrage Löschen"
      e_and_l " [${bold_yellow}2${colors_off}] Alle Snaps ohne einzelne Abfragen löschen"
      user_choice_012 2
      SNAP_PURGE_ACTION=$?
      # ----------------------------------------------
      # Sicherheitsabfrage zur Auswahl aller Elemente
      # ----------------------------------------------
      if [ $SNAP_PURGE_ACTION -eq 2 ];
      then
        e_and_l " Hast Du die Liste ganz genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Wirklich ${bold_red}alle${colors_off} vorstehenden Snaps löschen" "" "n"
        if [ $? -eq 0 ]; then SNAP_PURGE_ACTION=0; fi
      fi
      # ----------------------------------------------
      if [ $SNAP_PURGE_ACTION -gt 0 ];
      then
        echo -e -n "" > "$LOG_TEMP"
        i=0
        while [ $i -lt $ANZAHL_SNAPS ];
        do
          DO_PURGE_SNAP=1
          snap_name="${SNAP_PKG_LIST[$i]}"
          if [ $(LANG=C snap info "$snap_name" 2>/dev/null | grep -i -c -E "installed\:") -ne 0 ];
          then
            if [ $SNAP_PURGE_ACTION -eq 1 ];
            then
              e_and_l "$HALF_MINUS_LINE"
              ask_yes_or_no_plus "" " Snap ${light_cyan}$snap_name${colors_off} entfernen" "" "j"
              if [ $? -eq 0 ]; then DO_PURGE_SNAP=0; fi
            fi
            # ----------------
            # Element Löschen
            # ----------------
            if [ $DO_PURGE_SNAP -eq 1 ];
            then
              INST_STATUS=2
              e_and_l -n " Deinstalliere ${light_yellow}$snap_name${colors_off}, bitte warten ... "
              snap remove --purge "$snap_name" &>/dev/null
              if [ $? -eq 0 ];
              then
                remove_starter "$snap_name"
                e_and_l "$OK_TAG"
                remove_snapshots "$snap_name" 1
                if [ -d "$USER_HOME_DIR/snap/$snap_name" ];
                then
                  e_and_l -n " Lösche Ordner ${light_yellow}$USER_HOME_DIR/snap/$snap_name${colors_off}, bitte warten ... "
                  rm -f -r "$USER_HOME_DIR/snap/$snap_name" &>/dev/null
                  if [ $? -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                  else
                    ((SNAP_REMOVE_RESULT+=1))
                    e_and_l "$ERROR_TAG"
                  fi
                fi
              else
                ((SNAP_REMOVE_RESULT+=1))
                e_and_l "$ERROR_TAG"
              fi
            fi
          fi
          ((i+=1))
        done
      fi
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste der zuvor installierten Snaps ist gespeichert in:"
      e_and_l " ${light_yellow}$SNAP_INSTALLED_PKG_LIST${colors_off}"
    else
      e_and_l " ${bold_green}Perfekt${colors_off}, es scheinen keine ${bold_white}Anwendungen${colors_off} als Snap installiert zu sein ... $OK_TAG"
    fi
    e_and_l "$HALF_MINUS_LINE"
    # --------------------------------------------------------------------
    # 2. Snap-System vollständig deaktivieren (nicht deinstallieren)
    # --------------------------------------------------------------------
    e_and_l " ${bold_white}Schritt 2${colors_off} - Deaktivierung der Snap-Paketverwaltung"
    DO_DEACTIVATE_SNAP=1
    # ----------------------------------------------------------------
    # Falls noch Snaps installiert sind, noch eine Sicherheitsabfrage
    # ----------------------------------------------------------------
    SNAP_INST_PKG_LIST_2="${SNAP_INSTALLED_PKG_LIST/list/tmp}"
    update_snap_list "$SNAP_INST_PKG_LIST_2"
    if [ -s "$SNAP_INST_PKG_LIST_2" ];
    then
      e_and_l " $ACHTUNG_TAG, folgende Anwendungen sind noch als Snap installiert:"
      e_and_l "$HALF_MINUS_LINE"
      while read snap_name;
      do
        if [ "$snap_name" != "" ];
        then
          e_and_l " - $snap_name"
        fi
      done < "$SNAP_INST_PKG_LIST_2"
      remove_file "$SNAP_INST_PKG_LIST_2"
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " ${light_yellow}Diese Anwendungen sind nach der Deaktivierung der Snap-Paketverwaltung nicht"
      e_and_l " mehr als Snap aufrufbar und werden somit auch nicht mehr funktionieren!${colors_off}"
      ask_yes_or_no_plus "" " Die ${light_cyan}Snap-Paketverwaltung${colors_off} jetzt trotzdem deaktivieren" "" "n"
      DO_DEACTIVATE_SNAP=$?
      e_and_l "$HALF_MINUS_LINE"
    fi
    # ----------------------------------------------------------------
    if [ $DO_DEACTIVATE_SNAP -eq 1 ];
    then
      # ---------------------------------
      # 2.1 Snap-System-Dienste anhalten
      # ---------------------------------
      e_and_l -n " - Stoppe Snap-Prozesse und Snap-System-Dienste, bitte warten  ... "
      SNAP_STOP_RESULT=0
      for snap_component in ${SNAP_SYS_COMPONENTS[@]};
      do
        systemctl stop $snap_component &>/dev/null
        if [ $? -ne 0 ]; then ((SNAP_STOP_RESULT+=1)); fi
      done
      if [ $SNAP_STOP_RESULT -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG ($SNAP_STOP_RESULT)"
      fi
      # -------------------------------------
      # 2.2 Snap-System-Dienste deaktivieren
      # -------------------------------------
      e_and_l -n " - Blockiere Neu-Start aller Snap-System-Dienste, bitte warten ... "
      SNAP_DISABLE_RESULT=0
      for snap_component in ${SNAP_SYS_COMPONENTS[@]};
      do
        systemctl disable $snap_component &>/dev/null
        if [ $? -ne 0 ]; then ((SNAP_DISABLE_RESULT+=1)); fi
        systemctl mask --now $snap_component &>/dev/null
        if [ $? -ne 0 ]; then ((SNAP_DISABLE_RESULT+=1)); fi
      done
      if [ $SNAP_DISABLE_RESULT -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG ($SNAP_DISABLE_RESULT)"
      fi
      # -------------------------------------------------------
      # 2.3 Installation und Updates von Snap blockieren sowie
      #     verbliebene (temporäre) Snap-Dateien löschen
      # -------------------------------------------------------
      SNAP_HOLD_RESULT=0
      SNAP_RMDIR_RESULT=0
      snap_hold_and_clean 1

      # ----------------------------
      # Ergebnisanzeige vorbereiten
      # ----------------------------
      SNAP_STOP_ACTION_TEXT_1="deaktiviert"
      SNAP_STOP_ACTION_TEXT_2="Deaktivierung"
      if [ $SNAP_STOP_RESULT -eq 0 ] &&
         [ $SNAP_DISABLE_RESULT -eq 0 ] &&
         [ $SNAP_HOLD_RESULT -eq 0 ] &&
         [ $SNAP_RMDIR_RESULT -eq 0 ];
      then
        SNAP_STOP_SUCCESS=1
      fi
    else
      e_and_l " $USER_CHOICE_NO"
    fi
  else
    e_and_l " $USER_CHOICE_NO"
  fi
fi

# ------------------------------------------------------------------------------
# Entfernung der Snap-Paketverwaltung
# ------------------------------------
# ACHTUNG: Reihenfolge mit vorgeschalteter Abfrage sowie Routine zur
# Deaktivierung der Snap-Paketverwaltung (s.o.) nicht ändern!
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[snapkill]} -eq 1 ];
then
  e_and_l "$HALF_MINUS_LINE"
  e_and_l " ${bold_white}Entfernung der Snap-Paketverwaltung${colors_off}"
  e_and_l " $ACHTUNG_TAG: Die Snap-Paketverwaltung und alle als Snap installierten Programme"
  e_and_l " sowie deren Benutzer-Daten werden vollständig gelöscht, und es können danach"
  e_and_l " auch keine Programme mehr als Snap installiert werden."
  ask_yes_or_no_plus "" " Die ${light_cyan}Snap-Paketverwaltung und alle Snaps${colors_off} vollständig entfernen" "" "n"
  if [ $? -eq 1 ];
  then
    e_and_l "$HALF_MINUS_LINE"
    # ------------------------------------------------------------------
    # 1. Snaps und alle als Snap installierten Programmpakete entfernen
    # ------------------------------------------------------------------
    e_and_l -n " - Entferne Snap-System, das dauert etwas länger, bitte warten ... "
    # -------------------------------------------------------
    # Installations- und Update-Blockaden für snapd aufheben
    # -------------------------------------------------------
    SNAP_UNHOLD_RESULT=0
    snap_unhold
    # ----------------------------------
    # Mit Ausgabe sämtlicher Meldungen:
    # { apt purge snapd -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
    # PURGE_SNAP_RESULT=$(cat "$LAST_EXIT_CODE")
    # add_full_log
    # remove_file "$LAST_EXIT_CODE"
    # ----------------------------------
    apt-get purge snapd -y &>"$LOG_TEMP" # Ohne Ausgabe von Meldungen
    PURGE_SNAP_RESULT=$?
    if [ $PURGE_SNAP_RESULT -eq 0 ];
    then
      e_and_l "$OK_TAG"
    else
      e_and_l "$ERROR_TAG"
      add_full_log
    fi
    # ------------------------------------------------------
    # 2. Installation und Updates von Snap blockieren sowie
    #    verbliebene (temporäre) Snap-Dateien löschen
    # ------------------------------------------------------
    SNAP_HOLD_RESULT=0
    SNAP_RMDIR_RESULT=0
    snap_hold_and_clean 0 # Ohne apt-mark hold, weil es hier kein snap mehr gibt
    # ----------------------------
    # Ergebnisanzeige vorbereiten
    # ----------------------------
    SNAP_STOP_ACTION_TEXT_1="entfernt"
    SNAP_STOP_ACTION_TEXT_2="Entfernung"
    if [ $PURGE_SNAP_RESULT -eq 0 ] &&
       [ $SNAP_HOLD_RESULT -eq 0 ] &&
       [ $SNAP_RMDIR_RESULT -eq 0 ];
    then
      SNAP_STOP_SUCCESS=1
    fi
  else
    e_and_l " $USER_CHOICE_NO"
  fi
fi

# ------------------------------------------------------------------------------
# Ergebnisanzeige zur Deaktivierung oder Entfernung der Snap-Paketverwaltung
# ---------------------------------------------------------------------------
# ACHTUNG: Reihenfolge mit vorgeschalteter Abfrage sowie Routinen zur
# Deaktivierung oder Entfernung der Snap-Paketverwaltung (s.o.) nicht ändern!
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [[ ${OPTION_FLAG[snapkill]} -eq 1 || ${OPTION_FLAG[snapstop]} -eq 1 ]];
then
  if [ $SNAP_STOP_SUCCESS -eq 1 ];
  then
    e_and_l " ${bold_green}Glückwunsch${colors_off}, die Snap-Paketverwaltung wurde erfolgreich $SNAP_STOP_ACTION_TEXT_1."
    if [ -s "$SNAP_INSTALLED_PKG_LIST" ];
    then
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " ${bold_green}Tipp${colors_off}: Um alle vorher als Snap installierten und entfernte Anwendungen wieder"
      e_and_l " neu aus anderer Quelle zu installieren, kann einfach die dabei erstellte Liste"
      e_and_l " verwendet werden. Dazu Lissy später wie folgt aufrufen:"
      e_and_l " ${light_yellow}${0} instlist \"$SNAP_INSTALLED_PKG_LIST\"${colors_off}"
      e_and_l " und je nach Wunsch die Optionen ${light_yellow}addflat${colors_off}, ${light_yellow}extends${colors_off} und ${light_yellow}external${colors_off} hinzufügen."
    fi
    e_and_l "$HALF_MINUS_LINE"
    repo_update " Aktualisiere das Repository, bitte warten ... "
    e_and_l "$HALF_MINUS_LINE"
    e_and_l " $HINWEIS_TAG: Zur Vermeidung von Konflikten durch eventuell noch im Hauptspeicher"
    e_and_l " verbliebene Teile der Snap-Paketverwaltung sollte das gesamte System vor der"
    e_and_l " Installation neuer Anwendungen neu gestartet werden."
  else
    if [ "$SNAP_STOP_ACTION_TEXT_2" != "" ];
    then
      e_and_l " $WARN_TAG: Bei $SNAP_STOP_ACTION_TEXT_2 der Snap-Paketverwaltung sind Fehler aufgetreten."
    fi
  fi
fi

# ------------------------------------------------------------------------------
# Re-Aktivierung der Snap-Paketverwaltung
# ----------------------------------------
# ACHTUNG: Reihenfolge mit vorgeschalteter Abfrage sowie Routinen zur
# Deaktivierung oder Entfernung der Snap-Paketverwaltung (s.o.) nicht ändern!
# ------------------------------------------------------------------------------
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[snapcont]} -eq 1 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Re-Aktivierung der Snap-Paketverwaltung${colors_off} ${dark_gray}[snapcont]${colors_off}"
  e_and_l "$FULL_LINE"
  if [ $SNAP_INSTALLED -gt 0 ];
  then
    if [ $SNAP_ACTIVE -eq 0 ];
    then
      e_and_l " Die ${bold_white}Snap-Paketverwaltung${colors_off} ist installiert, scheint aber nicht aktiv zu sein."
      ask_yes_or_no_plus "snap_reactivate" " Soll die ${light_cyan}Snap-Paketverwaltung${colors_off} jetzt reaktiviert werden" "" "n"
      if [ $? -eq 1 ];
      then
        # ----------------------------------------------------------------------
        # 1. Snap-System-Dienste (re)aktivieren
        # ----------------------------------------------------------------------
        e_and_l "$HALF_MINUS_LINE"
        e_and_l -n " - Reaktiviere deaktivierte Snap-System-Dienste, bitte warten ... "
        SNAP_ENABLE_RESULT=0
        for snap_component in ${SNAP_SYS_COMPONENTS[@]};
        do
          systemctl unmask $snap_component &>/dev/null
          if [ $? -ne 0 ]; then ((SNAP_ENABLE_RESULT+=1)); fi
          systemctl enable $snap_component &>/dev/null
          if [ $? -ne 0 ]; then ((SNAP_ENABLE_RESULT+=1)); fi
        done
        if [ $SNAP_ENABLE_RESULT -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG ($SNAP_ENABLE_RESULT)"
        fi
        # ----------------------------------------------------------------------
        # 2. Snap-System-Dienste starten
        # ----------------------------------------------------------------------
        e_and_l -n " - Starte Snap-Prozesse und Snap-System-Dienste, bitte warten ... "
        SNAP_START_RESULT=0
        for snap_component in ${SNAP_SYS_COMPONENTS[@]};
        do
          systemctl start $snap_component &>/dev/null
          if [ $? -ne 0 ]; then ((SNAP_START_RESULT+=1)); fi
        done
        if [ $SNAP_START_RESULT -eq 0 ];
        then
          SNAP_ACTIVE=$(LANG=C systemctl status snapd 2>/dev/null | grep -c -i -E "\:\s*\bactive\b")
          if [ $SNAP_ACTIVE -gt 0 ];
          then
            SNAP_SYSTEM_VERSION="$(snap --version 2>/dev/null | grep -i -E "^\bsnap(d)*\b" | head -n 1 | awk '{print $2}' | xargs 2>/dev/null)"
          else
            SNAP_SYSTEM_VERSION=""
          fi
          if [ "$SNAP_SYSTEM_VERSION" != "" ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG ($SNAP_START_RESULT)"
          fi
        else
          e_and_l "$ERROR_TAG ($SNAP_START_RESULT)"
        fi
        # ----------------------------------------------------------------------
        # 3. Installations- und Update-Blockaden für snapd aufheben
        # ----------------------------------------------------------------------
        e_and_l -n " - Hebe Aktualisierungs-Blockade für Snapd auf, bitte warten  ... "
        SNAP_UNHOLD_RESULT=0
        snap_unhold
        if [ $SNAP_UNHOLD_RESULT -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
        # ----------------------------------------------------------------------
        # 4. Temporären Ordner für Snap wieder anlegen
        # ----------------------------------------------------------------------
        e_and_l -n " - Lege temporären Ordner für Snapd wieder an, bitte warten   ... "
        SNAP_MKDIR_RESULT=0
        if [ ! -d /var/cache/snapd ];
        then
          mkdir -p /var/cache/snapd &>/dev/null
          SNAP_MKDIR_RESULT=$?
        fi
        if [ $SNAP_MKDIR_RESULT -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
        # ----------------------------------------------------------------------
        # Ergebnis anzeigen (nur für Re-Aktivierung)
        # ----------------------------------------------------------------------
        if [ $SNAP_ENABLE_RESULT -eq 0 ] &&
           [ "$SNAP_SYSTEM_VERSION" != "" ] &&
           [ $SNAP_UNHOLD_RESULT -eq 0 ] &&
           [ $SNAP_MKDIR_RESULT -eq 0 ];
        then
          e_and_l " ${bold_green}Alles klar${colors_off}, die Snap-Paketverwaltung wurde erfolgreich reaktiviert."
          e_and_l "$HALF_MINUS_LINE"
          repo_update " Aktualisiere das Repository, bitte warten ... "
          e_and_l "$HALF_MINUS_LINE"
          e_and_l " $HINWEIS_TAG: Damit das Snap-System von laufenden Prozessen sicher als wieder aktiv"
          e_and_l " erkannt wird, sollte das gesamte System vor der Installation neuer Anwendungen"
          e_and_l " neu gestartet werden."
        else
          e_and_l " $WARN_TAG: Bei Reaktivierung der Snap-Paketverwaltung sind Fehler aufgetreten."
        fi
      fi
    else
      e_and_l " Die ${light_cyan}Snap-Paketverwaltung${colors_off} ist bereits aktiv ... $OK_TAG"
    fi
  else
    e_and_l " Die ${bold_white}Snap-Paketverwaltung${colors_off} ist nicht installiert und kann daher auch nicht"
    e_and_l -n " reaktiviert werden, "
    if [ $(apt list "snapd" 2>/dev/null | grep -i -c "snapd") -gt 0 ];
    then
      e_and_l "ist jedoch verfügbar und kann neu installiert werden."
      install_snap
    else
      e_and_l "ferner ist sie auf diesem Systen auch nicht verfügbar."
    fi
  fi
fi

#===============================================================================
# Update von Programmen, die keinen eigenen Eintrag im Repository besitzen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[exupdate]} -eq 1 ];
then
  # ----------------------------------------------------------------------------
  # Relevante Einstellungen des Benutzers zum Skript-Ablauf sichern und für
  # die Dauer der Update-Routine auf dazu erforderliche Werte setzen
  # ----------------------------------------------------------------------------
  PRESERVED_EXTERNAL_FLAG=${OPTION_FLAG[external]}
  OPTION_FLAG[external]=1
  PRESERVED_FORCE_FLAG=${OPTION_FLAG[force]}
  OPTION_FLAG[force]=0
  PRESERVED_QUIET_FLAG=${OPTION_FLAG[quiet]}
  OPTION_FLAG[quiet]=0
  PRESERVED_STATUS_FLAG=${OPTION_FLAG[status]}
  OPTION_FLAG[status]=0
  # ----------------------------------------------------------------------------
  e_and_l "$FULL_LINE"
  e_and_l -n " ${bold_blue}Updates für aus externen Quellen verfügbare Programme${colors_off} ${dark_gray}[exupdate]${colors_off}"
  if [ ${OPTION_FLAG[exupdall]} -eq 1 ]; then e_and_l -n " ${dark_gray}[exupdall]${colors_off}"; fi
  e_and_l ""
  e_and_l "$FULL_LINE"
  exupdate_counter=0
  for pkg_name in ${EXUPDATE_PKG_LIST[@]};
  do
    # ---------------------------------------------------------------
    # Freundlichen Namen und verfügbare Version des Pakets ermitteln
    # ---------------------------------------------------------------
    NEW_PKG_SRC=""
    IDX_NAME="$pkg_name"
    IDX_NAME+="_"
    IDX_NAME+="$ARCHITECTURE_MAIN"
    THE_PKG_INST_NAME="${DEB_PKG_NAME[$pkg_name]}"
    NEW_PKG_INST_VERS="${DEB_PKG_VERS[$pkg_name]}"
    NEW_PKG_INST_FILE="${DEB_PKG_FILE[$IDX_NAME]}"
    if [ "$NEW_PKG_INST_FILE" != "" ];
    then
      NEW_PKG_SRC="DEB"
    else
      THE_PKG_INST_NAME="${WEB_PKG_NAME[$pkg_name]}"
      NEW_PKG_INST_VERS="${WEB_PKG_VERS[$pkg_name]}"
      NEW_PKG_INST_FILE="${WEB_PKG_FILE[$IDX_NAME]}"
      if [ "$NEW_PKG_INST_FILE" != "" ];
      then
        NEW_PKG_SRC="WEB"
      fi
    fi
    # -------------------------------------------------------------
    # Status und Versionsnummer des installierten Pakets ermitteln
    # -------------------------------------------------------------
    get_install_status "$pkg_name"
    INST_STATUS=$?

    # ------------------------
    # Anzeige des Paketnamens
    # ------------------------
    if [ $INST_STATUS -ne 0 ] ||
       [ ${OPTION_FLAG[exupdall]} -eq 1 ];
    then
      if [ $exupdate_counter -ne 0 ]; then e_and_l "$HALF_LINE"; fi
      ((exupdate_counter+=1))
      e_and_l -n " ${light_green}"
      if [ "$THE_PKG_INST_NAME" != "" ];
      then
        e_and_l -n "$THE_PKG_INST_NAME"
      else
        e_and_l -n "$pkg_name"
      fi
      e_and_l -n "${colors_off}"
      if [ $INST_STATUS -ne 0 ];
      then
        if [ "$PKG_VERSION" != "" ] &&
           [ "$PKG_VERSION" != "0" ];
        then
          e_and_l -n " ${light_magenta}$PKG_VERSION${colors_off}"
        else
          if [ $INST_STATUS -gt 0 ]; then e_and_l -n " (Version unbekannt)"; fi
        fi
      fi
    fi

    # -------------------------------
    # Anzeige wenn nicht installiert
    # -------------------------------
    if [ $INST_STATUS -eq 0 ] &&
       [ ${OPTION_FLAG[exupdall]} -eq 1 ];
    then
      e_and_l " ist ${bold_red}nicht${colors_off} installiert."
    fi

    # -----------------------------
    # Anzeige der Installationsart
    # -----------------------------
    if [ $INST_STATUS -ne 0 ];
    then
      OLD_PKG_SRC="$(inst_status_to_name $INST_STATUS)"
      if [ "$OLD_PKG_SRC" != "" ];
      then
        e_and_l -n " ${dark_gray}($OLD_PKG_SRC)${colors_off}"
      fi
      e_and_l " ist installiert."
    fi

    # ----------------------------------
    # Hinweis wenn als SNAP installiert
    # ----------------------------------
    if [ $INST_STATUS -eq 2 ];
    then
      e_and_l " $HINWEIS_TAG${dark_gray}: Dieses Programm wird über die${colors_off} ${light_magenta}SNAP${colors_off}${dark_gray}-Paketverwaltung aktualisiert.${colors_off}"
    fi
    # -------------------------------------
    # Hinweis wenn als Flatpak installiert
    # -------------------------------------
    if [ $INST_STATUS -eq 6 ];
    then
      e_and_l " $HINWEIS_TAG${dark_gray}: Dieses Programm wird über die${colors_off} ${light_magenta}Flatpak${colors_off}${dark_gray}-Paketverwaltung aktualisiert.${colors_off}"
    fi

    # -------------------------------------------------------------------
    # Wenn installiert, dann prüfen ob eine neuere Version vorhanden ist
    # und gegebenenfalls als Update anbieten
    # -------------------------------------------------------------------
    if [ $INST_STATUS -ne 0 ];
    then

      if [[ $INST_STATUS -ne 2 && $INST_STATUS -ne 6 ]] ||
         [ ${OPTION_FLAG[exupdall]} -eq 1 ];
      then

        UPDATE_AVAILABLE=0
        if [ "$NEW_PKG_INST_FILE" != "" ];
        then
          CUR_VERSION_VALUE=$(get_version_value ${PKG_VERSION})
          NEW_VERSION_VALUE=$(get_version_value ${NEW_PKG_INST_VERS})
          if [ $CUR_VERSION_VALUE -lt $NEW_VERSION_VALUE ];
          then
            UPDATE_AVAILABLE=1
          fi
        fi
        # ------------------------------------------------
        # Wenn es eine neuere Version gibt, dann anbieten
        # ------------------------------------------------
        if [ $UPDATE_AVAILABLE -eq 1 ];
        then
          e_and_l -n " Die Version ${light_yellow}$NEW_PKG_INST_VERS${colors_off} steht"
          # -----------------------------------------------
          # Bei unterschiedlichen Quellen Hinweis anzeigen
          # -----------------------------------------------
          if [ "$NEW_PKG_SRC" != "" ] &&
             [ "$NEW_PKG_SRC" != "$OLD_PKG_SRC" ];
          then
            # ------------------------------------------------------------
            # Mit Dateien des Typs .deb installierte Programme werden von
            # apt als aus dem Standard installiert ausgegeben, daher in
            # dieser Kombination keinen Hinweis ausgeben
            # ------------------------------------------------------------
            if [ "$OLD_PKG_SRC" != "STD" ] || [ "$NEW_PKG_SRC" != "DEB" ];
            then
              e_and_l -n " aus ${light_yellow}anderer Quelle${colors_off} ${dark_gray}($NEW_PKG_SRC)${colors_off}"
            fi
          fi
          e_and_l " zur Verfügung."

          if [[ "$NEW_PKG_SRC" == "WEB" && ${OPTION_FLAG[external]} -ne 1 ]];
          then
            e_and_l " $HINWEIS_TAG: Die Option zur Installation von Paketen aus dieser Quelle wurde nicht"
            e_and_l " ausgewählt, daher kann auch kein Update des Pakets daraus durchgeführt werden."
            e_and_l " Aus Sicherheitsgründen und zugunsten einer höheren Flexibilität zur Auswahl"
            e_and_l " der Paketquellen wird diese Option hier auch nicht automatisch aktiviert."
          else
            e_and_l " Zum Update muss die alte Version erst vollständig entfernt und danach die"
            e_and_l " neue Version installiert werden. Eventuell bestehende Konfigurationsdaten"
            e_and_l " werden zuvor natürlich gesichert."
            # --------------------------------------------------------
            # Falls vorhanden Voraussetzungen anzeigen und evaluieren
            # --------------------------------------------------------
            FILL_WORD="jetzt"
            SHOW_PKG_MSG=""
            TMP_PACK_MSG="${WEB_PKG_MESG[$pkg_name]}"
            if [ "$TMP_PACK_MSG" == "" ]; then TMP_PACK_MSG="${DEB_PKG_MESG[$pkg_name]}"; fi
            if [ "$TMP_PACK_MSG" != "" ];
            then
              SHOW_PKG_MSG="${bold_red}Achtung:${colors_off} ${light_yellow}$TMP_PACK_MSG${colors_off}"
            fi
            if [ "$SHOW_PKG_MSG" != "" ];
            then
              EVAL_TEST="${WEB_PKG_EVAL["$pkg_name"]}"
              if [ "$EVAL_TEST" == "" ]; then EVAL_TEST="${DEB_PKG_EVAL["$pkg_name"]}"; fi
              if [ "$EVAL_TEST" != "" ];
              then
                eval "$EVAL_TEST" &>/dev/null
                if [ $? -ne 0 ];
                then
                  e_and_l " $SHOW_PKG_MSG"
                  e_and_l " Diese Voraussetzung scheint ${bold_red}nicht${colors_off} erfüllt zu sein!"
                  FILL_WORD="trotzdem"
                fi
              else
                e_and_l " $SHOW_PKG_MSG"
                e_and_l " Bitte prüfe vor der Installation, ob diese Voraussetzung erfüllt ist."
              fi
            fi
            # --------------------------------------
            # Vor Update zweimal bewusst bestätigen
            # --------------------------------------
            ask_yes_or_no_plus "exupdate_$pkg_name" " ${light_cyan}$pkg_name${colors_off} $FILL_WORD auf Version ${light_yellow}$NEW_PKG_INST_VERS${colors_off} updaten" "" "n"
            if [ $? -eq 1 ];
            then
              ask_yes_or_no_plus "" " Programm ${bold_yellow}$pkg_name $PKG_VERSION${colors_off} entfernen" "" "n"
              if [ $? -eq 1 ];
              then
                e_and_l " $USER_CHOICE_YES"
                # ----------------------------------------------------------------
                # 1. Konfigurationsdaten sichern
                # ----------------------------------------------------------------
                CONFIG_NAMES=( "$USER_HOME_DIR/$pkg_name"
                              "$USER_HOME_DIR/.$pkg_name"
                              "$USER_HOME_DIR/$THE_PKG_INST_NAME"
                              "$USER_CONFIG_DIR/$pkg_name"
                              "$USER_CONFIG_DIR/.$pkg_name"
                              "$USER_CONFIG_DIR/$THE_PKG_INST_NAME"
                              "$USER_HOME_DIR/Dokumente/$pkg_name"
                              "$USER_HOME_DIR/Dokumente/.$pkg_name"
                              "$USER_HOME_DIR/Dokumente/$THE_PKG_INST_NAME"
                              "$USER_HOME_DIR/.local/share/$pkg_name"
                              "$USER_HOME_DIR/.local/share/.$pkg_name"
                              "$USER_HOME_DIR/.local/share/$THE_PKG_INST_NAME" )
                for config_name in ${CONFIG_NAMES[@]};
                do
                  BACKUP_NAME="${config_name}_bak"
                  # -------
                  # Ordner
                  # -------
                  if [ -d "$config_name" ] &&
                     [ ! -d "$BACKUP_NAME" ];
                  then
                    cp -r -u --no-dereference "$config_name" "$BACKUP_NAME" &>/dev/null
                    if [ $? -eq 0 ];
                    then
                      chown -R "$USER_USERNAME:$USER_USERNAME" "$BACKUP_NAME" &>/dev/null
                      e_and_l " ${bold_magenta}Konfiguration${colors_off} gesichert in ${bold_magenta}$BACKUP_NAME${colors_off}"
                    fi
                  fi
                  # -----------------
                  # Einzelne Dateien
                  # -----------------
                  if [ -f "$config_name" ] &&
                     [ ! -s "$BACKUP_NAME" ];
                  then
                    cp -u --no-dereference "$config_name" "$BACKUP_NAME" &>/dev/null
                    if [ $? -eq 0 ];
                    then
                      chown -R "$USER_USERNAME:$USER_USERNAME" "$BACKUP_NAME" &>/dev/null
                      e_and_l " ${bold_magenta}Konfiguration${colors_off} gesichert in ${bold_magenta}$BACKUP_NAME${colors_off}"
                    fi
                  fi
                done
                # ----------------------------------------------------------------
                # 2. Benutzerbezogenen Autostart-Eintrag sichern
                # ----------------------------------------------------------------
                AUTOSTART_FILE="$USER_CONFIG_DIR/autostart/${pkg_name}.desktop"
                if [ -f "$AUTOSTART_FILE" ];
                then
                  BACKUP_FILE="${AUTOSTART_FILE}_bak"
                  cp -u --no-dereference "$AUTOSTART_FILE" "$BACKUP_FILE" &>/dev/null
                  if [ $? -eq 0 ];
                  then
                    chown -R "$USER_USERNAME:$USER_USERNAME" "$BACKUP_FILE" &>/dev/null
                    e_and_l " ${bold_magenta}Autostart${colors_off} gesichert in ${bold_magenta}$BACKUP_FILE${colors_off}"
                  fi
                fi
                # ----------------------------------------------------------------
                # 3. Programm löschen
                # Programme werden vollständig inklusive ihrer Konfigurationsdaten
                # gelöscht, um bei der Gelegenheit ev. bestehende Altlasten mit zu
                # bereinigen. Die Benutzer-bezogenen Konfigurations-Daten bleiben
                # hingegen erhalten (und wurden zudem zuvor ja auch noch gesichert).
                # ----------------------------------------------------------------
                remove_pkg "$pkg_name" 1

                # ----------------------------------------------------------------
                # Nur weitermachen, wenn das Löschen erfolgreich war
                # ----------------------------------------------------------------
                if [ $REMOVE_RESULT -eq 0 ];
                then
                  # --------------------------------------------------------------
                  # 4. Starter löschen
                  # --------------------------------------------------------------
                  remove_starter "$pkg_name"
                  # --------------------------------------------------------------
                  # 5. Programm neu installieren
                  # --------------------------------------------------------------
                  LAST_ERW_PACK=""
                  LAST_PPA_PACK=""
                  # --------------------------------------
                  # Für die Neu-Installation die Optionen
                  # "force" und "quiet" berücksichtigen
                  # --------------------------------------
                  OPTION_FLAG[force]=$PRESERVED_FORCE_FLAG
                  OPTION_FLAG[quiet]=$PRESERVED_QUIET_FLAG
                  install_pkg $pkg_name 0 0 1
                  OPTION_FLAG[force]=0
                  OPTION_FLAG[quiet]=0
                fi
              fi
            fi
          fi
        else
          e_and_l " ${dark_gray}Auf dem Lissy-Server steht keine neuere Version zur Verfügung ...${colors_off} $OK_TAG"
        fi

      fi
    fi
  done
  if [ $exupdate_counter -eq 0 ];
  then
    e_and_l " Es sind keine aus externen Quellen verfügbare Programme installiert ... $OK_TAG"
  fi

  # ----------------------------------------------------------------------------
  # Einstellungen des Benutzers zu weiterem Skript-Ablauf wieder herstellen
  # ----------------------------------------------------------------------------
  OPTION_FLAG[external]=$PRESERVED_EXTERNAL_FLAG
  OPTION_FLAG[force]=$PRESERVED_FORCE_FLAG
  OPTION_FLAG[quiet]=$PRESERVED_QUIET_FLAG
  OPTION_FLAG[status]=$PRESERVED_STATUS_FLAG
  # ----------------------------------------------------------------------------
fi # Ende Update aus externen Programmen [exupdate]

#===============================================================================
# Hauptschleife zur Installation oder Anzeige (wenn Pakete ausgewählt wurden)
#===============================================================================
ALL_STARTER_COUNTER=0
if [ $TOTAL_PACKS -gt 0 ] ||
   [ $USE_ILIST_FILE -eq 1 ];
then

  # ----------------------------------------------------------------------------
  # Bei Auswahl eines einzelnen individuellen Pakets nur dieses verarbeiten
  # ----------------------------------------------------------------------------
  if [ "$INST_ONLY_PKG" != "" ];
  then
    #---------------------------
    # Passende Kategorie suchen
    #---------------------------
    pkg_found=0
    for k in ${KAT_ORD_LIST[@]};
    do
      if [ "$k" != "xlinex" ];
      then
        TMP_LIST="${KATEGORIE_PKGS[$k]}"
        for p in ${TMP_LIST[@]};
        do
          if [ "$p" == "$INST_ONLY_PKG" ];
          then
            # ---------------------------------------------------------------
            # Wenn das Paket einer Kategorie zugeordnet ist, diese verwenden
            # ---------------------------------------------------------------
            KATEGORIE_TEXT[individual]="${KATEGORIE_TEXT[$k]}"
            pkg_found=1
            break
          fi
        done
      fi
    done
    # --------------------------------------------------------
    # Wenn das Paket keiner Kategorie zugeordnet ist, dann
    # eine zusätzliche Kategorie nur mit diesem Paket anlegen
    # --------------------------------------------------------
    if [ $pkg_found -eq 0 ];
    then
      KATEGORIE_TEXT[individual]="Individuelle Installation"
    fi
    KAT_ORD_LIST="individual"
    KATEGORIE_FLAG[individual]=1
    KATEGORIE_PKGS[individual]="$INST_ONLY_PKG"
  fi

  #-----------------------------------------------------------------------------
  # Bei Angabe einer Datei als individuelle Paket-Liste diese einlesen
  #-----------------------------------------------------------------------------
  LIST_PACKS=0
  if [ "$INST_ONLY_PKG" == "" ] &&
     [ $USE_ILIST_FILE -eq 1 ];
  then
    KATEGORIE_PKGS[individual]=""
    while read the_pkg_name;
    do
      # Hinweis: In regulärem Ausdruck für sed die Leerzeichen NICHT ans Ende und
      # - (minus) IMMER ans Ende setzen, da sed diese sonst falsch interpretiert!
      the_pkg_name=$(echo "${the_pkg_name}" | tr A-Z a-z | sed -E "s/[^a-z0-9 \.\_\-]//gi" | sed -E "s/ /\_/g" | xargs)
      if [ "$the_pkg_name" != "" ];
      then
        KATEGORIE_PKGS[individual]+=" $the_pkg_name"
        ((LIST_PACKS+=1));
      fi
    done < "$INST_LIST_FILE"
    KAT_ORD_LIST="individual"
    KATEGORIE_FLAG[individual]=1
    KATEGORIE_TEXT[individual]="Individuelle Installation"
  fi

  # ----------------------------------------------------------------------------
  # Start-Hinweise ausgeben
  # ----------------------------------------------------------------------------
  if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
     [ ${OPTION_FLAG[status]} -eq 0 ];
  then
    ACTION_TXT="Starte Installation"
  else
    if [ ${OPTION_FLAG[listonly]} -eq 1 ];
    then
      ACTION_TXT="Liste der Paketnamen"
    else
      ACTION_TXT="Anzeige des Status"
    fi
  fi

  ANZ_PACKS_TO_SHOW=$((TOTAL_PACKS+LIST_PACKS))
  START_MSG="$FULL_LINE"
  START_MSG+=$'\n'
  START_MSG+=" ${bold_blue}$ACTION_TXT von ${bold_white}$ANZ_PACKS_TO_SHOW${colors_off}${bold_blue} ausgewählten Programmpaketen${colors_off}"
  # START_MSG+=$'\n'
  if [ ${OPTION_FLAG[listonly]} -eq 1 ];
  then
    START_MSG+=$'\n'" ${bold_blue}Hinweise:${colors_off}  ${light_magenta}(Externe Paketquelle)${colors_off}  ${light_yellow}[Alternative Programmpakete]${colors_off}" # $'\n'
  fi
  # START_MSG+="$FULL_LINE"
  # START_MSG+=$'\n'
  e_and_l "$START_MSG"

  # ----------------------------------------------------------------------------
  # Ausgewählte Pakete anzeigen (nicht installieren)
  # ----------------------------------------------------------------------------
  if [ ${OPTION_FLAG[listonly]} -eq 1 ];
  then
    for k in ${KAT_ORD_LIST[@]};
    do
      if [ "$k" != "xlinex" ] &&
         [ ${KATEGORIE_FLAG[$k]} -eq 1 ];
      then
        e_and_l "$FULL_LINE"
        # ------------------------------------
        # Paket-Liste der Kategorie erstellen
        # ------------------------------------
        CAT_PKG_LIST=()
        CURRENT_CATEGORY=""
        KAT_SHORT_NAME=""
        create_cat_pkg_list
        e_and_l " ${bold_blue}$KAT_SHORT_NAME${colors_off} ${dark_gray}[+$k]${colors_off}"
        e_and_l "$FULL_LINE"
        # --------------------------------------------
        # Alle Pakete innerhalb der Liste durchlaufen
        # --------------------------------------------
        for pkg in ${CAT_PKG_LIST[@]};
        do
          check_skip_raspi $pkg
          SKIP_RESULT=$?
          if [ $SKIP_RESULT -eq 1 ]; then e_and_l -n "${bold_black}"; fi
          LIST_TXT=" $pkg"
          if [ $SKIP_RESULT -eq 1 ];
          then
            LIST_TXT+=" ($NA_TXT)${colors_off}"
          else
            # ------------------------------------
            # Hinweis auf alternative Paketquelle
            # ------------------------------------
            PACKAGE_TYPE=""
            get_package_type $pkg
            if [ "$PACKAGE_TYPE" != "STD" ];
            then
              if [ "$PACKAGE_TYPE" == "NONE" ];
              then
                LIST_TXT+=" ${light_red}(Quellangaben unvollständig)${colors_off}"
              else
                LIST_TXT+=" ${light_magenta}($PACKAGE_TYPE)${colors_off}"
              fi
            fi
            # ---------------------------------------
            # Hinweis auf alternative Programmpakete
            # ---------------------------------------
            if [ ${OPTION_FLAG[skipsims]} -eq 0 ];
            then
              SIMILAR_SEEN_LIST=("$pkg")
              SIMILAR_ALREADY_SEEN=0
              CHECK_SIM_PACK="${SIMILAR_PACK[$pkg]}"
              while [ "$CHECK_SIM_PACK" != "" ] &&
                    [ $SIMILAR_ALREADY_SEEN -eq 0 ];
              do
                for seen in ${SIMILAR_SEEN_LIST[@]};
                do
                  if [ "$seen" != "" ] &&
                     [ "$CHECK_SIM_PACK" == "$seen" ];
                  then
                    SIMILAR_ALREADY_SEEN=1
                    break
                  fi
                done
                if [ $SIMILAR_ALREADY_SEEN -eq 0 ];
                then
                  LIST_TXT+=" ${light_yellow}[$CHECK_SIM_PACK]${colors_off}"
                fi
                SIMILAR_SEEN_LIST+=($CHECK_SIM_PACK)
                CHECK_SIM_PACK="${SIMILAR_PACK[$CHECK_SIM_PACK]}"
              done
            fi
          fi
          e_and_l "$LIST_TXT"
        done # Ende der Pakete in einer Kategorie
      fi # Ende != "xlinex"
    done # Ende der Kategorien
  fi # Ende ausgewählte Pakete anzeigen

  # ----------------------------------------------------------------------------
  # Ausgewählte Pakete installieren
  # ----------------------------------------------------------------------------
  if [ ${OPTION_FLAG[listonly]} -eq 0 ];
  then

    e_and_l "$FULL_LINE"

    # ------------------------------------------------------------------
    # Abfrage vor der Erstellung sehr vieler Starter auf GNOME-Desktops
    # ------------------------------------------------------------------
    if [ ${OPTION_FLAG[addstart]} -ne 0 ] &&
       [ $ANZ_PACKS_TO_SHOW -gt 5 ] &&
       [ "$DESKTOP_ENVIRONMENT" == "GNOME" ];
    then
      e_and_l " $WARN_TAG: Für alle ausgewählten u. installierte Pakete werden Starter erstellt."
      ask_yes_or_no_plus "many_starter" " Wirklich so viele Starter direkt auf dem Desktop erstellen" "" "n"
      OPTION_FLAG[addstart]=$?
      e_and_l "$FULL_LINE"
    fi
    # ------------------------------------------------------------------

    NEW_STARTER_COUNTER=0
    for k in ${KAT_ORD_LIST[@]};
    do
      if [ "$k" != "xlinex" ] &&
         [ ${KATEGORIE_FLAG[$k]} -eq 1 ];
      then
        # ------------------------------------
        # Paket-Liste der Kategorie erstellen
        # ------------------------------------
        CAT_PKG_LIST=()
        CURRENT_CATEGORY=""
        KAT_SHORT_NAME=""
        create_cat_pkg_list
        e_and_l " ${bold_blue}$KAT_SHORT_NAME${colors_off} ${dark_gray}[+$k]${colors_off}"
        # --------------------------------------------
        # Alle Pakete innerhalb der Liste durchlaufen
        # --------------------------------------------
        pkg_in_category=0
        for pkg in ${CAT_PKG_LIST[@]};
        do
          LAST_ERW_PACK=""
          LAST_PPA_PACK=""
          PACKS_SEEN_LIST=("$pkg")
          install_pkg $pkg 0 0 0
          ((pkg_in_category+=1))
        done
        e_and_l "$FULL_LINE"
      fi # Ende != "xlinex"
    done # Ende der Kategorien
    ((ALL_STARTER_COUNTER+=NEW_STARTER_COUNTER))
  fi # Ausgewählte Pakete installieren

fi # Ende Hauptschleife zur Installation/Anzeige (wenn Pakete ausgewählt wurden)

#===============================================================================
# Zusätzliche Starter erstellen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[addstart]} -eq 1 ];
then

  if [ $TOTAL_PACKS -eq 0 ] &&
     [ $USE_ILIST_FILE -eq 0 ];
  then
    e_and_l "$FULL_LINE"
  fi
  e_and_l -n " ${bold_blue}Erstellung zusätzlicher Starter (Programm-Symbole)${colors_off}"
  if [ ${OPTION_FLAG[addstart]} -eq 1 ]; then e_and_l -n " ${dark_gray}[addstart]${colors_off}"; fi
  e_and_l ""
  e_and_l "$FULL_LINE"

  if [ ${OPTION_FLAG[addstart]} -eq 1 ];
  then

    # --------------------------------------------------------------------------
    # Starter der einzelnen Kategorien (wenn ausgewählt)
    # --------------------------------------------------------------------------
    if [ $ALL_STARTER_COUNTER -gt 0 ];
    then
      e_and_l " Bisher bereits neu erstellte Starter: ${bold_yellow}$ALL_STARTER_COUNTER${colors_off}"
      e_and_l "$HALF_LINE"
    fi
    e_and_l " ${bold_blue}Kategorien${colors_off}"
    e_and_l "$HALF_LINE"
    NEW_STARTER_COUNTER=0
    for katidx in "${!ADDITIONAL_STARTER[@]}";
    do
      if [ ${KATEGORIE_FLAG[$katidx]} -eq 1 ];
      then
        KAT_SHORT_NAME="${KATEGORIE_TEXT[$katidx]}"
        ADD_STARTER_LIST=(${ADDITIONAL_STARTER[$katidx]})
        e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}${KAT_SHORT_NAME%% (*}${colors_off}, bitte warten ... "
        for starter_name in "${ADD_STARTER_LIST[@]}";
        do
          copy_starter_to_desktop "$starter_name" "" 1
        done
        e_and_l "$OK_TAG"
        ((ALL_STARTER_COUNTER+=NEW_STARTER_COUNTER))
      fi
    done
    e_and_l " - Es wurden ${bold_green}$NEW_STARTER_COUNTER${colors_off} neue Starter erstellt"
    e_and_l "$HALF_LINE"

    # ----------------------------------------------------------------------------
    # Cinnamon Tools Starter (wenn ausgewählt)
    # ----------------------------------------------------------------------------
    if [ ${KATEGORIE_FLAG[ci]} -eq 1 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}Cinnamon Tools${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}Cinnamon-Desktop${colors_off}, bitte warten ... "
      # KAT_SHORT_NAME="Cinnamon Tools"
      KAT_SHORT_NAME="${KATEGORIE_TEXT[ci]}"
      SEARCH_RESULT_STANDARD=$(find /usr/share/applications -type f -iname "*.desktop" -print | grep -i -E "cinnamon\-.*\.desktop$")
      SEARCH_RESULT_SNAP=""
      if [ -d "/var/lib/snapd/desktop/applications" ];
      then
        SEARCH_RESULT_SNAP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -print | grep -i -E "cinnamon\-.*\.desktop$")
      fi
      SEARCH_RESULT_FLATPAK=""
      if [ -d "/var/lib/flatpak/app" ];
      then
        SEARCH_RESULT_FLATPAK=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -print | grep -i -E "\/export" | grep -i -E "cinnamon\-.*\.desktop$")
      fi
      SEARCH_STARTER_RESULT="${SEARCH_RESULT_STANDARD[@]} ${SEARCH_RESULT_SNAP[@]} ${SEARCH_RESULT_FLATPAK[@]}"
      EXCLUDE_STARTER_LIST=""
      copy_starter_list
      e_and_l "$HALF_LINE"
    fi

    # --------------------------------------------------------------------------
    # GNOME Apps Starter
    # --------------------------------------------------------------------------
    if [ ${KATEGORIE_FLAG[gx]} -eq 1 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}GNOME Apps${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}GNOME-Desktop${colors_off}, bitte warten ... "
      KAT_SHORT_NAME="${KATEGORIE_TEXT[gx]}"
      SEARCH_RESULT_STANDARD=$(find /usr/share/applications -type f -iname "*.desktop" -print | grep -i -E "gnome.*\.desktop$")
      SEARCH_RESULT_SNAP=""
      if [ -d "/var/lib/snapd/desktop/applications" ];
      then
        SEARCH_RESULT_SNAP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -print | grep -i -E "gnome.*\.desktop$")
      fi
      SEARCH_RESULT_FLATPAK=""
      if [ -d "/var/lib/flatpak/app" ];
      then
        SEARCH_RESULT_FLATPAK=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -print | grep -i -E "\/export" | grep -i -E "gnome.*\.desktop$")
      fi
      SEARCH_STARTER_RESULT="${SEARCH_RESULT_STANDARD[@]} ${SEARCH_RESULT_SNAP[@]} ${SEARCH_RESULT_FLATPAK[@]}"
      # -----------------------------------------
      # Spiele (und vielleicht später mal Pakete
      # aus anderen Kategorien) auslassen
      # -----------------------------------------
      EXCLUDE_STARTER_LIST="${PKG_STARTER_LIST[gnome-games]} org.gnome.atomix org.gnome.gbrainy gnome-mastermind"
      copy_starter_list
      e_and_l "$HALF_LINE"
    fi

    # --------------------------------------------------------------------------
    # LXDE Tools Starter
    # --------------------------------------------------------------------------
    if [ ${KATEGORIE_FLAG[lx]} -eq 1 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}LXDE Tools${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}LXDE-Desktop${colors_off}, bitte warten ... "
      KAT_SHORT_NAME="${KATEGORIE_TEXT[lx]}"
      SEARCH_RESULT_STANDARD=$(find /usr/share/applications -type f -iname "*.desktop" -print | grep -i -E "^lx.*\.desktop$")
      SEARCH_RESULT_SNAP=""
      if [ -d "/var/lib/snapd/desktop/applications" ];
      then
        SEARCH_RESULT_SNAP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -print | grep -i -E "^lx.*\.desktop$")
      fi
      SEARCH_RESULT_FLATPAK=""
      if [ -d "/var/lib/flatpak/app" ];
      then
        SEARCH_RESULT_FLATPAK=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -print | grep -i -E "\/export" | grep -i -E "^lx.*\.desktop$")
      fi
      SEARCH_STARTER_RESULT="${SEARCH_RESULT_STANDARD[@]} ${SEARCH_RESULT_SNAP[@]} ${SEARCH_RESULT_FLATPAK[@]}"
      EXCLUDE_STARTER_LIST=""
      copy_starter_list
      e_and_l "$HALF_LINE"
    fi

    # --------------------------------------------------------------------------
    # MATE Tools Starter
    # --------------------------------------------------------------------------
    if [ ${KATEGORIE_FLAG[mx]} -eq 1 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}MATE Tools${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}MATE-Desktop${colors_off}, bitte warten ... "
      KAT_SHORT_NAME="${KATEGORIE_TEXT[mx]}"
      SEARCH_RESULT_STANDARD=$(find /usr/share/applications -type f -iname "*.desktop" -print | grep -i -E "mate\-.*\.desktop$")
      SEARCH_RESULT_SNAP=""
      if [ -d "/var/lib/snapd/desktop/applications" ];
      then
        SEARCH_RESULT_SNAP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -print | grep -i -E "mate\-.*\.desktop$")
      fi
      SEARCH_RESULT_FLATPAK=""
      if [ -d "/var/lib/flatpak/app" ];
      then
        SEARCH_RESULT_FLATPAK=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -print | grep -i -E "\/export" | grep -i -E "mate\-.*\.desktop$")
      fi
      SEARCH_STARTER_RESULT="${SEARCH_RESULT_STANDARD[@]} ${SEARCH_RESULT_SNAP[@]} ${SEARCH_RESULT_FLATPAK[@]}"
      copy_starter_to_desktop "matecc" "" 0 # Control-Center / Steuerzentrale separat ("-" fehlt im Namen)
      EXCLUDE_STARTER_LIST=""
      copy_starter_list
      e_and_l "$HALF_LINE"
    fi

    # --------------------------------------------------------------------------
    # XFCE Tools Starter
    # --------------------------------------------------------------------------
    if [ ${KATEGORIE_FLAG[xf]} -eq 1 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}XFCE Tools${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}XFCE-Desktop${colors_off}, bitte warten ... "
      KAT_SHORT_NAME="${KATEGORIE_TEXT[xf]}"
      SEARCH_RESULT_STANDARD=$(find /usr/share/applications -type f -iname "*.desktop" -print | grep -i -E "^xfce.*\.desktop$")
      SEARCH_RESULT_SNAP=""
      if [ -d "/var/lib/snapd/desktop/applications" ];
      then
        SEARCH_RESULT_SNAP=$(find /var/lib/snapd/desktop/applications -type f -iname "*.desktop" -print | grep -i -E "^xfce.*\.desktop$")
      fi
      SEARCH_RESULT_FLATPAK=""
      if [ -d "/var/lib/flatpak/app" ];
      then
        SEARCH_RESULT_FLATPAK=$(find /var/lib/flatpak/app -type f -iname "*.desktop" -print | grep -i -E "\/export" | grep -i -E "^xfce.*\.desktop$")
      fi
      SEARCH_STARTER_RESULT="${SEARCH_RESULT_STANDARD[@]} ${SEARCH_RESULT_SNAP[@]} ${SEARCH_RESULT_FLATPAK[@]}"
      EXCLUDE_STARTER_LIST=""
      copy_starter_list
      e_and_l "$HALF_LINE"
    fi

    # ----------------------------------------------------------------------------
    # Raspberry Pi OS Tools - Starter (automatisch)
    # ----------------------------------------------------------------------------
    if [ $IS_PIOS -gt 0 ];
    then
      NEW_STARTER_COUNTER=0
      e_and_l " ${bold_blue}Pi OS Tools${colors_off}"
      e_and_l "$HALF_LINE"
      e_and_l -n " Erstelle zusätzliche Starter für ${bold_white}Pi-OS-Desktop${colors_off}, bitte warten ... "
      KAT_SHORT_NAME="Pi OS Tools"
      for desktop_starter in "${PIOS_EXT_STARTER[@]}";
      do
        copy_starter_to_desktop "$desktop_starter" "" 0
      done
      e_and_l "$OK_TAG"
      e_and_l " - Es wurden ${bold_green}$NEW_STARTER_COUNTER${colors_off} neue Starter erstellt"
      e_and_l "$HALF_LINE"
      ((ALL_STARTER_COUNTER+=NEW_STARTER_COUNTER))
    fi

  fi

  # ----------------------------------------------------------------------------
  # Starter bereinigen
  # ----------------------------------------------------------------------------
  e_and_l " ${bold_blue}Optimierung${colors_off}"
  e_and_l "$HALF_LINE"
  e_and_l -n " Bereinige und reorganisiere Starter auf dem Desktop, bitte warten ... "
  NEW_STARTER_COUNTER=0
  STARTER_DELETED=0
  DIRS_DELETED=0
  STARTER_MOVED=0
  if [ -d "$DESKTOP_STARTER_DIR" ];
  then
    # ---------------------------------------------------------------------
    # Spezifische Starter der Desktops für die Systemverwaltung in jeweils
    # seperate Unterordner verschieben (nicht auf GNOME-Desktop)
    # ---------------------------------------------------------------------
    if [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
    then
      if [ ${KATEGORIE_FLAG[v]} -eq 1 ]  ||
         [ ${KATEGORIE_FLAG[gx]} -eq 1 ] ||
         [ ${KATEGORIE_FLAG[lx]} -eq 1 ] ||
         [ ${KATEGORIE_FLAG[mx]} -eq 1 ] ||
         [ ${KATEGORIE_FLAG[mt]} -eq 1 ] ||
         [ ${KATEGORIE_FLAG[xf]} -eq 1 ] ||
         [ ${KATEGORIE_FLAG[ci]} -eq 1 ];
      then
        # ----------------------------------------------------------
        # Ordner Systemverwaltung anlegen wenn noch nicht vorhanden
        # ----------------------------------------------------------
        SYS_V_DIR="$DESKTOP_STARTER_DIR/${KATEGORIE_TEXT[v]%% (*}"
        if [ ! -d "$SYS_V_DIR" ];
        then
          mkdir -p "$SYS_V_DIR" &>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$SYS_V_DIR" &>/dev/null
            chmod -R 0755 "$SYS_V_DIR" &>/dev/null
          fi
        fi
        if [ -d "$SYS_V_DIR" ];
        then
          # ------------------
          # Für jeden Desktop
          # ------------------
          for asn in "${!ADDITIONAL_S_NAMES[@]}";
          do
            DESKTOP_STARTER_DIR_NAME="${ADDITIONAL_DIRNAME[$asn]}"
            DESKTOP_SYS_STARTER_LIST=(${ADDITIONAL_S_NAMES[$asn]})
            if [ ${#DESKTOP_SYS_STARTER_LIST} -gt 0 ];
            then
              V_STARTER_TARGET_DIR="$SYS_V_DIR/$DESKTOP_STARTER_DIR_NAME"
              # -----------------------------------------
              # Desktop-spezifischen Unterordner anlegen
              # -----------------------------------------
              if [ ! -d "$V_STARTER_TARGET_DIR" ];
              then
                mkdir -p "$V_STARTER_TARGET_DIR" &>/dev/null
                if [ $? -eq 0 ];
                then
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$V_STARTER_TARGET_DIR" &>/dev/null
                  chmod -R 0755 "$V_STARTER_TARGET_DIR" &>/dev/null
                fi
              fi
              # --------------------------------
              # Alle Starter der Liste kopieren
              # --------------------------------
              if [ -d "$V_STARTER_TARGET_DIR" ];
              then
                for starter_name in ${DESKTOP_SYS_STARTER_LIST[@]};
                do
                  if [ "$starter_name" != "" ];
                  then
                    # ------------------------------------------
                    # Wenn es den Starter schon im Haupt-Ordner
                    # der Systemverwaltung gibt ...
                    # ------------------------------------------
                    if [ -s "$SYS_V_DIR/$starter_name.desktop" ];
                    then
                      # ---------------------------------------------------
                      # ... und es diesen auch schon im Ziel-Ordner gibt,
                      # dann den doppelten im Haupt-Ordner wieder löschen
                      # ---------------------------------------------------
                      if [ -s "$V_STARTER_TARGET_DIR/$starter_name.desktop" ];
                      then
                        remove_file "$SYS_V_DIR/$starter_name.desktop"
                        ((STARTER_DELETED+=1))
                        ((ALL_STARTER_COUNTER-=1))
                      # -------------------------------------------------
                      # ... sonst, wenn es den Starter im Ziel-Ordner
                      # noch nicht gibt, den Starter dorthin verschieben
                      # -------------------------------------------------
                      else
                        mv -f "$SYS_V_DIR/$starter_name.desktop" "$V_STARTER_TARGET_DIR/$starter_name.desktop" &>/dev/null
                        if [ $? -eq 0 ];
                        then
                          make_starter_trusted "$V_STARTER_TARGET_DIR/$starter_name.desktop"
                          ((STARTER_MOVED+=1))
                        fi
                      fi
                    # ----------------------------------------
                    # ... sonst Starter suchen und direkt in
                    # den entsprechenden Unterordner kopieren
                    # ----------------------------------------
                    else
                      copy_starter_to_desktop "$starter_name" "$V_STARTER_TARGET_DIR" 1
                    fi
                  fi
                done
              fi
            fi
          done
        fi
      fi
    fi
    ((ALL_STARTER_COUNTER+=NEW_STARTER_COUNTER))

    # -------------------------------------
    # Falsch zugeordnete Starter entfernen
    # -------------------------------------
    for desktop_starter in "${WRONG_STARTER[@]}";
    do
      THE_WRONG_FILE="$DESKTOP_STARTER_DIR/$desktop_starter.desktop"
      if [ -s "$THE_WRONG_FILE" ];
      then
        remove_file "$THE_WRONG_FILE" &>/dev/null
        ((STARTER_DELETED+=1))
        ((ALL_STARTER_COUNTER-=1))
      fi
    done

    # ----------------------------------------------------------------------
    # Zur Sicherheit auch eventuell früher falsch angelegte Starter löschen
    # ----------------------------------------------------------------------
    for desktop_starter in "${REJECT_STARTER[@]}";
    do
      REJECTED_STARTER_FOUND=$(find "$DESKTOP_STARTER_DIR" -type f -iname "$desktop_starter.desktop" | wc -l)
      if [ $REJECTED_STARTER_FOUND -ne 0 ];
      then
        find "$DESKTOP_STARTER_DIR" -type f -iname "$desktop_starter.desktop" -delete &>"$LOG_TEMP"
        ((STARTER_DELETED+=1))
        ((ALL_STARTER_COUNTER-=1))
      fi
    done

    # ------------------------------------------------
    # Mehrfach gefundene Starter (für KDE) bereinigen
    # ------------------------------------------------
    while read the_kde_starter;
    do
      the_std_starter="${the_kde_starter/-kde.desktop/.desktop}"
      # Wenn zwei Starter existieren, dann den überflüssigen "falschen" löschen
      if [ "$the_std_starter" != "$the_kde_starter" ] &&
         [ -s "$the_std_starter" ] &&
         [ -s "$the_kde_starter" ];
      then
        if [ "$DESKTOP_ENVIRONMENT" != "KDE" ];
        then
          remove_file "$the_kde_starter" &>/dev/null
        else
          remove_file "$the_std_starter" &>/dev/null
        fi
        ((STARTER_DELETED+=1))
        ((ALL_STARTER_COUNTER-=1))
      fi
    done <<< $(find "$DESKTOP_STARTER_DIR" -type f -iname "*-kde".desktop -print)

    # -----------------------
    # Leere Ordner entfernen
    # -----------------------
    while read dir_entry;
    do
      if [ $(ls -A "$dir_entry" | wc -w) -eq 0 ];
      then
        rmdir "$dir_entry" &>/dev/null
        if [ $? -eq 0 ]; then ((DIRS_DELETED+=1)); fi
      fi
    done <<< $(find "$DESKTOP_STARTER_DIR" -type d -print)

  fi
  e_and_l "$OK_TAG"
  if [ $NEW_STARTER_COUNTER -gt 0 ];
  then
    e_and_l " - Es wurden ${bold_green}$NEW_STARTER_COUNTER${colors_off} weitere Starter erstellt"
  fi
  if [ $STARTER_MOVED -gt 0 ];
  then
    e_and_l " - Es wurden ${bold_yellow}$STARTER_MOVED${colors_off} bestehende Starter verschoben"
  fi
  if [ $STARTER_DELETED -gt 0 ];
  then
    e_and_l " - Es wurden ${bold_red}$STARTER_DELETED${colors_off} unpassende Starter entfernt"
  fi
  if [ $DIRS_DELETED -gt 0 ];
  then
    e_and_l " - Es wurden ${bold_white}$DIRS_DELETED${colors_off} leere Ordner entfernt"
  fi
fi # Ende Zusätzliche Starter erstellen

#===============================================================================
# Zusammenfassung anzeigen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then

  if [ $TOTAL_PACKS -gt 0 ] ||
     [ $USE_ILIST_FILE -eq 1 ];
  then

    SUMMARY_TEXT=""
    SUMMARY_TEXT+="$FULL_LINE"$'\n'
    SUMMARY_TEXT+=" ${bold_blue}Zusammenfassung der Paket-Verarbeitung${colors_off}"$'\n'
    SUMMARY_TEXT+="$FULL_LINE"$'\n'

    # -------
    # Zähler
    # -------
    if [ ${OPTION_FLAG[status]} -eq 0 ];
    then
      INST_MSG="Neu"
      INST_SPACE="    "
    else
      INST_MSG="Nicht"
      INST_SPACE="  "
    fi
    SUMMARY_TEXT+=" Bereits installierte Pakete: ${bold_green}$PAKETS_EXIST${colors_off}"
    if [ $PAKETS_SIMILAR_EXIST -ne 0 ];
    then
      SUMMARY_TEXT+=" (davon Alternativ-Pakete: ${bold_green}$PAKETS_SIMILAR_EXIST${colors_off})"
    fi
    SUMMARY_TEXT+=$'\n'

    SUMMARY_TEXT+=" $INST_MSG installierte Pakete:$INST_SPACE ${bold_yellow}$PAKETS_AVAIL${colors_off}"
    if [ $PAKETS_SIMILAR_AVAIL -ne 0 ];
    then
      SUMMARY_TEXT+=" (davon Alternativ-Pakete: ${bold_yellow}$PAKETS_SIMILAR_AVAIL${colors_off})"
    fi
    SUMMARY_TEXT+=$'\n'

    SUMMARY_TEXT+=" Übersprungene Pakete:        ${bold_cyan}$PAKETS_SKIP${colors_off}"$'\n'

    SUMMARY_TEXT+=" Nicht verfügbare Pakete:     ${bold_red}$PAKETS_NOAVAIL${colors_off}"
    if [ $PAKETS_SIMILAR_NOAVA -ne 0 ];
    then
      SUMMARY_TEXT+=" (davon Alternativ-Pakete: ${bold_red}$PAKETS_SIMILAR_NOAVA${colors_off})"
    fi

    if [ $ALL_STARTER_COUNTER -gt 0 ];
    then
      SUMMARY_TEXT+=$'\n'" Auf dem Desktop insgesamt neu erstellte Starter: ${bold_green}$ALL_STARTER_COUNTER${colors_off}"
    fi

    e_and_l "$SUMMARY_TEXT"

  fi
fi # Ende Zusammenfassung

#===============================================================================
# Installation einer grafischen Benutzeroberfläche (Desktop)
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  if [ ${OPTION_FLAG[desktop]} -eq 1 ];
  then
    e_and_l "$FULL_LINE"
    e_and_l " ${bold_blue}Grafische Benutzeroberfläche (Desktop)${colors_off}"
    e_and_l "$FULL_LINE"
    # --------------------------------------------------------------------------
    # Desktop(s) installieren
    # --------------------------------------------------------------------------
    if [ $TASKSEL_AVAILABLE -gt 0 ] ||
       [[ "$DESKTOP_ENVIRONMENT" != "MATE" && $MATE_DESKTOP_AVAILABLE -gt 0 ]];
    then
      INSTALL_DESKTOP_ANSWER=0
      if [ $TASKSEL_AVAILABLE -gt 0 ];
      then
        NEW_DESKTOP_TEXT=""
        if [ "$DESKTOP_ENVIRONMENT" != "" ];
        then
          e_and_l " Der ${bold_green}$DESKTOP_ENVIRONMENT${colors_off}-Desktop scheint bereits in Verwendung zu sein."
          NEW_DESKTOP_TEXT=" weiteren"
        fi
        ask_yes_or_no_plus "install_desktop" " Jetzt einen${bold_yellow}$NEW_DESKTOP_TEXT Desktop${colors_off} auswählen und installieren" "" "n"
        INSTALL_DESKTOP_ANSWER=$?
        if [ $INSTALL_DESKTOP_ANSWER -eq 1 ];
        then
          DO_THE_TASKSEL=1
          if [ $(LANG=C dpkg-query -W -f='${Status}' "tasksel" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
          then
            e_and_l -n " Installiere tasksel ... "
            apt install "tasksel" -y &>/dev/null
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              DO_THE_TASKSEL=0
            fi
          fi
          if [ $DO_THE_TASKSEL -gt 0 ];
          then
            do_log " Rufe tasksel auf ..."
            tasksel
          fi
        fi
      else
        ask_yes_or_no_plus "install_mate" " Soll jetzt der ${bold_yellow}MATE-Desktop${colors_off} installiert werden" "" "n"
        INSTALL_DESKTOP_ANSWER=$?
        if [ $INSTALL_DESKTOP_ANSWER -eq 1 ];
        then
          if [ $(LANG=C dpkg-query -W -f='${Status}' "lightdm" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
          then
            e_and_l " Installiere Display-Manager ${bold_yellow}lightdm${colors_off} ..."
            apt install "lightdm" -y &>/dev/null
          fi
          if [ $(LANG=C dpkg-query -W -f='${Status}' "mate-desktop-environment" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
          then
            e_and_l " Installiere das ${bold_yellow}MATE-Desktop-Environment${colors_off} ..."
            apt install "mate-desktop-environment" -y &>/dev/null
          fi
        fi
      fi
      if [ $INSTALL_DESKTOP_ANSWER -eq 1 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        e_and_l " $HINWEIS_TAG: Weitere Optionen zum Desktop sind erst nach einem Neustart verfügbar."
      fi
    else
      e_and_l " $HINWEIS_TAG: Es kann derzeit leider kein zusätzlicher Desktop installiert werden."
    fi
    # --------------------------------------------------------------------------
    # Anmeldung über Desktop (GUI) oder Kommandozeile (CLI) einstellen
    # --------------------------------------------------------------------------
    declare -A DEFAULT_TARGET_VALUE
    declare -A DEFAULT_TARGET_TEXT
    DEFAULT_TARGET_VALUE[0]="multi-user"
    DEFAULT_TARGET_VALUE[1]="graphical"
    DEFAULT_TARGET_TEXT[0]="Kommandozeile (CLI)"
    DEFAULT_TARGET_TEXT[1]="Desktop (GUI)"
    if [ $(systemctl get-default 2>/dev/null | grep -c -i -E "graphical") -gt 0 ];
    then
      OLD_TARGET_IDX=1
      NEW_TARGET_IDX=0
    else
      OLD_TARGET_IDX=0
      NEW_TARGET_IDX=1
    fi
    e_and_l "$HALF_MINUS_LINE"
    e_and_l " Die ${light_cyan}Anmeldung am System${colors_off} ist aktuell auf ${light_cyan}${DEFAULT_TARGET_TEXT[$OLD_TARGET_IDX]}${colors_off} eingestellt."
    ask_yes_or_no_plus "change_login_mode" " Die Anmeldung ab jetzt auf ${bold_yellow}${DEFAULT_TARGET_TEXT[$NEW_TARGET_IDX]}${colors_off} umstellen" "" "n"
    if [ $? -eq 1 ];
    then
      e_and_l -n " Stelle die Anmeldung am System auf ${bold_yellow}${DEFAULT_TARGET_TEXT[$NEW_TARGET_IDX]}${colors_off} um ... "
      # -------------------------------------------------------------
      # Bei Umstellung auf GUI zusätzlich gldriver-test installieren
      # -------------------------------------------------------------
      if [ $NEW_TARGET_IDX -eq 1 ];
      then
        if [ $(LANG=C dpkg-query -W -f='${Status}' "gldriver-test" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
        then
          if [ $(apt list "gldriver-test" 2>/dev/null | grep -i -c -E "gldriver-test") -gt 0 ];
          then
            apt install "gldriver-test" -y &>/dev/null
          fi
        fi
      fi
      # -------------------------------------------------------------
      systemctl set-default ${DEFAULT_TARGET_VALUE[$NEW_TARGET_IDX]} &>/dev/null
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
      fi
    fi
  fi
fi

#===============================================================================
# Installation zusätzlicher System-Komponenten (Treiber und Extras)
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then

  CHANGES_MADE=0

  if [ ${OPTION_FLAG[extras]} -eq 1 ];
  then

    e_and_l "$FULL_LINE"
    e_and_l " ${bold_blue}Zusätzliche System-Komponenten und Treiber ${colors_off} ${dark_gray}[extras]${colors_off}"
    e_and_l "$FULL_LINE"
    e_and_l " ${bold_blue}Firmware und Geräte-Treiber${colors_off}"
    e_and_l "$HALF_LINE"

    # ==========================================================================
    # Microcode für Intel-CPUs installieren
    # ==========================================================================
    ACTION_MESSAGE=" Installation des ${light_cyan}Microcode für Intel-CPUs${colors_off}  ..."
    if [ $(LANG=C lshw -short 2>/dev/null | grep -i processor | grep -c -i intel) -gt 0 ];
    then
      if [ $(LANG=C dpkg-query -W -f='${Status}' "intel-microcode" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
      then
        if [ $(apt list "intel-microcode" 2>/dev/null | grep -i -c -E "intel-microcode") -gt 0 ];
        then
          ask_yes_or_no_plus "intel-microcode" " ${bold_yellow}Microcode für Intel-CPUs${colors_off} installieren" "" "j"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere ${bold_yellow}Microcode für Intel-CPUs${colors_off}       ... "
            apt install intel-microcode -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
          fi
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE " "$NV_TXT")"
        fi
      else
        e_and_l "$ACTION_MESSAGE $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE " "$NV_TXT")"
    fi

    # ==========================================================================
    # Firmware für WiFi-Chipsatz installieren
    # ==========================================================================
    ACTION_MESSAGE=" Installation d. ${light_cyan}Firmware für WiFi-Chipsatz${colors_off} ..."
    if [ $(LANG=C lshw -short 2>/dev/null | grep -i network | grep -c -i wifi) -gt 0 ];
    then
      if [ $(LANG=C dpkg-query -W -f='${Status}' "firmware-iwlwifi" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
      then
        if [ $(apt list "firmware-iwlwifi" 2>/dev/null | grep -i -c -E "firmware-iwlwifi") -gt 0 ];
        then
          ask_yes_or_no_plus "firmware-iwlwifi" " ${bold_yellow}Firmware für WiFi-Chipsatz${colors_off} installieren" "" "j"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere ${bold_yellow}Firmware für WiFi-Chipsatz${colors_off}     ... "
            apt install firmware-iwlwifi -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
          fi
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
        fi
      else
        e_and_l "$ACTION_MESSAGE $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
    fi

    # ==========================================================================
    # D-Bus-Proxy für IIO-Sensoren installieren
    # ==========================================================================
    ACTION_MESSAGE=" Installation der ${light_cyan}Treiber für IIO-Sensoren${colors_off} "
    if [ $(LANG=C dpkg-query -W -f='${Status}' "iio-sensor-proxy" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
    then
      if [ $(apt list "iio-sensor-proxy" 2>/dev/null | grep -i -c -E "iio-sensor-proxy") -gt 0 ];
      then
        ask_yes_or_no_plus "iio-sensor-proxy" " ${bold_yellow}Treiber für IIO-Sensoren${colors_off} installieren" "" "j"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Installiere ${bold_yellow}D-Bus-Proxy für IIO-Sensoren${colors_off}   ... "
          apt install iio-sensor-proxy -y &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
          fi
          add_full_log
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
      fi
    else
      e_and_l "$ACTION_MESSAGE ... $NC_TAG"
    fi

    # ==========================================================================
    # Zusätzliche Ubuntu-Geräte-Treiber suchen und installieren
    # Wird ab Version 5.7.0 nicht mehr angeboten ...
    # ==========================================================================
    # ACTION_MESSAGE=" Zusätzliche ${light_cyan}Ubuntu-Geräte-Treiber${colors_off} suchen"
    # if [ $(apt list "ubuntu-drivers-common" 2>/dev/null | grep -i -c "ubuntu-drivers-common") -gt 0 ];
    # then
    #   ask_yes_or_no_plus "ubuntu-drivers" "$ACTION_MESSAGE" "" "j"
    #   if [ $? -eq 1 ];
    #   then
    #     e_and_l -n " Suche zusätzliche ${light_cyan}Geräte-Treiber${colors_off}, bitte warten ... "
    #     INSTALL_RESULT=0
    #     if [ $(LANG=C dpkg-query -W -f='${Status}' "ubuntu-drivers-common" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
    #     then
    #       apt install ubuntu-drivers-common -y &>"$LOG_TEMP"
    #       INSTALL_RESULT=$?
    #     fi
    #     if [ $INSTALL_RESULT -eq 0 ];
    #     then
    #       THE_TEMP_FILE="$DOWNLOAD_DIR/missing-driver-list" # Nur zur Anzeige der Liste
    #       MISSING_DRIVER_LIST=$(ubuntu-drivers list 2>/dev/null | grep -v "nvidia" | xargs 2>/dev/null)
    #       NVIDIA_DRIVER_LIST=$(ubuntu-drivers list 2>/dev/null | grep -i -E "nvidia" | xargs 2>/dev/null)
    #       if [ "$MISSING_DRIVER_LIST" != "" ];
    #       then
    #         e_and_l "${bold_green}ok, Treiber gefunden${colors_off}"
    #         echo -e "$MISSING_DRIVER_LIST" > "$THE_TEMP_FILE" 2>/dev/null
    #         e_and_l " $HINWEIS_TAG: Es wird empfohlen vorher eine Sicherung des System zu erstellen."
    #         ask_yes_or_no_plus "ubuntu-drivers" " Zusätzliche ${light_cyan}Geräte-Treiber${colors_off} installieren" "$THE_TEMP_FILE" "j"
    #         if [ $? -eq 1 ];
    #         then
    #           e_and_l " Installiere zusätzliche ${light_yellow}Geräte-Treiber${colors_off} ... "
    #           ubuntu-drivers install | tee "$LOG_TEMP"
    #           CHANGES_MADE=1
    #           add_full_log
    #           e_and_l ""
    #         fi
    #         remove_file "$THE_TEMP_FILE"
    #       else
    #         if [ "$NVIDIA_DRIVER_LIST" == "" ];
    #         then
    #           e_and_l "$NF_TAG"
    #         else
    #           e_and_l "$OK_TAG - siehe Hinweis"
    #         fi
    #       fi
    #       if [ "$NVIDIA_DRIVER_LIST" != "" ];
    #       then
    #         e_and_l " $HINWEIS_TAG: Es stehen ${light_yellow}NVIDIA-Treiber${colors_off} zur Verfügung. Um die Stabilität dieses"
    #         e_and_l " Systems nicht zu gefährden, wurden diese jedoch ${bold_white}nicht${colors_off} automatisch installiert."
    #       fi
    #     else
    #       e_and_l "$ERROR_TAG $LINENO"
    #     fi
    #   fi
    # else
    #   e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NU_TXT")"
    # fi

    e_and_l "$HALF_LINE"
    e_and_l " ${bold_blue}Weitere System-Komponenten${colors_off}"
    e_and_l "$HALF_LINE"

    # ==========================================================================
    # Einstellung der Sprachumgebung (des Systems) auf deutsch (oder andere)
    # ==========================================================================
    if [ "$CUR_SYS_LANG" != "de" ] &&
       [ "$CUR_SYS_LANG" != "de_DE" ];
    then
      e_and_l " Die Sprachumgebung des Systems ist nicht auf deutsch eingestellt."
      ask_yes_or_no_plus "cur_sys_lang" " Soll die ${light_cyan}Systemsprache${colors_off} geändert werden" "" "n"
      if [ $? -eq 1 ];
      then
        export LANG=de_DE.UTF-8
        dpkg-reconfigure locales
        if [ $? -eq 0 ];
        then
          e_and_l "$REBOOT_MSG"
        else
          e_and_l " $HINWEIS_TAG: Die Sprachumgebung wurde nicht geändert."
        fi
      fi
    else
      e_and_l " Einstellung der ${light_cyan}Sprachumgebung${colors_off} auf deutsch ... $NC_TAG"
    fi

    # ==========================================================================
    # Zusätzliche Sprachpakete (fehlende Sprachunterstützung) installieren
    # ==========================================================================
    ACTION_MESSAGE=" Zusätzliche ${light_cyan}Sprachpakete${colors_off} installieren"
    if [ $(LANG=C dpkg-query -W -f='${Status}' "language-selector-common" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
    then
      if [ $(apt list "language-selector-common" 2>/dev/null | grep -i -c "language-selector-common") -gt 0 ];
      then
        e_and_l -n " Installiere ${light_yellow}Sprachauswahl${colors_off} für Ubuntu       ... "
        apt install language-selector-common -y &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG $LINENO"
        fi
        add_full_log
      fi
    fi
    if check-language-support --help  &>/dev/null;
    then
      CHECK_LANGUAGES="${CUR_SYS_LANG:0:2} en"
      for lang_code in ${CHECK_LANGUAGES[@]};
      do
        ACTION_MESSAGE=" Zusätzliche ${light_cyan}Sprachpakete ($lang_code)${colors_off} installieren"
        MISSING_SUPPORT_LIST="$DOWNLOAD_DIR/missing_language_support_$lang_code.list"
        MISSING_LANGUAGE_SUPPORT=$(check-language-support -l ${lang_code} 2>/dev/null)
        if [ "$MISSING_LANGUAGE_SUPPORT" != "" ];
        then
          echo -e "$MISSING_LANGUAGE_SUPPORT" 2>/dev/null | tr ' ' '\n' | sed -E "s/^/ - /g" > "$MISSING_SUPPORT_LIST"
          ask_yes_or_no_plus "language-support" "$ACTION_MESSAGE" "$MISSING_SUPPORT_LIST" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere zusätzliche ${light_yellow}Sprachpakete ($lang_code)${colors_off}, bitte warten ... "
            apt install $(check-language-support -l ${lang_code}) -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG $LINENO"
            fi
            add_full_log
            e_and_l "$HALF_MINUS_LINE"
          fi
          remove_file "$MISSING_SUPPORT_LIST"
        else
          e_and_l "$ACTION_MESSAGE ... $KF_TAG"
        fi
      done
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE     " "$NA_TXT")"
    fi

    if [ $DESKTOP_INSTALLED -eq 0 ];
    then

      e_and_l "$HALF_MINUS_LINE"
      e_and_l "$NO_DESKTOP_INFO"
      e_and_l -n "${dark_gray}"
      e_and_l " - Schriftarten MegaFontPack"
      e_and_l " - Extra-Mauszeiger CursorPack"
      e_and_l " - Diverse Desktop-Themen"
      e_and_l " - Diverse Desktop-Tools"
      e_and_l " - Bildschirmschoner XScreenSaver"
      e_and_l -n "${colors_off}"
      e_and_l "$HALF_MINUS_LINE"

    else

      # ========================================================================
      # Schriftarten MegaFontPack oder ersatzweise MS Windows Fonts installieren
      # ========================================================================
      SYSTEM_FONT_DIR="/usr/share/fonts/truetype"
      MEGA_FONT_DIR="$SYSTEM_FONT_DIR/MegaFontPack"
      if [ ! -d "$MEGA_FONT_DIR" ];
      then
        ask_yes_or_no_plus "megafontpack" " Schriftarten ${light_cyan}MegaFontPack${colors_off} installieren" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Installiere ${light_yellow}MegaFontPack${colors_off}, bitte warten     "
          DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/MegaFontPack.7z"
          DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
          LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
          wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
          if [ $? -eq 0 ] &&
            [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
            [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
            7z x "$LOCAL_DOWNLOAD_FILE" -o"$SYSTEM_FONT_DIR/" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              chown -R "root:root" "$MEGA_FONT_DIR" &>/dev/null
              chmod -R 0644 "$MEGA_FONT_DIR/*" &>/dev/null
              fc-cache &>/dev/null
              dpkg-reconfigure fontconfig &>/dev/null
              remove_file "$LOCAL_DOWNLOAD_FILE"
              e_and_l "... $OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "... $ERROR_TAG $LINENO"
              add_full_log
            fi
          else
            e_and_l "... ${bold_red}nicht${colors_off} installiert"
            remove_file "$LOCAL_DOWNLOAD_FILE"
            add_full_log
          fi
          e_and_l "$HALF_MINUS_LINE"
        else
          ACTION_MESSAGE=" Schriftarten ${light_cyan}MS Windows Fonts${colors_off} installieren"
          if [ $(LANG=C dpkg-query -W -f='${Status}' "ttf-mscorefonts-installer" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
          then
            if [ $(apt list "ttf-mscorefonts-installer" 2>/dev/null | grep -i -c -E "ttf-mscorefonts-installer") -gt 0 ];
            then
              ask_yes_or_no_plus "ms_windows_fonts" "$ACTION_MESSAGE" "" "n"
              if [ $? -eq 1 ];
              then
                e_and_l " Installiere ${light_yellow}MS Windows Fonts${colors_off} ... "
                { apt install "ttf-mscorefonts-installer" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                INSTALL_RESULT=$(cat "$LAST_EXIT_CODE")
                if [ $INSTALL_RESULT -eq 0 ];
                then
                  CHANGES_MADE=1
                fi
                add_full_log
                remove_file "$LAST_EXIT_CODE"
                clear # Die Installation von ttf-mscorefonts hinterlässt leider keinen sauberen Terminal-Status!
                e_and_l "$HALF_MINUS_LINE"
              fi
            else
              e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
            fi
          else
            e_and_l "$ACTION_MESSAGE ... $NC_TAG"
          fi
        fi
      else
        e_and_l " Schriftartensatz ${light_cyan}MegaFontPack${colors_off} installieren ... $NC_TAG"
      fi

      # ========================================================================
      # Mauszeiger (CursorPack) installieren
      # ========================================================================
      ACTION_MESSAGE=" Extra-Mauszeiger ${light_cyan}CursorPack${colors_off} installieren"
      USER_ICON_DIR="$USER_HOME_DIR/.icons"
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ] &&
         [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
      then
        if [ ! -f "$USER_ICON_DIR/.CursorPack_ok" ];
        then
          ask_yes_or_no_plus "cursorpack" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere ${light_yellow}CursorPack${colors_off}, bitte warten       "
            DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/CursorPack.7z"
            DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
            LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
            wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
            if [ $? -eq 0 ] &&
              [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
              [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
              if [ ! -d "$USER_ICON_DIR" ];
              then
                mkdir -p "$USER_ICON_DIR" &>/dev/null
              fi
              if [ -d "$USER_ICON_DIR" ];
              then
                7z x "$LOCAL_DOWNLOAD_FILE" -o"$USER_ICON_DIR/" -y &>"$LOG_TEMP"
                if [ $? -eq 0 ];
                then
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_ICON_DIR" &>/dev/null
                  # chmod -R 0755 "$USER_ICON_DIR" &>/dev/null
                  remove_file "$LOCAL_DOWNLOAD_FILE"
                  e_and_l "... $OK_TAG"
                  CHANGES_MADE=1
                else
                  e_and_l "... $ERROR_TAG $LINENO"
                  add_full_log
                fi
              else
                e_and_l "... $ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l "... ${bold_red}nicht${colors_off} installiert"
              remove_file "$LOCAL_DOWNLOAD_FILE"
              add_full_log
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE   ... $NC_TAG"
        fi
      else
        if [ "$DESKTOP_ENVIRONMENT" == "GNOME" ];
        then
          e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NG_TXT")"
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NAPIOSDESK_TXT")"
        fi
      fi

      # ========================================================================
      # Themen Ambiant und Radiant installieren
      # ========================================================================
      ACTION_MESSAGE=" Desktop-Themen ${light_cyan}Amb- & Radiant${colors_off} installieren"
      if [ "$DESKTOP_ENVIRONMENT" == "MATE" ];
      then
        THEME_TARGET_HOME="/usr/share"
        declare -A THEME_DIR
        THEME_DIR[0]="icons/Ambiant-MATE"
        THEME_DIR[1]="icons/Radiant-MATE"
        THEME_DIR[2]="themes/Ambiant-MATE"
        THEME_DIR[3]="themes/Ambiant-MATE-Dark"
        THEME_DIR[4]="themes/Radiant-MATE"
        ANZ_THEMES=${#THEME_DIR[@]}
        DIRS_FOUND=0
        tnr=0
        while [ $tnr -lt $ANZ_THEMES ];
        do
          if [ -d "$THEME_TARGET_HOME/${THEME_DIR[$tnr]}" ];
          then
            ((DIRS_FOUND+=1))
          fi
          ((tnr+=1))
        done
        if [ $DIRS_FOUND -lt $ANZ_THEMES ];
        then
          ask_yes_or_no_plus "ambiant_and_radiant" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l " Installiere Desktop-Themen ${light_yellow}Ambiant und Radiant${colors_off}:"
            e_and_l -n " - Extrahiere Master-Archiv, bitte warten   ... "
            DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/Ambiant-MATE-master.zip"
            DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
            LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
            wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
            if [ $? -eq 0 ] &&
              [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
              [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
              unzip -o -qq "$LOCAL_DOWNLOAD_FILE" 'Ambiant-MATE-master/usr/share/icons/*' -d "$DOWNLOAD_DIR/MATE" &>"$LOG_TEMP"
              ICON_RESULT=$?
              unzip -o -qq "$LOCAL_DOWNLOAD_FILE" 'Ambiant-MATE-master/usr/share/themes/*' -d "$DOWNLOAD_DIR/MATE" &>"$LOG_TEMP"
              THEME_RESULT=$?
              if [ $ICON_RESULT -eq 0 ] &&
                  [ $THEME_RESULT -eq 0 ];
              then
                e_and_l "$OK_TAG"
                chown -R "$USER_USERNAME:$USER_USERNAME" "$DOWNLOAD_DIR/MATE" &>/dev/null
                NEW_THEMES=0
                tnr=0
                while [ $tnr -lt $ANZ_THEMES ];
                do
                  THEME_TARGET_DIR="$THEME_TARGET_HOME/${THEME_DIR[$tnr]}"
                  THEME_NAME=${THEME_TARGET_DIR##*/}
                  THEME_TYPE=""
                  if [ $(echo "$THEME_TARGET_DIR" | grep -c -E "icons") -gt 0 ];
                  then
                    THEME_TYPE="Icons "
                  fi
                  if [ $(echo "$THEME_TARGET_DIR" | grep -c -E "themes") -gt 0 ];
                  then
                    THEME_TYPE="Thema "
                  fi
                  e_and_l -n " - Kopiere $THEME_TYPE${light_yellow}$THEME_NAME${colors_off} "
                  ((ANZ_SPACES=26-${#THEME_NAME}))
                  insert_spaces $ANZ_SPACES
                  cp -r -u "$DOWNLOAD_DIR/MATE/Ambiant-MATE-master$THEME_TARGET_DIR" "$THEME_TARGET_DIR" &>$LOG_TEMP
                  if [ $? -eq 0 ];
                  then
                    chown -R "root:root" "$THEME_TARGET_DIR" &>/dev/null
                    e_and_l "... $OK_TAG"
                    ((NEW_THEMES+=1))
                  else
                    e_and_l "... $ERROR_TAG $LINENO"
                  fi
                  ((tnr+=1))
                done
                if [ $NEW_THEMES -gt 0 ];
                then
                  e_and_l " $HINWEIS_TAG: Die Themen sind nun zur Einrichtung des Erscheinungsbilds verfügbar."
                fi
              else
                e_and_l "$ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l "$ERROR_TAG $LINENO"
              add_full_log
            fi
            remove_file "$LOCAL_DOWNLOAD_FILE"
            rm -f -r "$DOWNLOAD_DIR/MATE" &>/dev/null
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else # kein MATE
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NM_TXT")"
      fi

      # ========================================================================
      # Desktop-Themen MATE (Official) installieren
      # ========================================================================
      ACTION_MESSAGE=" Desktop-Themen ${light_cyan}Official MATE${colors_off} installieren"
      if [ $(apt list "mate-themes" 2>/dev/null | grep -i -c "mate-themes") -gt 0 ];
      then
        if [ $(LANG=C dpkg-query -W -f='${Status}' "mate-themes" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
        then
          ask_yes_or_no_plus "mate-themes" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere Desktop-Themen ${light_yellow}Official MATE${colors_off}   ... "
            apt install "mate-themes" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE  ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
      fi

      # ========================================================================
      # Desktop-Themen Ubuntu-MATE installieren
      # ========================================================================
      ACTION_MESSAGE=" Desktop-Themen ${light_cyan}Ubuntu MATE${colors_off} installieren"
      if [ $(apt list "ubuntu-mate-themes" 2>/dev/null | grep -i -c "ubuntu-mate-themes") -gt 0 ];
      then
        if [ $(LANG=C dpkg-query -W -f='${Status}' "ubuntu-mate-themes" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
        then
          ask_yes_or_no_plus "ubuntu-mate-themes" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere Desktop-Themen ${light_yellow}Ubuntu-MATE${colors_off}     ... "
            apt install "ubuntu-mate-themes" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE    ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE   " "$NA_TXT")"
      fi

      # ========================================================================
      # Desktop-Themen Yaru installieren
      # ========================================================================
      ACTION_MESSAGE=" Desktop-Themen ${light_cyan}Yaru${colors_off} installieren"
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        deskpart=""
        if [ "$DESKTOP_ENVIRONMENT" == "Cinnamon" ]; then deskpart="-cinnamon"; fi
        YARU_THEME_PARTS="gtk icon" # sound
        YARU_AVAILS=""
        YARU_MISSING=""
        for yarupkg in ${YARU_THEME_PARTS[@]};
        do
          if [ $(apt list "yaru$deskpart-theme-$yarupkg" 2>/dev/null | grep -i -c "yaru$deskpart-theme-$yarupkg") -gt 0 ];
          then
            YARU_AVAILS+="$yarupkg"
            if [ $(LANG=C dpkg-query -W -f='${Status}' "yaru$deskpart-theme-$yarupkg" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
            then
              YARU_MISSING+="yaru$deskpart-theme-$yarupkg "
            fi
          fi
        done
        if [ "$YARU_AVAILS" != "" ];
        then
          if [ "$YARU_MISSING" != "" ];
          then
            ask_yes_or_no_plus "yaru-theme" "$ACTION_MESSAGE" "" "n"
            if [ $? -eq 1 ];
            then
              e_and_l -n " Installiere ${light_yellow}Yaru-Themen${colors_off}, bitte warten      ... "
              YARU_ERRORS=0
              for ym in ${YARU_MISSING[@]};
              do
                apt install "$ym" -y &>"$LOG_TEMP"
                if [ $? -ne 0 ]; then ((YARU_ERRORS+=1)); fi
              done
              if [ $YARU_ERRORS -eq 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG"
              fi
              add_full_log
              e_and_l "$HALF_MINUS_LINE"
            fi
          else
            e_and_l "$ACTION_MESSAGE           ... $NC_TAG"
          fi
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE          " "$NA_TXT")"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE          " "$NAPIOSDESK_TXT")"
      fi

      # ========================================================================
      # Bildschirmschoner XScreenSaver installieren
      # ========================================================================
      ACTION_MESSAGE=" Bildschirmschoner ${light_cyan}XScreenSaver${colors_off} einrichten"
      if [ "$DISPLAY_SERVER" == "X11" ];
      then
        XSCRSAVER_EPKG_LIST=('xscreensaver' 'xscreensaver-data' 'xscreensaver-data-extra' 'xscreensaver-gl' 'xscreensaver-gl-extra' 'rss-glx')
        XSCRSAVER_AVAILABLE=0 # Verfügbare Module
        XSCRSAVER_INSTALLED=0 # Bereits installierte Module
        XSCRSAVER_NEWINST=0   # Neu installierte Module
        for xs_pkg in ${XSCRSAVER_EPKG_LIST[@]};
        do
          if [ $(apt list "$xs_pkg" 2>/dev/null | grep -i -c "$xs_pkg") -gt 0 ];
          then
            ((XSCRSAVER_AVAILABLE+=1))
          fi
          get_install_status "$xs_pkg"
          if [ $? -ne 0 ];
          then
            ((XSCRSAVER_INSTALLED+=1))
          fi
        done
        if [ $XSCRSAVER_AVAILABLE -gt 1 ];
        then
          # -----------------------------------------------
          # Fehlende XScreenSaver-Komponenten installieren
          # -----------------------------------------------
          if [ $XSCRSAVER_INSTALLED -ne $XSCRSAVER_AVAILABLE ];
          then
            # e_and_l "$HALF_MINUS_LINE"
            ask_yes_or_no_plus "xscreensaver_$xs_pkg" "$ACTION_MESSAGE" "" "n"
            if [ $? -eq 1 ];
            then
              if [ $XSCRSAVER_INSTALLED -ne $XSCRSAVER_AVAILABLE ];
              then
                e_and_l -n " Installiere ${light_yellow}XScreen-Module${colors_off}, bitte warten   ... "
                echo -e "" > "$LOG_TEMP"
                for xs_pkg in ${XSCRSAVER_EPKG_LIST[@]};
                do
                  # ----------------------------------------------
                  # Wenn das Modul noch nicht installiert ist ...
                  # ----------------------------------------------
                  if [ $(LANG=C dpkg-query -W -f='${Status}' "$xs_pkg" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
                  then
                    # -------------------------------------------------
                    # ... und verfügbar ist, dann neu installieren ...
                    # -------------------------------------------------
                    if [ $(apt list "$xs_pkg" 2>/dev/null | grep -i -c "$xs_pkg") -gt 0 ];
                    then
                      apt install "$xs_pkg" -y &>>"$LOG_TEMP"
                      if [ $? -eq 0 ];
                      then
                        ((XSCRSAVER_NEWINST+=1))
                      fi
                    fi
                  fi
                done
                if [ $XSCRSAVER_NEWINST -gt 0 ];
                then
                  e_and_l "$OK_TAG"
                  # -------------------------------------------
                  # Starter für Einstellungen des XScreenSaver
                  # der Systemverwaltung zuordnen
                  # -------------------------------------------
                  CURRENT_CATEGORY="v"
                  KAT_SHORT_NAME="${KATEGORIE_TEXT[v]}"
                  copy_starter_to_desktop "xscreensaver-properties" "" 0
                  copy_starter_to_desktop "xscreensaver-settings" "" 0
                  CHANGES_MADE=1
                else
                  e_and_l "$ERROR_TAG"
                fi
                add_full_log
                remove_file "$LOG_TEMP"
              fi
            fi
            # e_and_l "$HALF_MINUS_LINE"
          else
            e_and_l "$ACTION_MESSAGE  ... $NC_TAG"
          fi
          # ---------------------------------------------------
          # Wenn XScreenSaver verfügbar, dann Autostarteintrag
          # für XScreenSaver erstellen/aktivieren
          # ---------------------------------------------------
          if [ $XSCRSAVER_INSTALLED -eq $XSCRSAVER_AVAILABLE ] ||
            [ $XSCRSAVER_NEWINST -gt 0 ];
          then
            X_SCREENSAVER_AUTOSTART_FILE="$USER_HOME_DIR/.config/autostart/xscreensaver.desktop"
            if [ ! -s "$X_SCREENSAVER_AUTOSTART_FILE" ];
            then
              e_and_l -n " Erstelle Autostarteintrag für ${light_yellow}XScreenSaver${colors_off} ... "
              XSCR_EXEC_TEXT="xscreensaver"
              if [ $(xscreensaver --help 2>&1 | grep -c -E "no-splash") -gt 0 ]; then XSCR_EXEC_TEXT+=" --no-splash"; fi
              create_autostart_file "$X_SCREENSAVER_AUTOSTART_FILE" "XScreenSaver" "Bildschirmschoner und Bildschirmsperre" "$XSCR_EXEC_TEXT" "xscreensaver"
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
          fi
          # ------------------------------------------
          # Wenn XScreenSaver verfügbar ist, dann die
          # Original-Bildschirmschoner deaktivieren
          # ------------------------------------------
          if [ $XSCRSAVER_INSTALLED -eq $XSCRSAVER_AVAILABLE ] ||
            [ $XSCRSAVER_NEWINST -gt 0 ];
          then
            for ((screen_saver = 1; screen_saver < 3; screen_saver++));
            do
              ORG_FILES_NAME=""
              # -------------
              # MATE-Desktop
              # -------------
              if [ $screen_saver -eq 1 ];
              then
                if [ -e "/usr/bin/mate-screensaver" ] ||
                  [ -e "/usr/bin/mate-screensaver.deactivated" ];
                then
                  ORG_FILES_NAME="MATE"
                  declare -A ORG_SCRSAVER_FILES
                  # Binär-Datei
                  ORG_SCRSAVER_FILES[0]="/usr/bin/mate-screensaver"
                  # Autostart-Einträge
                  ORG_SCRSAVER_FILES[1]="/etc/xdg/autostart/mate-screensaver.desktop"
                  ORG_SCRSAVER_FILES[2]="$USER_CONFIG_DIR/autostart/mate-screensaver.desktop"
                  # Menü-Einträge
                  ORG_SCRSAVER_FILES[3]="$GLOBAL_STARTER_DIR/mate-screensaver-preferences.desktop"
                  ORG_SCRSAVER_FILES[4]="/usr/share/mate/applications/mate-screensaver-preferences.desktop"
                fi
              fi
              # -----------------
              # Cinnamon-Desktop
              # -----------------
              if [ $screen_saver -eq 2 ];
              then
                if [ -e "/usr/bin/cinnamon-screensaver" ] ||
                  [ -e "/usr/bin/cinnamon-screensaver.deactivated" ];
                then
                  ORG_FILES_NAME="Cinnamon"
                  declare -A ORG_SCRSAVER_FILES
                  # Binär-Datei
                  ORG_SCRSAVER_FILES[0]="/usr/bin/cinnamon-screensaver"
                  ORG_SCRSAVER_FILES[1]="/usr/bin/cinnamon-screensaver-lock-dialog"
                  # Autostart-Einträge
                  ORG_SCRSAVER_FILES[2]="/etc/xdg/autostart/cinnamon-settings-daemon-screensaver-proxy.desktop"
                  ORG_SCRSAVER_FILES[3]="$USER_CONFIG_DIR/autostart/cinnamon-settings-daemon-screensaver-proxy.desktop"
                  # Menü-Einträge
                  ORG_SCRSAVER_FILES[4]="$GLOBAL_STARTER_DIR/cinnamon-settings-screensaver.desktop"
                fi
              fi
              # ---------------------------------------------------------
              # Wenn Original-Bildschirmschoner aktiv, dann deaktivieren
              # ---------------------------------------------------------
              if [ "$ORG_FILES_NAME" != "" ];
              then
                ORG_ACTIVE_SS_FILES=0
                for scr_saver_file in ${ORG_SCRSAVER_FILES[@]};
                do
                  if [ -e "$scr_saver_file" ]; then ((ORG_ACTIVE_SS_FILES+=1)); fi
                done
                if [ $ORG_ACTIVE_SS_FILES -gt 0 ];
                then
                  e_and_l "$HALF_MINUS_LINE"
                  e_and_l " $ACHTUNG_TAG: Mit $ORG_FILES_NAME- und XScreenSaver sind zwei Bildschirmschoner aktiv."
                  ask_yes_or_no_plus "deactivate_org_screensaver" " $ORG_FILES_NAME-Screensaver vollständig deaktivieren (empfohlen)" "" "j"
                  if [ $? -eq 1 ];
                  then
                    e_and_l -n " Deaktiviere den ${light_yellow}$ORG_FILES_NAME-Bildschirmschoner${colors_off} ... "
                    MSCR_RESULT=0
                    for scr_saver_file in ${ORG_SCRSAVER_FILES[@]};
                    do
                      if [ -e "$scr_saver_file" ];
                      then
                        mv -f "$scr_saver_file" "$scr_saver_file.deactivated" &>/dev/null
                        if [ $? -ne 0 ]; then ((MSCR_RESULT+=1)); fi
                      fi
                    done
                    if [ $MSCR_RESULT -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                      e_and_l "$REBOOT_MSG"
                      CHANGES_MADE=1
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                    e_and_l "$HALF_MINUS_LINE"
                  fi
                fi
              fi
            done
          fi
        else # Kein XScreenSaver verfügbar
          e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
        fi
      else # Kein X11
        e_and_l "$(skip_text "$ACTION_MESSAGE " "nur mit X11")"
      fi

      # ========================================================================
      # Diverse Desktop-Tools einrichten (ggf. mit Autostart)
      # ========================================================================
      AUTOSTART_ACTIVATE_LIST=('copyq' 'redshift-gtk')
      AUTOSTART_ACTIVATE_NAME=('CopyQ' 'Redshift')
      AUTOSTART_ACTIVATE_DESC=('Zwischenablage-Manager' 'Farbtemperaturanpassung')
      AUTOSTART_ACTIVATE_ICON=('copyq' 'redshift')
      AUTOSTART_ACTIVATE_ONLY=('all' 'all')
      a=0
      while [ $a -lt ${#AUTOSTART_ACTIVATE_LIST[@]} ];
      do
        PACKET_NAME_TO_SHOW="${AUTOSTART_ACTIVATE_LIST[$a]/-gtk/}"
        ACTION_MESSAGE=" Modul ${light_cyan}${AUTOSTART_ACTIVATE_DESC[$a]}${colors_off} [$PACKET_NAME_TO_SHOW]"
        ANZ_SPACES=34
        ((ANZ_SPACES-=${#AUTOSTART_ACTIVATE_DESC[$a]}))
        ((ANZ_SPACES-=${#PACKET_NAME_TO_SHOW}))
        i=1; while [ $i -lt $ANZ_SPACES ]; do ACTION_MESSAGE+=" "; ((i+=1)); done
        if [ "${AUTOSTART_ACTIVATE_ONLY[$a]}" == "all" ] ||
          [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E "${AUTOSTART_ACTIVATE_ONLY[$a]}") -gt 0 ];
        then
          # ---------------------------
          # 1. Installation des Moduls
          # ---------------------------
          MODULE_NEW_INSTALLED=0
          get_install_status "${AUTOSTART_ACTIVATE_LIST[$a]}"
          INSTALL_STATUS=$?
          if [ $INSTALL_STATUS -eq 0 ];
          then
            if [ $(apt list "${AUTOSTART_ACTIVATE_LIST[$a]}" 2>/dev/null | grep -i -c -E "${AUTOSTART_ACTIVATE_LIST[$a]}") -gt 0 ];
            then
              ask_yes_or_no_plus "desktop_tool_$PACKET_NAME_TO_SHOW" " Modul ${light_cyan}${AUTOSTART_ACTIVATE_DESC[$a]%%*\/ }${colors_off} installieren" "" "n"
              if [ $? -eq 1 ];
              then
                e_and_l -n " Installiere ${light_yellow}$PACKET_NAME_TO_SHOW${colors_off}, bitte warten"
                ANZ_SPACES=17
                ((ANZ_SPACES-=${#PACKET_NAME_TO_SHOW}))
                i=1; while [ $i -lt $ANZ_SPACES ]; do e_and_l -n " "; ((i+=1)); done
                e_and_l -n " ... "
                apt install "${AUTOSTART_ACTIVATE_LIST[$a]}" -y &>"$LOG_TEMP"
                if [ $? -eq 0 ];
                then
                  MODULE_NEW_INSTALLED=1
                  INSTALL_STATUS=1
                  CHANGES_MADE=1
                  e_and_l "$OK_TAG"
                else
                  e_and_l "$ERROR_TAG"
                fi
              fi
            else
              e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
            fi
          else
            e_and_l "$ACTION_MESSAGE ... $NC_TAG"
          fi
          # --------------------------------------
          # 2. Einrichtung des Autostart-Eintrags
          # --------------------------------------
          if [ $INSTALL_STATUS -eq 1 ];
          then
            # --------------------------------------------------------
            # Auf geeigneten-Desktops zusätzlich Autostart einrichten
            # --------------------------------------------------------
            if [ "$DESKTOP_ENVIRONMENT" == "Cinnamon" ] ||
              [ "$DESKTOP_ENVIRONMENT" == "MATE" ] ||
              [ "$DESKTOP_ENVIRONMENT" == "XFCE" ];
            then
              e_and_l -n " Autostart für ${bold_white}$PACKET_NAME_TO_SHOW${colors_off} einrichten"
              ANZ_SPACES=18
              ((ANZ_SPACES-=${#PACKET_NAME_TO_SHOW}))
              i=1; while [ $i -lt $ANZ_SPACES ]; do e_and_l -n " "; ((i+=1)); done
              e_and_l -n " ... "
              ENTRY_FILE_NAME="$USER_CONFIG_DIR/autostart/${AUTOSTART_ACTIVATE_LIST[$a]}"
              ENTRY_FILE_NAME+=".desktop"
              # --------------------------------------------------
              # Wenn es schon eine Datei gibt, diese anpassen ...
              # --------------------------------------------------
              if [ -s "$ENTRY_FILE_NAME" ];
              then
                if [ $(grep -i -c -E "X-GNOME-Autostart-enabled\s*\=\s*true" "$ENTRY_FILE_NAME" 2>/dev/null) -gt 0 ] &&
                  [ $(grep -i -c -E "X-MATE-Autostart-enabled\s*\=\s*true" "$ENTRY_FILE_NAME" 2>/dev/null) -gt 0 ] &&
                  [ $(grep -i -c -E "NoDisplay\s*=\s*false" "$ENTRY_FILE_NAME" 2>/dev/null) -gt 0 ] &&
                  [ $(grep -i -c -E "Hidden\s*=\s*false" "$ENTRY_FILE_NAME" 2>/dev/null) -gt 0 ];
                then
                  e_and_l "$OA_TAG"
                else
                  # -------------------------------
                  # "Falsche" Einträge korrigieren
                  # -------------------------------
                  create_backup_file "$ENTRY_FILE_NAME"
                  sed -i -E "s/^\s*Autostart-enabled\s*=\s*false/Autostart-enabled=true/gi" "$ENTRY_FILE_NAME"
                  sed -i -E "s/^\s*NoDisplay\s*=\s*true/NoDisplay=false/gi" "$ENTRY_FILE_NAME"
                  sed -i -E "s/^\s*Hidden\s*=\s*true/Hidden=false/gi" "$ENTRY_FILE_NAME"
                  # -----------------------------
                  # Fehlende Einträge hinzufügen
                  # -----------------------------
                  if [ $(grep -i -c -E "X-GNOME-Autostart-enabled\s*\=\s*true" "$ENTRY_FILE_NAME" 2>/dev/null) -eq 0 ];
                  then
                    echo -e $'\n'"X-GNOME-Autostart-enabled=true" >> "$ENTRY_FILE_NAME" 2>/dev/null
                  fi
                  if [ $(grep -i -c -E "X-MATE-Autostart-enabled\s*\=\s*true" "$ENTRY_FILE_NAME" 2>/dev/null) -eq 0 ];
                  then
                    echo -e $'\n'"X-MATE-Autostart-enabled=true" >> "$ENTRY_FILE_NAME" 2>/dev/null
                  fi
                  if [ $(grep -i -c -E "NoDisplay\s*\=\s*false" "$ENTRY_FILE_NAME" 2>/dev/null) -eq 0 ];
                  then
                    echo -e $'\n'"NoDisplay=false" >> "$ENTRY_FILE_NAME" 2>/dev/null
                  fi
                  if [ $(grep -i -c -E "Hidden\s*\=\s*false" "$ENTRY_FILE_NAME" 2>/dev/null) -eq 0 ];
                  then
                    echo -e $'\n'"Hidden=false" >> "$ENTRY_FILE_NAME" 2>/dev/null
                  fi
                  # -------------------------------------------
                  # Leerzeilen entfernen (nur für die Optik ;)
                  sed -i -E "/^[[:space:]]*$/d" "$ENTRY_FILE_NAME"
                  # -----------------------------------------------------
                  # Ausnahmsweise OK ohne vorherige "Erfolgs-Prüfung" ;)
                  # -----------------------------------------------------
                  e_and_l "$OA_TAG"
                  CHANGES_MADE=1
                fi
              else
                # ----------------------------------
                # ... sonst eine neue Datei anlegen
                # ----------------------------------
                create_autostart_file "$ENTRY_FILE_NAME" "${AUTOSTART_ACTIVATE_NAME[$a]}" "${AUTOSTART_ACTIVATE_DESC[$a]}" "/usr/bin/${AUTOSTART_ACTIVATE_LIST[$a]}" "${AUTOSTART_ACTIVATE_ICON[$a]}"
                if [ $? -eq 0 ];
                then
                  e_and_l "$OA_TAG"
                  CHANGES_MADE=1
                else
                  e_and_l "$ERROR_TAG"
                fi
              fi
            fi
          fi
          if [ $MODULE_NEW_INSTALLED -gt 0 ];
          then
            e_and_l "$HALF_MINUS_LINE"
          fi
        else # Kein Ubuntu
          e_and_l "$(skip_text "$ACTION_MESSAGE" "$NU_TXT")"
        fi
        ((a+=1))
      done

    fi

    # ==========================================================================
    # Signaturen der Blu-ray-Datenbank erneuern
    # ==========================================================================
    ACTION_MESSAGE=" Signaturen der ${light_cyan}Blu-ray-Datenbank${colors_off} erneuern "
    if [ $(LANG=C dpkg-query -W -f='${Status}' "libbluray2" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
    then
      USER_AACS_DIR="$USER_CONFIG_DIR/aacs"
      # SNAP_AACS_DIR="$USER_HOME_DIR/snap/vlc/current/.config/aacs" # Derzeit nicht verwendet
      # Nur weitermachen, wenn es keine Schlüsseldatei gibt,
      # oder diese älter als eine Woche ist ...
      if [ -d "$USER_AACS_DIR" ] &&
         [ $(find "$USER_AACS_DIR" -type f -iname "keydb.cfg" -print0 2>/dev/null | grep -i -c -E "keydb.cfg") -gt 0 ] &&
         [ $(find "$USER_AACS_DIR" -type f -iname "keydb.cfg" -mtime +7 -print0 2>/dev/null | grep -i -c -E "keydb.cfg") -eq 0 ];
      then
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      else
        ask_yes_or_no_plus "aacs_update" " AACS-Signaturen für ${light_cyan}Blu-rays${colors_off} erneuern" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Download ${light_yellow}Blu-ray Signaturen${colors_off}, bitte warten  "
          DOWNLOAD_FILE_URL="http://fvonline-db.bplaced.net/fv_download.php?lang=deu"
          DOWNLOAD_FILE_NAME="keydb_deu.zip"
          LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
          wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
          if [ $? -eq 0 ] &&
             [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
             [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
            if [ ! -d "$USER_AACS_DIR" ];
            then
              mkdir -p "$USER_AACS_DIR" &>/dev/null
            fi
            if [ -d "$USER_AACS_DIR" ];
            then
              find "$USER_AACS_DIR" -type f -iname "keydb.cfg" -mtime +7 -delete &>/dev/null
              7z x "$LOCAL_DOWNLOAD_FILE" -o"$USER_AACS_DIR/" -y &>"$LOG_TEMP"
              if [ $? -eq 0 ];
              then
                chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_AACS_DIR" &>/dev/null
                # chmod -R 0755 "$USER_AACS_DIR" &>/dev/null
                remove_file "$LOCAL_DOWNLOAD_FILE"
                e_and_l "... $OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "... $ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l "... $ERROR_TAG $LINENO"
              add_full_log
            fi
          else
            e_and_l "... $ERROR_TAG $LINENO"
            remove_file "$LOCAL_DOWNLOAD_FILE"
            add_full_log
          fi
        fi
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "kein Blu-ray")"
    fi

    # ==========================================================================
    # Hinweis auf Änderungen
    # ==========================================================================
    if [ $CHANGES_MADE -gt 0 ];
    then
      e_and_l "$HALF_LINE"
      e_and_l " $HINWEIS_TAG: Einzelne Änderungen werden ev. erst bei der nächsten Anmeldung aktiv"
    fi

  fi # Ende [extras]

fi # Ende Zusätzliche System-Komponenten und Treiber [extras]

#===============================================================================
# Blockieren oder freigeben der Kernel-Updates
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [[ ${OPTION_FLAG[kuplock]} -eq 1 || ${OPTION_FLAG[kunlock]} -eq 1 ]];
then
  e_and_l "$FULL_LINE"
  e_and_l -n " ${bold_blue}Kernel-Update-Locking${colors_off} ${dark_gray}[ku"
  if [ ${OPTION_FLAG[kuplock]} -eq 1 ];
  then
    e_and_l -n "p"
  else
    e_and_l -n "n"
  fi
  e_and_l "lock]${colors_off}"
  e_and_l "$FULL_LINE"
  # e_and_l " Die aktuell verwendete Kernel-Version ist ${bold_white}$CURRENT_KERNEL_VERSION${colors_off}."
  if [ ${OPTION_FLAG[kuplock]} -eq 1 ];
  then
    e_and_l " Zur Stabilisierung des Systems können ${light_cyan}Updates des Kernels${colors_off} blockiert werden."
    KERNEL_QUESTION="jetzt ${light_cyan}blockieren${colors_off}"
  else
    e_and_l " ${light_cyan}Aktualisierungen${colors_off} (Updates) ${light_cyan}für den Kernel${colors_off} sind derzeit blockiert."
    KERNEL_QUESTION="wieder ${light_cyan}freigeben${colors_off}"
  fi
  ask_yes_or_no_plus "" " Updates für den Kernel $KERNEL_QUESTION" "" "n"
  if [ $? -eq 1 ];
  then
    if [ ${OPTION_FLAG[kuplock]} -eq 1 ];
    then
      e_and_l -n " ${light_yellow}Blockiere Aktualisierungen${colors_off} (Updates) für den Linux-Kernel ... "
    else
      e_and_l -n " ${light_yellow}Entferne die Aktualisierungs-Blockade${colors_off} für den Linux-Kernel ... "
    fi
    LOCKING_ERRORS=0
    echo -e "" > "$LOG_TEMP"
    for kp in "${KERNEL_PACKS[@]}";
    do
      if [ $(dpkg -l 2>/dev/null | grep -c -i "$kp") -gt 0 ];
      then
        if [ ${OPTION_FLAG[kuplock]} -eq 1 ];
        then
          apt-mark hold "$kp*" 2>&1 1>>"$LOG_TEMP"
          if [ $? -ne 0 ]; then ((LOCKING_ERRORS+=1)); fi
        else
          apt-mark unhold "$kp*" 2>&1 1>>"$LOG_TEMP"
          if [ $? -ne 0 ]; then ((LOCKING_ERRORS+=1)); fi
        fi
      fi
    done
    if [ $LOCKING_ERRORS -eq 0 ];
    then
      e_and_l "$OK_TAG"
      repo_update " Aktualisiere das Repository, bitte warten ... "
    else
      e_and_l "$ERROR_TAG"
    fi
    add_full_log
  fi
fi # Ende [kuplock] [kunlock]

#===============================================================================
# Einrichtung und Optimierung von System-Einstellungen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then

  if [[ ${OPTION_FLAG[setutc]} -eq 1 || ${OPTION_FLAG[optimize]} -eq 1 ]];
  then
    e_and_l "$FULL_LINE"
    e_and_l -n " ${bold_blue}Einrichtung und Optimierung von System-Einstellungen${colors_off}"
    if [ ${OPTION_FLAG[setutc]} -eq 1 ]; then e_and_l -n " ${dark_gray}[setutc]${colors_off}"; fi
    if [ ${OPTION_FLAG[optimize]} -eq 1 ]; then e_and_l -n " ${dark_gray}[optimize]${colors_off}"; fi
    e_and_l ""
    e_and_l "$FULL_LINE"
  fi

  # ============================================================================
  # Umstellung der Systemzeit auf Universal Time Coordinated (UTC)
  # ---------------------------------------------------------------
  # Derzeit noch als separate Option - die Umstellung der Systemzeit auf RTC
  # erfolgt im Rahmen der weiteren System-Einstellungen [optimize] - s.u.
  # ============================================================================
  if [ ${OPTION_FLAG[setutc]} -eq 1 ];
  then
    e_and_l " ${bold_blue}Systemzeit${colors_off}"
    e_and_l "$HALF_LINE"
    ACTION_MESSAGE=" Umstellung der ${light_cyan}Systemzeit auf UTC${colors_off}         "
    if timedatectl &>/dev/null;
    then
      if [ $(LANG=C timedatectl show 2>/dev/null | grep -c -i -E "^\s*LocalRTC\s*=\s*yes") -gt 0 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
        timedatectl set-local-rtc 0 --adjust-system-clock 2>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          e_and_l "$REBOOT_MSG"
        else
          e_and_l "$ERROR_TAG"
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
    e_and_l "$HALF_LINE"
  fi

fi

if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[optimize]} -eq 1 ];
then

  CHANGES_MADE=0

  e_and_l " ${bold_blue}Multi-Boot${colors_off}"
  e_and_l "$HALF_LINE"

  if [ ${OPTION_FLAG[setutc]} -eq 0 ];
  then
    # ==========================================================================
    # Umstellung der Systemzeit auf RTC wie bei Microsoft Windows (statt UTC)
    # ==========================================================================
    IS_MULTI_BOOT=1
    ACTION_MESSAGE=" Umstellung der ${light_cyan}Systemzeit auf RTC${colors_off} (MS Win)"
    if [ $IS_MULTI_BOOT -ne 0 ];
    then
      if timedatectl &>/dev/null;
      then
        if [ $(LANG=C timedatectl show 2>/dev/null | grep -c -i -E "^\s*LocalRTC\s*=\s*yes") -eq 0 ];
        then
          e_and_l " Einige Betriebssysteme wie MS Windows verwenden für Datum und Uhrzeit das"
          e_and_l " RTC-Format (Real Time Clock) statt UTC-Format (Universal Time Coordinated),"
          e_and_l " was auf ${bold_white}Multi-Boot-Systemen${colors_off} zu unterschiedlichen Zeitangaben führen kann."
          e_and_l " Um die Angaben zu vereinheitlichen, kann Linux auf RTC umgestellt werden."
          ask_yes_or_no_plus "utc_to_rtc" " Die ${light_cyan}Systemzeit auf RTC (Real Time Clock)${colors_off} umstellen" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
            timedatectl set-local-rtc 1 --adjust-system-clock 2>/dev/null
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  fi

  # ============================================================================
  # Aktivierung der Betriebssystem-Erkennung
  # ============================================================================
  ACTION_MESSAGE=" Aktivierung der ${light_cyan}Betriebssystem-Erkennung${colors_off}  "
  if [ -s "$GRUB_DEFAULT_FILE" ];
  then
    # ------------------------------------------------------------------------
    # Nur ändern, wenn die Erkennung warum auch immer zuvor deaktiviert wurde
    # ------------------------------------------------------------------------
    if [ $(grep -i -c -E "^\s*GRUB_DISABLE_OS_PROBER\s*=\s*\"*true" "$GRUB_DEFAULT_FILE") -gt 0 ];
    then
      ask_yes_or_no_plus "activate_os_prober" " Die Erkennung anderer ${light_cyan}Betriebssysteme${colors_off} aktivieren" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
        if [ $(grep -i -c -E "^\s*\#*\s*GRUB_DISABLE_OS_PROBER" "$GRUB_DEFAULT_FILE") -gt 0 ];
        then
          sed -i 's/^\s*\#*\s*GRUB_DISABLE_OS_PROBER.*/GRUB_DISABLE_OS_PROBER=false/gi' "$GRUB_DEFAULT_FILE" 2>/dev/null
        else
          echo -e "" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
          echo -e "GRUB_DISABLE_OS_PROBER=false" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
        fi
        if [ $? -eq 0 ];
        then
          update-grub &>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
        else
          e_and_l "$ERROR_TAG"
        fi
      fi
    else
      e_and_l -n "$ACTION_MESSAGE ... $OK_TAG ${dark_gray}"
      if [ $(grep -i -c -E "^\s*GRUB_DISABLE_OS_PROBER\s*\=\s*\"*false" "$GRUB_DEFAULT_FILE") -gt 0 ];
      then
        e_and_l -n "(explizit aktiviert)"
      else
        e_and_l -n "(nicht deaktiviert)"
      fi
      e_and_l "${colors_off}"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Betriebssystem${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Einschalten der internen Firewall (ufw) und auschalten der UFW-Protokolle
  # ============================================================================
  ASKED_UFW_INST_NO=0
  ACTION_MESSAGE=" Einschalten der internen ${light_cyan}Firewall (ufw)${colors_off}"
  if [ $(LANG=C dpkg-query -W -f='${Status}' "ufw" 2>/dev/null | grep -i -c -E "ok installed") -gt 0 ];
  then
    UFW_IS_INSTALLED=1
  else
    if [ $(apt list "ufw" 2>/dev/null | grep -i -c -E "ufw") -gt 0 ];
    then
      ask_yes_or_no_plus "ufw_install" " Soll die ${light_cyan}Firewall (ufw)${colors_off} installiert werden" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Installiere ${light_yellow}Firewall (ufw)${colors_off}, bitte warten   ... "
        apt install "ufw" -y &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          UFW_IS_INSTALLED=1
          # Wenn das geklappt hat, auch die grafische Oberfläche dazu laden -----
          if [ $(LANG=C dpkg-query -W -f='${Status}' "gufw" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ] &&
             [ $(apt list "gufw" 2>/dev/null | grep -i -c -E "gufw") -gt 0 ];
          then
            apt install "gufw" -y &>"$LOG_TEMP"
          fi
          e_and_l "$OK_TAG"
        else
          UFW_IS_INSTALLED=0
          e_and_l "$ERROR_TAG"
          add_full_log
        fi
      else
        ASKED_UFW_INST_NO=1
        UFW_IS_INSTALLED=0
      fi
    else
      UFW_IS_INSTALLED=0
    fi
  fi
  if [ $UFW_IS_INSTALLED -eq 1 ];
  then
    # ---------------------
    # Firewall einschalten
    # ---------------------
    if [ $(LANG=C ufw status 2>/dev/null | grep -i -c -E "status\s*:\s*a") -eq 0 ];
    then
      ask_yes_or_no_plus "ufw_activate" "$ACTION_MESSAGE" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Schalte die interne ${light_yellow}Firewall (ufw)${colors_off} ein     ... "
        echo "y" | ufw enable &>/dev/null
        if [ $? -eq 0 ];
        then
          ufw reload &>/dev/null
          e_and_l "$OK_TAG"
          CHANGES_MADE=1
        else
          e_and_l "$ERROR_TAG"
          add_full_log
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE    ... $NC_TAG"
    fi
    # ----------------------------
    # Protokollierung ausschalten
    # ----------------------------
    ACTION_MESSAGE=" Ausschalten der ${light_cyan}Firewall-Protokoll-Logs${colors_off}"
    if [ $(LANG=C ufw status 2>/dev/null | grep -i -c -E "status\s*:\s*a") -gt 0 ];
    then
      if [ $(LANG=C ufw status verbose 2>/dev/null | grep -i -c -E "Proto.*\:\s*off$") -eq 0 ] &&
         [ $(LANG=C ufw status verbose 2>/dev/null | grep -i -c -E "Logging\s*\:\s*off$") -eq 0 ];
      then
        ask_yes_or_no_plus "ufw_logging_off" "$ACTION_MESSAGE" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Schalte das ${light_yellow}Protokoll-Log der Firewall${colors_off} aus ... "
          ufw logging off &>/dev/null
          if [ $? -eq 0 ];
          then
            ufw reload &>/dev/null
            e_and_l "$OK_TAG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
            add_full_log
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$ACTION_MESSAGE    ... $NC_TAG"
      fi
    # else
    #   e_and_l "$(skip_text "$ACTION_MESSAGE   " "$NA_TXT")" # Firewall nicht aktiv
    fi
  else
     # Wenn die Installation verneint wurde, nicht nochmal
     # anzeigen dass die Firewall nicht installiert ist ;)
    if [ $ASKED_UFW_INST_NO -eq 0 ];
    then
      e_and_l "$(skip_text "$ACTION_MESSAGE   " "$NA_TXT")"
    fi
  fi

  # ============================================================================
  # Aktivierung des SSH-Server bei Systemstart
  # (einschließlich Installation von openssh-server und sshguard)
  # ============================================================================
  if [ $(apt list "openssh-server" 2>/dev/null | grep -i -c -E "openssh-server") -gt 0 ];
  then
    ASKED_SSH_INST_NO=0
    if [ $(LANG=C dpkg-query -W -f='${Status}' "openssh-server" 2>/dev/null | grep -i -c -E "ok installed") -gt 0 ];
    then
      OPENSSH_INSTALL_STATUS=0
    else
      ask_yes_or_no_plus "ssh_install" " Installation des ${light_cyan}OpenSSH-Servers${colors_off}" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Installiere ${light_yellow}openssh-server${colors_off}, bitte warten   ... "
        apt install "openssh-server" -y &>"$LOG_TEMP"
        OPENSSH_INSTALL_STATUS=$?
        if [ $OPENSSH_INSTALL_STATUS -eq 0 ];
        then
          e_and_l "$OK_TAG"
          # ---------------------------------
          # zusätzlich sshguard installieren
          # ---------------------------------
          if [ $(LANG=C dpkg-query -W -f='${Status}' "sshguard" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ] &&
             [ $(apt list "sshguard" 2>/dev/null | grep -i -c -E "sshguard") -gt 0 ];
          then
            e_and_l -n " Installiere ${light_yellow}sshguard${colors_off}, bitte warten         ... "
            apt install "sshguard" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
        else
          e_and_l "$ERROR_TAG"
          add_full_log
        fi
      else
        ASKED_SSH_INST_NO=1
        OPENSSH_INSTALL_STATUS=1
      fi
    fi
    # ------------------------------------------------------
    # Nur weitermachen, wenn openssh-server installiert ist
    # ------------------------------------------------------
    if [ $ASKED_SSH_INST_NO -eq 0 ];
    then
      ACTION_MESSAGE=" Aktivierung des ${light_cyan}SSH-Server${colors_off} bei Systemstart"
      if [ $OPENSSH_INSTALL_STATUS -eq 0 ];
      then
        if [ $(LANG=C systemctl is-enabled ssh 2>/dev/null | grep -i -c -E "enabled") -eq 0 ];
        then
          ask_yes_or_no_plus "ssh_activate" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Aktiviere den ${light_yellow}SSH-Server${colors_off} bei Systemstart   ... "
            systemctl enable ssh &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG $LINENO"
              add_full_log
            fi
            systemctl start ssh &>/dev/null
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else # openssh-server nicht installiert
        e_and_l "$(skip_text "$ACTION_MESSAGE ... " "$NA_TXT")"
      fi
    fi
  else # openssh-server nicht verfügbar
    e_and_l "$(skip_text " Installation u. Einrichtung des SSH-Server" "$NA_TXT")"
  fi

  # ============================================================================
  # Reduzierung des Swappings
  # Werte von 0 (wenig) bis 100 (viel)
  # ACHTUNG: 0 = kein Swapping => nur verwenden, wenn soviel Hauptspeicher
  # vorhanden ist, dass Swapping durch das System ausgeschlossen werden kann!
  # ============================================================================
  # Schwellwert (verbleibender freier Hauptspeicher), ab welchem das
  # Betriebssystem anfängt Speicher auf Festplatten auszulagern (swappen)
  START_SWAP_FREE=512
  # Kleinster einzugebender neuer Wert (in %)
  MIN_SWAPPING=1
  # Größter einzugebender neuer Wert (in %)
  MAX_SWAPPING=80 # Standardvorgabe Linux ist 60
  # Liste der Konfigurations-Dateien
  declare -A SWAP_CONF_FILE_LIST
  SWAP_CONF_FILE_LIST[0]="/etc/sysctl.conf" # (bis Debian 12)
  SWAP_CONF_FILE_LIST[1]="/etc/sysctl.d/10_swappiness.conf" # (ab Debian 13)
  # Optimalen Wert berechnen
  BEST_SWAP_SIZE=$((START_SWAP_FREE * 1024 * 1024))
  BEST_SWAP_SIZE=$((BEST_SWAP_SIZE * 100 / MEMORY_TOTAL))
  # Aktuellen Wert auslesen
  SWAP_VALUE=$(sysctl vm.swappiness)
  SWAP_VALUE=$(echo -n "${SWAP_VALUE##*\=}" | xargs)
  ACTION_MESSAGE=" Einstellung des ${light_cyan}Swapping${colors_off} von Hauptspeicher ... "
  if [ $SWAP_VALUE -eq $BEST_SWAP_SIZE ];
  then
    e_and_l -n "$ACTION_MESSAGE"
    e_and_l "$OK_TAG ${dark_gray}(Wert: $SWAP_VALUE%)${colors_off}"
  else
    e_and_l " Der ${light_cyan}Swapping-Wert${colors_off} liegt bei ${light_cyan}$SWAP_VALUE${colors_off}, für dieses System wird ${light_yellow}$BEST_SWAP_SIZE${colors_off} empfohlen."
    ask_yes_or_no_plus "swap_change" " Einstellung des ${light_cyan}Swapping-Wertes${colors_off} jetzt ändern" "" "n"
    if [ $? -eq 1 ];
    then
      NEW_SWAPPING=0
      while [ $NEW_SWAPPING -lt $MIN_SWAPPING ] ||
            [ $NEW_SWAPPING -gt $MAX_SWAPPING ];
      do
        e_and_l -n " Bitte neuen Wert eingeben von ${bold_yellow}$MIN_SWAPPING${colors_off} bis ${bold_yellow}$MAX_SWAPPING${colors_off}: "
        read -r NEW_SWAPPING
        NEW_SWAPPING=$(echo $NEW_SWAPPING | sed 's/[^0-9]*//g')
        if [ "$NEW_SWAPPING" == "" ]; then NEW_SWAPPING=0; fi
      done
      e_and_l -n "$ACTION_MESSAGE"
      if [ $SWAP_VALUE -ne $NEW_SWAPPING ];
      then
        # Änderungen sofort wirksam machen
        sysctl vm.swappiness=${NEW_SWAPPING} &>/dev/null
        # Änderungen permanent machen
        FILE_ERRORS=0
        for swap_conf_file in "${SWAP_CONF_FILE_LIST[@]}";
        do
          create_backup_file "$swap_conf_file"
          # Alle eventuell bestehenden Einträge löschen
          if [ -s "$swap_conf_file" ];
          then
            SEARCH_SWAP_STRING="^\s*vm.swappiness\s*=\s*"
            OLD_ENTRY_LINE=$(grep -i -m 1 -n -E "$SEARCH_SWAP_STRING" "$swap_conf_file" 2>/dev/null)
            while [ "$OLD_ENTRY_LINE" != "" ];
            do
              DELETE_PART=${OLD_ENTRY_LINE##*\:}
              OLD_ENTRY_LINE=$(echo ${OLD_ENTRY_LINE/:$DELETE_PART/} | xargs)
              sed -i "${OLD_ENTRY_LINE}d" "$swap_conf_file"
              OLD_ENTRY_LINE=$(grep -i -m 1 -n -E "$SEARCH_SWAP_STRING" "$swap_conf_file" 2>/dev/null)
            done
          fi
          # Neuen Eintrag hinzufügen
          echo -e "vm.swappiness=$NEW_SWAPPING" >> "$swap_conf_file"
          if [ $? -eq 0 ];
          then
            remove_double_empty_lines "$swap_conf_file"
          else
            ((FILE_ERRORS+=1))
          fi
        done
        if [ $FILE_ERRORS -eq 0 ];
        then
          e_and_l "$OK_TAG ${light_yellow}(NEU: $NEW_SWAPPING%)${colors_off}"
          CHANGES_MADE=1
        else
          e_and_l "$ERROR_TAG"
          add_full_log
        fi
      else
        e_and_l "$NC_TAG ${dark_gray}($NEW_SWAPPING%)${colors_off}"
      fi
    fi
    e_and_l "$HALF_MINUS_LINE"
  fi

  # ============================================================================
  # Reduzierung unnötiger Schreibvorgänge auf Festplatten
  # ============================================================================
  ACTION_MESSAGE=" Reduzierung unnötiger ${light_cyan}Festplatten-Zugriffe${colors_off} ... "
  if [ -s "$ETC_FSTAB" ];
  then
    FSTAB_EXT4_LINES=$(grep -i -c -E "\sext4\s" "$ETC_FSTAB")
    FSTAB_AUTO_LINES=$(grep -i -c -E "\sauto\s" "$ETC_FSTAB")
    FSTAB_RELEVANT_LINES=$((FSTAB_EXT4_LINES+FSTAB_AUTO_LINES))
    FSTAB_NOATIME_EXT4_LINES=$(grep -i -c -E "\sext4\s*.*noatime" "$ETC_FSTAB")
    FSTAB_NOATIME_AUTO_LINES=$(grep -i -c -E "\sauto\s*.*noatime" "$ETC_FSTAB")
    FSTAB_OCCURES_LINES=$((FSTAB_NOATIME_EXT4_LINES+FSTAB_NOATIME_AUTO_LINES))
    if [ $FSTAB_RELEVANT_LINES -ne $FSTAB_OCCURES_LINES ];
    then
      ask_yes_or_no_plus "fstab_noatime" " Unnötige ${light_cyan}Festplatten-Zugriffe${colors_off} reduzieren" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}"
        create_backup_file "$ETC_FSTAB"
        # 1. "noatime" an allen relevanten Stellen hinzufügen. Dazu werden alle
        # Dateisysteme im Format "ext4" und "auto" als relevant angesehen
        sed -i -E "s/(\s*\sext4\s\s*)/\1noatime,/gi" "$ETC_FSTAB"
        sed -i -E "s/(\s*\sauto\s\s*)/\1noatime,/gi" "$ETC_FSTAB"
        # 2. Bestehende oder entstandene Mehrfacheinträge von "noatime" korrigieren
        sed -i -E "s/(noatime.*),noatime/\1/gi" "$ETC_FSTAB"
        sed -i -E "s/noatime,(.*noatime)/\1/gi" "$ETC_FSTAB"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          CHANGES_MADE=1
        else
          e_and_l "$ERROR_TAG"
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE$NC_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "keine fstab!")"
  fi

  # ============================================================================
  # Temporäre System-Ordner ins RAM verlagern (NICHT eigene RAM Disk - s.u.)
  # Das erstellte Laufwerk (tmpfs) ist dynamisch und belegt nur soviel Memory
  # wie es braucht, maximal 50% des zur Verfügung stehenden Hauptspeichers
  # ACHTUNG: Diesen Teil immer VOR der Erstellung der permanenten dynamischen
  #          RAM Disk lassen, weil hier REDUCE_TMP_RAM ermittelt wird!
  # ============================================================================
  REDUCE_TMP_RAM=0
  ACTION_MESSAGE=" Ordner ${light_cyan}/tmp${colors_off} in den ${light_cyan}Hauptspeicher${colors_off} auslagern"
  if [ -s "$ETC_FSTAB" ];
  then
    HALF_TOTAL_MEMORY=$((MEMORY_TOTAL / 2))
    RAMDISK_ENABLED_SIZE=$(get_tmpfs_size "$RAMDISK_MOUNTPOINT")
    RAMDISK_ENABLED_SIZE=$((RAMDISK_ENABLED_SIZE * 1024 * 1024))
    FREE_FOR_TMP_DIR=$((MEMORY_TOTAL - MIN_LINUX_RAM - RAMDISK_ENABLED_SIZE))
    TEMP_MSG="$ACTION_MESSAGE ..."
    if [ $(grep -i -c -E "^\s*tmpfs\s*\/tmp\s*tmpfs" "$ETC_FSTAB") -gt 0 ];
    then
      e_and_l "$TEMP_MSG $NC_TAG"
      REDUCE_TMP_RAM=1
    else
      e_and_l "$HALF_MINUS_LINE"
      # Abfrage ---------------------------------------------------------------
      # Wenn nach Abzug einer ev. vorhandenen RAM Disk und der Sicherheitsreserve für Linux
      # noch Platz ist, dann anbieten /tmp in den Hauptspeicher zu verlagern ...
      FREE_MEMORY=$(show_human_bytes ${MEMORY_AVAIL} "M")
      if [ $FREE_FOR_TMP_DIR -gt $HALF_TOTAL_MEMORY ];
      then
        e_and_l " Es sind ${light_yellow}$FREE_MEMORY${colors_off} Hauptspeicher frei."
        ask_yes_or_no_plus "unused_memory_1" "$ACTION_MESSAGE" "" "n"
        DO_MOVE_TMP=$?
      else # ... sonst fragen ob das trotzdem gewollt ist
        e_and_l " Es sind nur ${light_yellow}$FREE_MEMORY${colors_off} Hauptspeicher frei. Soll der Ordner ${light_cyan}/tmp${colors_off} trotzdem in den"
        ask_yes_or_no_plus "unused_memory_2" " ${light_cyan}Hauptspeicher${colors_off} ausgelagert werden (${bold_white}nicht empfohlen${colors_off})" "" "n"
        DO_MOVE_TMP=$?
      fi
      # Auslagern -------------------------------------------------------------
      if [ $DO_MOVE_TMP -eq 1 ];
      then
        e_and_l -n " Verlagere Ordner ${light_yellow}/tmp${colors_off} in den ${light_yellow}Hauptspeicher${colors_off} ... "
        create_backup_file "$ETC_FSTAB"
        # Wenn es den Eintrag schon gibt, diesen auskommentieren ...
        if [ $(grep -i -c -E "^#\s*tmpfs\s\s*\/tmp\s\s*tmpfs\s\s*noatime,nosuid,mode=1777\s\s*0\s\s*0" "$ETC_FSTAB") -gt 0 ];
        then
          sed -i -E "s/^#\s*tmpfs\s\s*\/tmp\s\s*tmpfs\s\s*noatime,nosuid,mode=1777\s\s*0\s\s*0/tmpfs  \/tmp  tmpfs  noatime,nosuid,mode=1777  0  0/gi" "$ETC_FSTAB"
        else # ... sonst neu anlegen
          echo -e "tmpfs  /tmp  tmpfs  noatime,nosuid,mode=1777  0  0" >> "$ETC_FSTAB" 2>"$LOG_TEMP"
        fi
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          e_and_l "$REBOOT_MSG"
          CHANGES_MADE=1
          REDUCE_TMP_RAM=1
        else
          restore_backup_file "$ETC_FSTAB"
          e_and_l "$ERROR_TAG $LINENO"
          add_full_log
        fi
      fi
      e_and_l "$HALF_MINUS_LINE"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "keine fstab!")"
  fi

  # ============================================================================
  # Permanente dynamische RAM Disk einrichten (NICHT /tmp verlagern - s.o.)
  # Das erstellte Laufwerk (tmpfs) ist dynamisch und belegt nur soviel Memory
  # wie es braucht, maximal soviel Platz wie in der Eingabe angegeben wird
  # ACHTUNG: Diesen Teil immer HINTER der Verlagerung des temporären System-
  #          Ordners ins RAM lassen, weil dort REDUCE_TMP_RAM ermittelt wird!
  # ============================================================================
  RAMDISK_MOUNTPOINT="/media/ramdisk"
  # Platz für ggf. ausgelagerten Ordner /tmp freilassen (s.o.)
  REDUCE_TMP_RAM=$((REDUCE_TMP_RAM * MEMORY_TOTAL / 2))
  # Verbleidener Platz für die RAM DISK
  FREE_FOR_RAMDISK=$((MEMORY_TOTAL - MIN_LINUX_RAM - REDUCE_TMP_RAM))
  FREE_FOR_RAMDISK=$((FREE_FOR_RAMDISK / 1024 / 1024))
  # ---------------------------------------------------------------------------
  ACTION_MESSAGE=" Permanente dynamische ${light_cyan}RAM Disk${colors_off} einrichten"
  if [ -s "$ETC_FSTAB" ];
  then
    TEMP_MSG="$ACTION_MESSAGE  ..."
    RAMDISK_ENABLED_SIZE=$(get_tmpfs_size "$RAMDISK_MOUNTPOINT")
    if [ $RAMDISK_ENABLED_SIZE -gt 0 ];
    then
      e_and_l "$TEMP_MSG $OK_TAG ${dark_gray}(Wert: $RAMDISK_ENABLED_SIZE MB)${colors_off}"
    else
      if [ $FREE_FOR_RAMDISK -ge $RAMDISK_MIN_SIZE ];
      then
        # e_and_l "$HALF_MINUS_LINE"
        ask_yes_or_no_plus "ram_disk" "$ACTION_MESSAGE" "" "n"
        if [ $? -eq 1 ];
        then
          RAMDISK_SIZE=0
          while [ $RAMDISK_SIZE -lt $RAMDISK_MIN_SIZE ] ||
                [ $RAMDISK_SIZE -gt $FREE_FOR_RAMDISK ];
          do
            if [ $FREE_FOR_RAMDISK -ge $BROWSER_CACHE_MIN_SIZE ];
            then
              e_and_l " ${bold_yellow}Tipp${colors_off}: Für die Verlagerung von Browser-Caches mind. ${light_yellow}$BROWSER_CACHE_MIN_SIZE${colors_off} (MB) angeben."
            fi
            e_and_l -n " Bitte maximale Größe angeben von ${bold_yellow}$RAMDISK_MIN_SIZE${colors_off} bis ${bold_yellow}$FREE_FOR_RAMDISK${colors_off} (MB): "
            read -r RAMDISK_SIZE
            RAMDISK_SIZE=$(echo $RAMDISK_SIZE | sed 's/[^0-9]*//g')
            if [ "$RAMDISK_SIZE" == "" ]; then RAMDISK_SIZE=0; fi
          done
          ask_yes_or_no_plus "" " Jetzt dynamische ${light_yellow}RAM Disk${colors_off} von ${light_yellow}max. $RAMDISK_SIZE MB${colors_off} anlegen" "" "n"
          if [ $? -eq 1 ];
          then
            if [ $(df | grep -i -c -E "$RAMDISK_MOUNTPOINT") -gt 0 ];
            then
              e_and_l " ${bold_yellow}Ups${colors_off}, das Dateisystem ${light_cyan}$RAMDISK_MOUNTPOINT${colors_off} ist noch eingehangen."
              ask_yes_or_no_plus "" " Jetzt aushängen (alle Daten darauf werden gelöscht)" "" "n"
              if [ $? -eq 1 ];
              then
                umount "$RAMDISK_MOUNTPOINT" &>/dev/null
                RAMDISK_IS_MOUNTED=$?
              else
                RAMDISK_IS_MOUNTED=1
              fi
            else
              RAMDISK_IS_MOUNTED=0
            fi
            if [ $RAMDISK_IS_MOUNTED -eq 0 ];
            then
              e_and_l -n " Erstellung der neuen dynamischen ${light_cyan}RAM Disk${colors_off}  ... "
              if [ ! -d "$RAMDISK_MOUNTPOINT" ];
              then
                mkdir -p "$RAMDISK_MOUNTPOINT" &>"$LOG_TEMP"
              fi
              if [ -d "$RAMDISK_MOUNTPOINT" ];
              then
                chmod -R 0777 "$RAMDISK_MOUNTPOINT" &>/dev/null
                create_backup_file "$ETC_FSTAB"
                echo -e "tmpfs  ${RAMDISK_MOUNTPOINT}  tmpfs  noatime,defaults,size=${RAMDISK_SIZE}M,x-gvfs-show,x-gvfs-name=RAM%20Disk  0  0" >> "$ETC_FSTAB" 2>"$LOG_TEMP"
                if [ $? -eq 0 ];
                then
                  mount "$RAMDISK_MOUNTPOINT" &>"$LOG_TEMP"
                  e_and_l "$OK_TAG (${light_yellow}$RAMDISK_MOUNTPOINT${colors_off})"
                else
                  restore_backup_file "$ETC_FSTAB"
                  e_and_l "$ERROR_TAG $LINENO"
                  add_full_log
                fi
              else
                e_and_l "$ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l " Sicherheitshalber wurde die ${light_cyan}RAM Disk${colors_off} ${bold_red}nicht${colors_off} neu erstellt!"
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$TEMP_MSG ${bold_yellow}besser nicht${colors_off} ${dark_gray}(zu wenig Memory)${colors_off}"
      fi
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE " "keine fstab!")"
  fi

  # ============================================================================
  # Verlagerung der Browser-Caches in den Hauptspeicher (RAM Disk)
  # ---------------------------------------------------------------------------
  # Dazu wird ein Autostart-Eintrag angelegt, welcher mittels eines Skripts
  # "browser-cache-to-ram" bei der Anmeldung des Benutzers für jeden Browser
  # einen Unterordner auf einer dynamischen RAM Disk (sofern diese angelegt
  # ist) erstellt, sowie die Cache-Ordner dorthin umlenkt.
  # ============================================================================
  THE_BCD_SCRIPT_NAME="browser-cache-to-ram"
  THE_BCD_SCRIPT_DIR="$USER_HOME_DIR/.local/bin"
  THE_BCD_SCRIPT_FILE="$THE_BCD_SCRIPT_DIR/$THE_BCD_SCRIPT_NAME"
  ACTION_MESSAGE=" ${light_cyan}Browser-Caches${colors_off} auf die ${light_cyan}RAM Disk${colors_off} verlagern "
  if [ "$USER_USERNAME" != "root" ];
  then
    if [ ! -s "$THE_BCD_SCRIPT_FILE" ];
    then
      CHECK_RAMDISK_SIZE=$(get_tmpfs_size "/media/ramdisk")
      if [ $CHECK_RAMDISK_SIZE -ge $BROWSER_CACHE_MIN_SIZE ];
      then
        ask_yes_or_no_plus "browser-cache-to-ram" "$ACTION_MESSAGE" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Verlagere ${light_yellow}Browser-Caches${colors_off} auf die ${light_yellow}RAM Disk${colors_off}  ... "
          # 1. Download des Skriptes zur Anlage der Ordner und Verknüpfungen
          DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/scripts/$THE_BCD_SCRIPT_NAME"
          DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
          LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
          wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
          if [ $? -eq 0 ] &&
             [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
             [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
            if [ ! -d "$THE_BCD_SCRIPT_DIR" ];
            then
              mkdir -p "$THE_BCD_SCRIPT_DIR" &>"$LOG_TEMP"
              chown -R "$USER_USERNAME:$USER_USERNAME" "$THE_BCD_SCRIPT_DIR" &>/dev/null
            fi
            if [ -d "$THE_BCD_SCRIPT_DIR" ];
            then
              create_backup_file "$THE_BCD_SCRIPT_FILE"
              mv -f "$LOCAL_DOWNLOAD_FILE" "$THE_BCD_SCRIPT_FILE" &>"$LOG_TEMP"
              if [ $? -eq 0 ];
              then
                chown -R "$USER_USERNAME:$USER_USERNAME" "$THE_BCD_SCRIPT_FILE" &>/dev/null
                chmod -R 0744 "$THE_BCD_SCRIPT_FILE" &>/dev/null
                # 2. Autostart-Eintrag für das Skript erzeugen
                create_autostart_file "$USER_CONFIG_DIR/autostart/$THE_BCD_SCRIPT_NAME.desktop" "Browser-Caches to RAM" "Verlagert Browser-Cache-Ordner auf die RAM Disk und passt die Standard-Ordner je nach Existenz der RAM-Ordner entsprechend an" "$THE_BCD_SCRIPT_FILE" "browser"
                if [ $? -eq 0 ];
                then
                  # 3. Skript starten
                  THE_EVAL_ACTION="$THE_BCD_SCRIPT_FILE \"$USER_USERNAME\" -quiet"
                  { eval "$THE_EVAL_ACTION" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                  if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                    e_and_l " $HINWEIS_TAG: Diese Funktion wird erst nach der nächsten Anmeldung aktiv. Darüber"
                    e_and_l " hinaus müssen die betroffenen Browser bis dahin bereits jeweils mindestens"
                    e_and_l " einmal gestartet worden sein, damit deren zu ändernde Konfiguration existiert."
                    CHANGES_MADE=1
                  else
                    e_and_l "$ERROR_TAG $LINENO"
                    add_full_log
                  fi
                else
                  e_and_l "$ERROR_TAG $LINENO"
                  add_full_log
                fi
              else
                restore_backup_file "$THE_BCD_SCRIPT_FILE"
                e_and_l "$ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l "$ERROR_TAG $LINENO"
              add_full_log
            fi
          else
            e_and_l "$ERROR_TAG $LINENO"
            remove_file "$LOCAL_DOWNLOAD_FILE"
            add_full_log
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "ab $BROWSER_CACHE_MIN_SIZE MB RDisk")"
      fi
    else
      e_and_l "$ACTION_MESSAGE ... $NC_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NR_TXT")"
  fi

  # ============================================================================
  # WiFi-Geschwindigkeit für Intel-Chipsatz erhöhen
  # ============================================================================
  ACTION_MESSAGE=" Erhöhung des ${light_cyan}WiFi-Datendurchsatzes${colors_off} (Intel)"
  if [ $(lsmod | grep -i -c -E "^iwlwifi") -ne 0 ];
  then
    WLAN_CONF_FILE="/etc/modprobe.d/iwlwifi-speed.conf"
    WLAN_CONF_TEXT="options iwlwifi 11n_disable=8"
    if [ -s "$WLAN_CONF_FILE" ] &&
       [ $(grep -i -c -E "$WLAN_CONF_TEXT" "$WLAN_CONF_FILE" 2>/dev/null) -gt 0 ];
    then
      e_and_l "$ACTION_MESSAGE ... $NC_TAG"
    else
      ask_yes_or_no_plus "wifi_speed_up" "$ACTION_MESSAGE" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
        create_backup_file "$WLAN_CONF_FILE"
        echo "$WLAN_CONF_TEXT" >> "$WLAN_CONF_FILE" 2>/dev/null
        modprobe -r iwlwifi &>/dev/null
        modprobe iwlwifi &>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l " $OK_TAG"
          CHANGES_MADE=1
          remove_double_empty_lines "$WLAN_CONF_FILE"
        else
          e_and_l "$ERROR_TAG"
          remove_file "$WLAN_CONF_FILE"
          restore_backup_file "$WLAN_CONF_FILE"
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NV_TXT")"
  fi

  # ============================================================================
  # Stabilisierung des WLAN-Durchsatzes durch Ausschalten des Power-Management
  # ============================================================================
  ACTION_MESSAGE=" Stabilisierung des ${light_cyan}WiFi-Datendurchsatzes${colors_off}"
  WLAN_CONF_FILE="/etc/NetworkManager/conf.d/default-wifi-powersave-on.conf"
  if [ -s "$WLAN_CONF_FILE" ];
  then
    if [ $(grep -i -c -E "wifi.powersave\s*=\s*2" "$WLAN_CONF_FILE" 2>/dev/null) -gt 0 ];
    then
      e_and_l "$ACTION_MESSAGE   ... $NC_TAG"
    else
      ask_yes_or_no_plus "wifi_powersave" "$ACTION_MESSAGE" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}  "
        create_backup_file "$WLAN_CONF_FILE"
        sed -i -E "s/wifi\.powersave\s*\=\s*[0-9]*/wifi.powersave = 2/gi" "$WLAN_CONF_FILE"
        if [ $? -eq 0 ];
        then
          e_and_l " ... $OK_TAG"
          CHANGES_MADE=1
        else
          e_and_l " ... $ERROR_TAG $LINENO"
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NA_TXT")"
  fi

  # ============================================================================
  # Flackern der WiFi-LED bei Netzwerk-Traffik ausschalten
  # ============================================================================
  ACTION_MESSAGE=" Traffikflackern der ${light_cyan}WiFi-LED${colors_off} ausschalten"
  if [ $(lsmod | grep -i -c -E "^iwlwifi") -ne 0 ];
  then
    WLAN_CONF_FILE="/etc/modprobe.d/wlan.conf"
    WLAN_CONF_TEXT="options iwlwifi led_mode=1"
    if [ -s "$WLAN_CONF_FILE" ] &&
       [ $(grep -i -c -E "$WLAN_CONF_TEXT" "$WLAN_CONF_FILE" 2>/dev/null) -gt 0 ];
    then
      e_and_l "$ACTION_MESSAGE   ... $NC_TAG"
    else
      ask_yes_or_no_plus "wifi_led" "$ACTION_MESSAGE" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}   ... "
        create_backup_file "$WLAN_CONF_FILE"
        echo "$WLAN_CONF_TEXT" >> "$WLAN_CONF_FILE" 2>/dev/null
        modprobe -r iwlwifi &>/dev/null
        modprobe iwlwifi &>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          CHANGES_MADE=1
          remove_double_empty_lines "$WLAN_CONF_FILE"
        else
          e_and_l "$ERROR_TAG"
          remove_file "$WLAN_CONF_FILE"
          restore_backup_file "$WLAN_CONF_FILE"
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NV_TXT")"
  fi

  # ============================================================================
  # Fehlerberichte deaktivieren
  # ============================================================================
  ACTION_MESSAGE=" Deaktivierung der ${light_cyan}Fehlerbericht-Erstellung${colors_off}"
  # Wenn es apport oder whoopsie gibt
  if [ $(apt list "apport" 2>/dev/null | grep -i -c -E "apport") -gt 0 ] ||
     [ $(apt list "whoopsie" 2>/dev/null | grep -i -c -E "whoopsie") -gt 0 ];
  then
    APPORT_INSTALL_STATUS=$(LANG=C dpkg-query -W -f='${Status}' "apport" 2>/dev/null | grep -i -c -E "ok installed")
    WHOOPSIE_INSTALL_STATUS=$(LANG=C dpkg-query -W -f='${Status}' "whoopsie" 2>/dev/null | grep -i -c -E "ok installed")
    # Wenn apport oder whoopsie installiert sind, diese deinstallieren
    if [ $APPORT_INSTALL_STATUS -gt 0 ] ||
       [ $WHOOPSIE_INSTALL_STATUS -gt 0 ];
    then
      ask_yes_or_no_plus "apport_deactivate_full" " Erstellung von ${light_cyan}Fehlerberichten${colors_off} komplett deaktivieren" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l " Ok, die Module zur ${light_yellow}Fehlerbericht-Erstellung${colors_off} werden jetzt entfernt."
        e_and_l "$HALF_MINUS_LINE"
        if [ $APPORT_INSTALL_STATUS -gt 0 ];
        then
          INST_STATUS=1
          remove_pkg apport 0
          e_and_l "$HALF_MINUS_LINE"
        fi
        if [ $WHOOPSIE_INSTALL_STATUS -gt 0 ];
        then
          INST_STATUS=1
          remove_pkg whoopsie 0
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        # Wenn die System-Fehlerberichte nicht komplett deaktiviert werden sollen,
        # fragen ob nur die Sendung der Berichte unterbunden werden soll ...
        ACTION_MESSAGE=" Ausschalten der ${light_cyan}Sendung der Fehlerberichte${colors_off} ... "
        APPORT_FILE="/etc/default/apport"
        if [ -s "$APPORT_FILE" ];
        then
          APPORT_FILE_STATUS=$(grep -i -c -E "^\s*enabled\s*=\s*0" "$APPORT_FILE")
          APPORT_SERVICE_STATUS=$(LANG=C systemctl is-enabled apport 2>/dev/null | grep -i -c -E "^\s*disabled")
          if [ $APPORT_FILE_STATUS -eq 0 ] ||
             [ $APPORT_SERVICE_STATUS -eq 0 ];
          then
            ask_yes_or_no_plus "apport_deactivate" " Sendung der ${light_cyan}Fehlerberichte${colors_off} ausschalten" "" "n"
            if [ $? -eq 1 ];
            then
              e_and_l -n "${ACTION_MESSAGE//96m/93m}"
              # 1. Datei
              APPORT_FILE_RESULT=0
              if [ $APPORT_FILE_STATUS -eq 0 ];
              then
                create_backup_file "$APPORT_FILE"
                sed -i "s/enabled=1/enabled=0/gi" "$APPORT_FILE"
                APPORT_FILE_RESULT=$?
              fi
              # 2. Service
              APPORT_SERVICE_RESULT=0
              if [ $APPORT_SERVICE_STATUS -eq 0 ];
              then
                systemctl stop apport &>"$LOG_TEMP"
                systemctl disable apport &>"$LOG_TEMP"
                APPORT_SERVICE_RESULT=$?
              fi
              # Ergebnis
              if [ $APPORT_FILE_RESULT -eq 0 ] &&
                 [ $APPORT_SERVICE_RESULT -eq 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG"
                add_full_log
              fi
              e_and_l "$HALF_MINUS_LINE"
            fi
          else
            e_and_l "$ACTION_MESSAGE$NC_TAG"
          fi
        fi
      fi
    else # (wenn es apport oder whoopsie gibt, aber beide nicht installiert sind)
      e_and_l "$ACTION_MESSAGE ... $NC_TAG"
    fi
  else # (wenn es überhaupt kein apport und auch kein whoopsie gibt)
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NV_TXT")"
  fi

  # ============================================================================
  # Anzahl und Größe der System-Log-Dateien begrenzen
  # ============================================================================
  ANZ_LOG_DAYS=5   # Tage
  MAX_LOG_SIZE=100 # MB
  # ----------------------
  ACTION_MESSAGE=" Begrenzung gespeicherter ${light_cyan}System-Logdateien${colors_off} ... "
  VALUE_MESSAGE="$ANZ_LOG_DAYS Tage und $MAX_LOG_SIZE MB"
  SYSLOG_CFG_FILE="/etc/systemd/journald.conf"
  if [ -s "$SYSLOG_CFG_FILE" ];
  then
    if [ $(grep -i -c -E "^\s*SystemMaxFiles\s*=\s*${ANZ_LOG_DAYS}d" "$SYSLOG_CFG_FILE") -eq 0 ] ||
       [ $(grep -i -c -E "^\s*SystemMaxFileSize\s*=\s*${MAX_LOG_SIZE}M" "$SYSLOG_CFG_FILE") -eq 0 ] ||
       [ $(grep -i -c -E "^\s*SystemMaxUse\s*=\s*${MAX_LOG_SIZE}M" "$SYSLOG_CFG_FILE") -eq 0 ];
    then
      ask_yes_or_no_plus "system_log_limit" " Speicherplatz für ${light_cyan}System-Logdateien${colors_off} begrenzen" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}"
        create_backup_file "$SYSLOG_CFG_FILE"
        # Neue Werte sofort setzen
        journalctl --vacuum-time="${ANZ_LOG_DAYS}d" &>/dev/null
        journalctl --vacuum-size="${MAX_LOG_SIZE}M" &>/dev/null
        # Neue Werte permanent einstellen
        sed -i "s/^#*\s*SystemMaxFiles\s*=\s*[0-9]*[a-zA-Z]*/SystemMaxFiles=${ANZ_LOG_DAYS}d/gi" "$SYSLOG_CFG_FILE"
        sed -i "s/^#*\s*SystemMaxFileSize\s*=\s*[0-9]*[a-zA-Z]*/SystemMaxFileSize=${MAX_LOG_SIZE}M/gi" "$SYSLOG_CFG_FILE"
        sed -i "s/^#*\s*SystemMaxUse\s*=\s*[0-9]*[a-zA-Z]*/SystemMaxUse=${MAX_LOG_SIZE}M/gi" "$SYSLOG_CFG_FILE"
        # Log-Dienst mit geänderter Konfiguration neu starten
        service systemd-journald restart &>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG ${light_yellow}(NEU: $VALUE_MESSAGE)${colors_off}"
          CHANGES_MADE=1
        else
          e_and_l "$ERROR_TAG"
          add_full_log
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE$OK_TAG ${dark_gray}(Wert: $VALUE_MESSAGE)${colors_off}"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  # ============================================================================
  # Erhöhung der initramfs-Kompressions-Rate
  # ============================================================================
  ACTION_MESSAGE=" Erhöhung der ${light_cyan}initramfs-Kompressions-Rate${colors_off}  "
  IRFS_CONF_FILE="/etc/initramfs-tools/initramfs.conf"
  if [ -s "$IRFS_CONF_FILE" ];
  then
    if [ $(grep -i -c -E "^\s*COMPRESS\s*=" "$IRFS_CONF_FILE") -ne 0 ];
    then
      IRFS_COMP=$(grep -i -E "^\s*COMPRESS\s*=" "$IRFS_CONF_FILE" | sed -E "s/^\s*COMPRESS\s*=\s*//i")
      if [ "$IRFS_COMP" != "xz" ] &&
         [ "$IRFS_COMP" != "zstd" ];
      then
        e_and_l " Die aktuelle Kompressions-Methode des initramfs ist nur ${bold_white}$IRFS_COMP${colors_off}."
        ask_yes_or_no_plus "compress_initramfs" " Soll die ${light_cyan}Kompressions-Rate${colors_off} mit Methode ${bold_white}xz${colors_off} erhöht werden" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l " $ACHTUNG_TAG: Dieser Vorgang verändert wichtige Boot-Dateien und sollte nur nach"
          e_and_l " einem vollständigen System-Backup durchgeführt werden! Soll jetzt wirklich die"
          e_and_l -n " Kompressions-Methode des initramfs geändert werden? [Bestätigung mit ${bold_yellow}ja${colors_off}]: "
          read -r CONFIRM_TEXT
          if [ "$CONFIRM_TEXT" == "ja" ] ||
             [ "$CONFIRM_TEXT" == "JA" ];
          then
            e_and_l " $USER_CHOICE_YES"
            create_backup_file "$IRFS_CONF_FILE"
            e_and_l -n "${ACTION_MESSAGE//96m/93m}"
            sed -i -E "s/^\s*COMPRESS\s*=\s*[0-9a-zA-Z]*\s*$/COMPRESS=xz/gi" "$IRFS_CONF_FILE"
            if [ $? -eq 0 ];
            then
              e_and_l " ... $OK_TAG"
              e_and_l " Erneuerung des ${light_yellow}initramfs${colors_off} ... bitte warten!"
              update-initramfs -u -k all
              if [ $? -eq 0 ];
              then
                CHANGES_MADE=1
              fi
            else
              e_and_l " ... $ERROR_TAG $LINENO"
            fi
          else
            e_and_l " $USER_CHOICE_NO"
          fi
        fi
        # e_and_l "$HALF_MINUS_LINE"
      else # Schon optimiert
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else # Kein COMPRESS-Eintrag
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else # Keine initramfs.conf
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Raspberry Pi${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Taktfrequenzen des Raspberry Pi einstellen
  # ============================================================================
  ACTION_MESSAGE=" Taktfrequenzen des Raspberry Pi einstellen"
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    PI_CONF_FILE="/boot/firmware/config.txt" # Debian
    if [ ! -s "$PI_CONF_FILE" ];
    then
      PI_CONF_FILE="/boot/config.txt" # Pi OS
    fi
    if [ -s "$PI_CONF_FILE" ];
    then
      if [ $(grep -i -c -E "\[pi$PI_MODELL\]" "$PI_CONF_FILE") -eq 0 ];
      then
        echo -e $'\n'"[pi$PI_MODELL]" >> "$PI_CONF_FILE" 2>/dev/null
      fi
      pi_perfname=('Standard' 'Advanced' 'Maxspeed')
      if [ "$PI_MODELL" == "4" ];
      then
        pi_arm_freq=('1500'     '1750'     '2000')
        pi_gpu_freq=('500'      '600'      '750' )
        pi_overvolt=('0'        '3'        '6'   )
      fi
      if [ "$PI_MODELL" == "5" ];
      then
        pi_arm_freq=('2400'     '2700'     '3000')
        pi_gpu_freq=('800'      '950'      '1100')
        pi_overvolt=('0'        '3'        '6'   )
      fi
      CURRENT_ARM_FREQ="$(grep -i -E "^\s*arm_freq\s*=" "$PI_CONF_FILE" | cut -d"=" -f 2 | xargs)"
      CURRENT_GPU_FREQ="$(grep -i -E "^\s*gpu_freq\s*=" "$PI_CONF_FILE" | cut -d"=" -f 2 | xargs)"
      CURRENT_OVERVOLT="$(grep -i -E "^\s*over_voltage\s*=" "$PI_CONF_FILE" | cut -d"=" -f 2 | xargs)"
      CURRENT_PI_PERFNAME="Standard" # Standard, wenn nichts anderes konfiguriert ist
      if [ "$CURRENT_ARM_FREQ" != "" ];
      then
        i=0
        for cpu_freq in ${pi_arm_freq[@]};
        do
          if [ $CURRENT_ARM_FREQ -ge $cpu_freq ];
          then
            CURRENT_PI_PERFNAME=${pi_perfname[$i]}
          fi
          ((i+=1))
        done
      fi
      e_and_l " Die aktuellen ${light_cyan}Taktfrequenzen${colors_off} dieses Pi sind auf Profil ${light_yellow}$CURRENT_PI_PERFNAME${colors_off} eingestellt."
      ask_yes_or_no_plus "raspi_performance" " Sollen die Taktfreqenzen geändert werden" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l " Bitte neues Performance-Profil auswählen"
        p=0
        for perfname in ${pi_perfname[@]};
        do
          e_and_l -n " [${bold_yellow}$p${colors_off}] ${bold_white}$perfname${colors_off} "
          # ((ANZ_SPACES=$p*2))
          # insert_spaces $ANZ_SPACES
          e_and_l "(CPU ${pi_arm_freq[$p]} MHz, GPU ${pi_gpu_freq[$p]} MHz, Over-Voltage ${pi_overvolt[$p]} V)"
          ((p+=1))
        done
        setterm -cursor off 2>/dev/null
        NEW_PERF_MODE=-1
        MAX_NEW_MODE=${#pi_perfname[@]}
        ((MAX_NEW_MODE-=1))
        while [ $NEW_PERF_MODE -lt 0 ] ||
              [ $NEW_PERF_MODE -gt $MAX_NEW_MODE ];
        do
          read -N 1 -r -s NEW_PERF_MODE
          NEW_PERF_MODE=$(echo $NEW_PERF_MODE | sed 's/[^0-9]*//g')
          if [ "$NEW_PERF_MODE" == "" ]; then NEW_PERF_MODE=-1; fi
        done
        setterm -cursor on 2>/dev/null

        if [ "${pi_perfname[$NEW_PERF_MODE]}" != "$CURRENT_PI_PERFNAME" ];
        then
          e_and_l "$HALF_MINUS_LINE"
          if [ $NEW_PERF_MODE -gt 0 ];
          then
            e_and_l " $ACHTUNG_TAG: Die Erhöhung der Taktfrequenzen kann zu einer Beschädigung der CPU"
            e_and_l " und anderer Komponenten des Rechners führen, wenn diese nicht zusätzlich"
            e_and_l " hinreichend gekühlt werden! Wir lehnen daher jegliche Verantwortung für die"
            e_and_l " Nutzung dieser Option vollständig ab!"
            e_and_l "$HALF_MINUS_LINE"
          fi
          ask_yes_or_no_plus "" " Taktfrequenzen wirklich auf das Profil ${light_yellow}${pi_perfname[$NEW_PERF_MODE]}${colors_off} umstellen" "" "n"
          if [ $? -eq 1 ];
          then
            SED_ERROR_CODE_1=0
            SED_ERROR_CODE_2=0
            SED_ERROR_CODE_3=0
            e_and_l -n " OK, ändere Einstellung der ${light_yellow}Taktfrequenzen${colors_off}  ... "
            create_backup_file "$PI_CONF_FILE"
            # ------------------------------------------------------------------
            # 1. Zur Vermeidung und Bereinigung eventuell redundanter Eintragungen
            #    alle bestehenden Einträge deaktivieren (auskommentieren)
            # ------------------------------------------------------------------
            sed -i -E "s/(^\s*arm_freq\s*=)/\# \1/gi" "$PI_CONF_FILE" 2>/dev/null
            sed -i -E "s/(^\s*gpu_freq\s*=)/\# \1/gi" "$PI_CONF_FILE" 2>/dev/null
            sed -i -E "s/(^\s*over_voltage\s*=)/\# \1/gi" "$PI_CONF_FILE" 2>/dev/null
            # ------------------------------------------------------------------
            # 2. Neue Werte durch die Re-Aktivierung passender (falls vorhanden)
            #    oder das Hinzufügen neuer Eintragungen einstellen
            #    NEU: Wenn Standard ausgewählt, keine neunen Einträge bzw. neue
            #         Einträge nur bei individuellen Einstellungen erstellen.
            # ------------------------------------------------------------------
            if [ $NEW_PERF_MODE -gt 0 ];
            then
              PI_CONF_NEWLINE=$'\n'
              # --------
              # 2.1 CPU
              # --------
              NEW_ARM_FREQ=${pi_arm_freq[$NEW_PERF_MODE]}
              if [ $(grep -i -c -E "^\s*#\s*arm_freq\s*=\s*$NEW_ARM_FREQ" "$PI_CONF_FILE") -gt 0 ];
              then
                sed -i -E "s/^\s*#\s*arm_freq\s*=\s*$NEW_ARM_FREQ/arm_freq=$NEW_ARM_FREQ/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_2=$?
              else
                sed -i -E "s/\[pi$PI_MODELL\]/[pi$PI_MODELL]\\${PI_CONF_NEWLINE}arm_freq=$NEW_ARM_FREQ/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_2=$?
              fi
              # --------
              # 2.2 GPU
              # --------
              NEW_GPU_FREQ=${pi_gpu_freq[$NEW_PERF_MODE]}
              if [ $(grep -i -c -E "^\s*#\s*gpu_freq\s*=\s*$NEW_GPU_FREQ" "$PI_CONF_FILE") -gt 0 ];
              then
                sed -i -E "s/^\s*#\s*gpu_freq\s*=\s*$NEW_GPU_FREQ/gpu_freq=$NEW_GPU_FREQ/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_1=$?
              else
                sed -i -E "s/\[pi$PI_MODELL\]/[pi$PI_MODELL]\\${PI_CONF_NEWLINE}gpu_freq=$NEW_GPU_FREQ/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_1=$?
              fi
              # ---------
              # 2.3 VOLT
              # ---------
              NEW_OVERVOLT=${pi_overvolt[$NEW_PERF_MODE]}
              if [ $(grep -i -c -E "^\s*#\s*over_voltage\s*=\s*$NEW_OVERVOLT" "$PI_CONF_FILE") -gt 0 ];
              then
                sed -i -E "s/^\s*#\s*over_voltage\s*=\s*$NEW_OVERVOLT/over_voltage=$NEW_OVERVOLT/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_3=$?
              else
                sed -i -E "s/\[pi$PI_MODELL\]/[pi$PI_MODELL]\\${PI_CONF_NEWLINE}over_voltage=$NEW_OVERVOLT/gi" "$PI_CONF_FILE" 2>/dev/null
                SED_ERROR_CODE_3=$?
              fi
            fi
            # -----------------------------------------------------------------
            if [ $SED_ERROR_CODE_1 -eq 0 ] &&
               [ $SED_ERROR_CODE_2 -eq 0 ] &&
               [ $SED_ERROR_CODE_3 -eq 0 ];
            then
              e_and_l "$OK_TAG"
              e_and_l "$REBOOT_MSG"
              CHANGES_MADE=1
              remove_double_empty_lines "$PI_CONF_FILE"
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
        else
          e_and_l " Das Profil ${light_yellow}${pi_perfname[$NEW_PERF_MODE]}${colors_off} ist bereits aktiv - es erfolgt keine Änderung."
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else # Keine config.txt
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NFPI45_TXT")"
  fi

  # ============================================================================
  # Optimierung des Raspberry Pi GPU-Speichers
  # ============================================================================
  # >2GB MEM => gpu_mem=128
  # >4GB MEM => gpu_mem=256
  ACTION_MESSAGE=" Optimierung des Raspberry Pi ${light_cyan}GPU-Speichers${colors_off} ... "
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    PI_CONF_FILE="/boot/firmware/config.txt" # Debian
    if [ ! -s "$PI_CONF_FILE" ];
    then
      PI_CONF_FILE="/boot/config.txt" # Pi OS
    fi
    if [ -s "$PI_CONF_FILE" ];
    then
      TWO_GIGABYTES=$((2 * 1024 * 1024 * 1024))
      FOUR_GIGABYTES=$((4 * 1024 * 1024 * 1024))
      NEW_MEM_SIZE=0
      if [ $MEMORY_TOTAL -gt $TWO_GIGABYTES ]; then NEW_MEM_SIZE=128; fi
      if [ $MEMORY_TOTAL -gt $FOUR_GIGABYTES ]; then NEW_MEM_SIZE=256; fi
      VALUE_MESSAGE="$NEW_MEM_SIZE MB"
      if [ $NEW_MEM_SIZE -ne 0 ];
      then
        if [ $(grep -i -c -E "^\s*gpu_mem\s*=\s*$NEW_MEM_SIZE" "$PI_CONF_FILE") -eq 0 ];
        then
          ask_yes_or_no_plus "raspi_gpu_mem" " Soll der ${light_cyan}GPU-Speicher${colors_off} optimiert werden" "" "n"
          if [ $? -eq 1 ];
          then
            create_backup_file "$PI_CONF_FILE"
            e_and_l -n "$ACTION_MESSAGE"
            # Wenn ein Eintrag vorhanden ist, diesen ändern ...
            if [ $(grep -i -c -E "^\s*gpu_mem\s*=\s*" "$PI_CONF_FILE") -gt 0 ];
            then
              sed -i -E "s/^\s*gpu_mem\s*=\s*[0-9]*/gpu_mem=$NEW_MEM_SIZE/gi" "$PI_CONF_FILE" 2>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG ${light_yellow}(NEU: $VALUE_MESSAGE)${colors_off}"
                e_and_l "$REBOOT_MSG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG $LINENO"
              fi
            else # ... sonst einen neuen Eintrag hinzufügen
              echo -e $'\n'"gpu_mem=$NEW_MEM_SIZE" >> "$PI_CONF_FILE" 2>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG ${light_yellow}(NEU: $VALUE_MESSAGE)${colors_off}"
                e_and_l "$REBOOT_MSG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG $LINENO"
              fi
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l -n "$ACTION_MESSAGE"
          e_and_l "$OK_TAG ${dark_gray}(Wert: $NEW_MEM_SIZE MB)${colors_off}"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "erst über 2GB RAM")"
      fi
    else # Keine config.txt
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NFPI45_TXT")"
  fi

  # ============================================================================
  # Einstellung einer sicheren Boot-Screen-Auflösung (1024x768)
  # ============================================================================
  ACTION_MESSAGE=" Einstellung ${light_cyan}sicherer Boot-Screen-Auflösung${colors_off}"
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    PI_CMD_FILE="/boot/firmware/cmdline.txt"
    if [ -s "$PI_CMD_FILE" ];
    then
      SECURE_VIDEO_PART="video=HDMI-A-1:1024x768@60D"
      if [ $(grep -i -c -E "$SECURE_VIDEO_PART" "$PI_CMD_FILE" 2>/dev/null) -eq 0 ];
      then
        ask_yes_or_no_plus "" " Sichere ${light_cyan}Auflösung für Boot-Screen${colors_off} (1024x768) aktivieren" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
          create_backup_file "$PI_CMD_FILE"
          # Wenn ein aktiver Eintrag vorhanden ist, diesen ändern ...
          # Achtung: "-" zum Schluss
          if [ $(grep -i -c -E "\svideo=[A-Z0-9\:\x\@\-]*" "$PI_CMD_FILE" 2>/dev/null) -gt 0 ];
          then
            sed -i -E "s/\svideo=[A-Z0-9\:\x\@\-]*/ $SECURE_VIDEO_PART/gi" "$PI_CMD_FILE" &>/dev/null
            CMD_RESULT=$?
          # ... sonst hinzufügen ...
          else
            echo -n $(cat "$PI_CMD_FILE" | tr -d '\n') > "$PI_CMD_FILE.tmp" 2>/dev/null
            echo " $SECURE_VIDEO_PART" >> "$PI_CMD_FILE.tmp" 2>/dev/null
            mv -f "$PI_CMD_FILE.tmp" "$PI_CMD_FILE" 2>/dev/null
            CMD_RESULT=$?
          fi
          if [ $CMD_RESULT -eq 0 ];
          then
            e_and_l "$OK_TAG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
      else
        ask_yes_or_no_plus "" " Sichere ${light_cyan}Auflösung für Boot-Screen${colors_off} (1024x768) entfernen" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
          create_backup_file "$PI_CMD_FILE"
          sed -i -E "s/\svideo\=HDMI\-A\-1\:1024x768\@60D/ /gi" "$PI_CMD_FILE" &>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NFPI45_TXT")"
  fi

  # ============================================================================
  # Deaktivierung des internen Screen Blanking
  # ============================================================================
  ACTION_MESSAGE=" Deaktivierung des internen ${light_cyan}Screen Blanking${colors_off}"
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    e_and_l -n "$ACTION_MESSAGE ... "
    PI_X_CONF_DIR="/etc/X11/xorg.conf.d"
    PI_X_CONF_FILE="$PI_X_CONF_DIR/10-blanking.conf"
    # Wenn es die X-Konfig-Datei noch nicht gibt, dann diese neu anlegen
    if [ ! -f "$PI_X_CONF_FILE" ];
    then
      if [ ! -d "$PI_X_CONF_DIR" ];
      then
        mkdir -p "$PI_X_CONF_DIR" &>/dev/null
      fi
      if [ -d "$PI_X_CONF_DIR" ];
      then
        echo -e "Section \"ServerLayout\"" > "$PI_X_CONF_FILE"
        if [ $? -eq 0 ];
        then
          echo -e "  Identifier \"ServerLayout0\"" >> "$PI_X_CONF_FILE"
          echo -e "  Option \"BlankTime\" \"0\"" >> "$PI_X_CONF_FILE"
          echo -e "EndSection" >> "$PI_X_CONF_FILE"
          e_and_l "$OK_TAG"
          e_and_l "$REBOOT_MSG"
          CHANGES_MADE=1
        else
          e_and_l "$ERROR_TAG $LINENO"
        fi
      else
        e_and_l "$ERROR_TAG $LINENO"
      fi
    else
      if [ $(grep -i -c -E "BlankTime\"*\s*\s\"*0" "$PI_X_CONF_FILE" 2>/dev/null) -gt 0 ];
      then
        e_and_l "$NC_TAG"
      else
        e_and_l "$ERROR_TAG (manuelle Konfiguration)"
      fi
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NFPI45_TXT")"
  fi

  # ============================================================================
  # Änderung der Monitor-Overscan-Einstellung
  # ============================================================================
  ACTION_MESSAGE=" Änderung der Einstellung ${light_cyan}Monitor-Overscan${colors_off}"
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    PI_CONF_FILE="/boot/firmware/config.txt" # Debian
    if [ ! -s "$PI_CONF_FILE" ];
    then
      PI_CONF_FILE="/boot/config.txt" # Pi OS
    fi
    if [ -s "$PI_CONF_FILE" ];
    then
      ask_yes_or_no_plus "" " Einstellung für ${light_cyan}Monitor-Overscan${colors_off} ändern" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}  ... "
        create_backup_file "$PI_CONF_FILE"
        # Wenn ein aktiver Eintrag vorhanden ist, diesen ändern ...
        if [ $(grep -i -c -E "^\s*disable_overscan\s*\=" "$PI_CONF_FILE" 2>/dev/null) -gt 0 ];
        then
          CURRENT_OVERSCAN="$(grep -i -E "^\s*disable_overscan\s*\=" "$PI_CONF_FILE" | cut -d"=" -f 2 | xargs)"
          if [ "$CURRENT_OVERSCAN" == "1" ];
          then
            NEW_OVERSCAN="0"
          else
            NEW_OVERSCAN="1"
          fi
          sed -i -E "s/^\s*disable_overscan\s*\=\s*[0-9]*/disable_overscan=$NEW_OVERSCAN/gi" "$PI_CONF_FILE" &>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
            e_and_l "$REBOOT_MSG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
          fi
        else # ... wenn kein aktiver Eintrag existiert, einen hinzufügen
          echo -e $'\n'"disable_overscan=1" >> "$PI_CONF_FILE" 2>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
            e_and_l "$REBOOT_MSG"
            CHANGES_MADE=1
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else # Keine Config-Datei
      e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE " "$NFPI45_TXT")"
  fi

  # ============================================================================
  # Aktivierung des Sudo-Passwortes
  # ============================================================================
  ACTION_MESSAGE=" Aktivierung des ${light_cyan}Sudo-Passwort${colors_off} für Benutzer"
  if [ $IS_RASPBERRY_PI -gt 0 ];
  then
    if [ -s "$PI_NOPASS_FILE" ];
    then
      if [ $(cat "$PI_NOPASS_FILE" | grep -i -c -E "^\s*$USER_USERNAME.*NOPASSWD\:\s*ALL") -gt 0 ];
      then
        e_and_l " Das ${light_cyan}Sudo-Passwort${colors_off} für diesen Benutzer ist deaktiviert."
        ask_yes_or_no_plus "" " Sudo-Passwort für ${bold_white}$USER_USERNAME${colors_off} aktivieren" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
          create_backup_file "$PI_NOPASS_FILE"
          sed -i -E "s/^\s*($USER_USERNAME.*NOPASSWD\:\s*ALL)/# \1/gi" "$PI_NOPASS_FILE" 2>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
            e_and_l "$REBOOT_MSG"
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NFPI45_TXT")"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Anmeldung (Login über Desktop)${colors_off}"
  e_and_l "$HALF_LINE"

  if [ $DESKTOP_INSTALLED -eq 0 ];
  then

    e_and_l "$NO_DESKTOP_INFO"
    e_and_l -n "${dark_gray}"
    e_and_l " - Deaktivierung der automatischen Anmeldung"
    e_and_l " - Bei Anmeldung Liste der Benutzer anzeigen"
    e_and_l " - Aktuellen Benutzer als Vorauswahl eintragen"
    e_and_l " - Deaktivierung der Anmeldung mit Gastzugang"
    e_and_l " - Automatisch Nummernblock einschalten"
    e_and_l " - Hintergrundbild des Anmeldebildschirms"
    e_and_l -n "${colors_off}"

  else

    # ==========================================================================
    # Für die Einstellungen zur Anmeldung am Desktop des LightDM prüfen ob die
    # Datei lightdm.conf existiert und diese ggf. erstellen oder erweitern
    # ==========================================================================
    if [ -d "$LDM_CONF_DIR" ];
    then
      # ------------------------------------------------------------------------
      # Wenn es schon eine Konfigurations-Datei gibt, diese vervollständigen ...
      # ------------------------------------------------------------------------
      LDM_CONF_FILE="$LDM_CONF_DIR/lightdm.conf"
      if [ -s "$LDM_CONF_FILE" ] &&
        [ $(grep -i -c -E "\[Seat" "$LDM_CONF_FILE" 2>/dev/null) -gt 0 ];
      then
        # -----------------------------------
        # Fehlende Default-Einträge ergänzen
        # -----------------------------------
        if [ $(grep -i -c -E "^#*\s*autologin-guest\s*=" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ];
        then
          echo -e "autologin-guest=false" >> "$LDM_CONF_FILE" 2>/dev/null
        fi
        if [ $(grep -i -c -E "^#*\s*autologin-user\s*=" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ];
        then
          echo -e "#autologin-user=" >> "$LDM_CONF_FILE" 2>/dev/null
        fi
        if [ $(grep -i -c -E "^#*\s*autologin-user-timeout\s*=" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ];
        then
          echo -e "autologin-user-timeout=0" >> "$LDM_CONF_FILE" 2>/dev/null
        fi
        if [ $(grep -i -c -E "^#*\s*allow-guest\s*=" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ];
        then
          echo -e "allow-guest=true" >> "$LDM_CONF_FILE" 2>/dev/null
        fi
        remove_double_empty_lines "$LDM_CONF_FILE"
      # -------------------------------
      # ... sonst komplett neu anlegen
      # -------------------------------
      else
# START ---------------------------
cat > "$LDM_CONF_FILE" <<EOF
[Seat:*]
autologin-guest=false
autologin-user=
autologin-user-timeout=0
allow-guest=true
EOF
# ENDE ---------------------------
    fi
  fi

    # ==========================================================================
    # Deaktivierung der automatischen Anmeldung
    # ==========================================================================
    ACTION_MESSAGE=" Deaktivierung der ${light_cyan}automatischen Anmeldung${colors_off} "
    if [ -s "$LDM_CONF_FILE" ] ||
       [ -s "$GDM_CCONF_FILE" ];
    then
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        declare -A AUTO_LOGIN_CFILE_LIST
        declare -A AUTO_LOGIN_IS_OK_LIST
        declare -A AUTO_LOGIN_WRONG_LIST
        AUTO_LOGIN_CFILE_LIST[0]="$LDM_CONF_FILE"
        AUTO_LOGIN_IS_OK_LIST[0]="#autologin-user="
        AUTO_LOGIN_WRONG_LIST[0]="^\s*autologin-user\s*=\s*[0-9a-z]+"
        AUTO_LOGIN_CFILE_LIST[1]="$GDM_CCONF_FILE"
        AUTO_LOGIN_IS_OK_LIST[1]="AutomaticLoginEnable=False"
        AUTO_LOGIN_WRONG_LIST[1]="^\s*AutomaticLoginEnable\s*=\s*True"
        # ----------------------------------------------------------------------
        # Prüfen ob es falsche Einträge (mit automatischer Anmeldung) gibt
        # und zugehörigen Benutzernamen extrahieren
        # ----------------------------------------------------------------------
        AUTO_LOGIN_FOUND=0
        AUTO_LOGIN_USER_NAME=""
        for ((i = 0; i < ${#AUTO_LOGIN_CFILE_LIST[@]}; i++));
        do
          AUTO_LOGIN_CFILE=${AUTO_LOGIN_CFILE_LIST[$i]}
          AUTO_LOGIN_IS_OK=${AUTO_LOGIN_IS_OK_LIST[$i]}
          AUTO_LOGIN_WRONG=${AUTO_LOGIN_WRONG_LIST[$i]}
          if [ -s "$AUTO_LOGIN_CFILE" ];
          then
            if [ $(grep -i -c -E "$AUTO_LOGIN_WRONG" "$AUTO_LOGIN_CFILE" 2>/dev/null) -gt 0 ];
            then
              if [ "$AUTO_LOGIN_CFILE" == "$LDM_CONF_FILE" ];
              then
                AUTO_LOGIN_USER_NAME=$(grep -i -E "$AUTO_LOGIN_WRONG" "$AUTO_LOGIN_CFILE" 2>/dev/null | cut -d"=" -f 2 | xargs 2>/dev/null)
              fi
              if [ "$AUTO_LOGIN_CFILE" == "$GDM_CCONF_FILE" ];
              then
                AUTO_LOGIN_USER_NAME=$(grep -i -E "^\s*AutomaticLogin\s*=" "$AUTO_LOGIN_CFILE" 2>/dev/null | cut -d"=" -f 2 | xargs 2>/dev/null)
              fi
              ((AUTO_LOGIN_FOUND+=1))
            fi
          fi
        done
        # ----------------------------------------------------------------------
        # Änderungen durchführen
        # ----------------------------------------------------------------------
        if [ $AUTO_LOGIN_FOUND -ne 0 ];
        then
          e_and_l -n " $WARN_TAG: Der Benutzer"
          if [ "$AUTO_LOGIN_USER_NAME" != "" ];
          then
            e_and_l -n " ${light_cyan}$AUTO_LOGIN_USER_NAME${colors_off}"
          fi
          e_and_l " wird automatisch am System angemeldet!"
          ask_yes_or_no_plus "login_deactivate_auto_login" " Soll die ${light_cyan}automatische Anmeldung${colors_off} deaktiviert werden" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
            create_backup_file "$AUTO_LOGIN_CFILE"
            ENTRIES_TOTAL=0
            ENTRIES_CHANGED=0
            ENTRIES_OK=0
            ENTRIES_FAIL=0
            for ((i = 0; i < ${#AUTO_LOGIN_CFILE_LIST[@]}; i++));
            do
              AUTO_LOGIN_CFILE=${AUTO_LOGIN_CFILE_LIST[$i]}
              AUTO_LOGIN_IS_OK=${AUTO_LOGIN_IS_OK_LIST[$i]}
              AUTO_LOGIN_WRONG=${AUTO_LOGIN_WRONG_LIST[$i]}
              if [ -s "$AUTO_LOGIN_CFILE" ];
              then
                ((ENTRIES_TOTAL+=1))
                if [ $(grep -i -c -E "$AUTO_LOGIN_WRONG" "$AUTO_LOGIN_CFILE" 2>/dev/null) -gt 0 ];
                then
                  sed -i -E "s/$AUTO_LOGIN_WRONG/$AUTO_LOGIN_IS_OK/gi" "$AUTO_LOGIN_CFILE"
                  if [ $? -eq 0 ];
                  then
                    ((ENTRIES_CHANGED+=1))
                    CHANGES_MADE=1
                  else
                    ((ENTRIES_FAIL+=1))
                  fi
                else
                  ((ENTRIES_OK+=1))
                fi
              fi
            done
            if [ $ENTRIES_FAIL -gt 0 ];
            then
              e_and_l "$ERROR_TAG"
            else
              e_and_l "$OK_TAG"
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NAPIOSDESK_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "nur LDM und GDM")"
    fi

    # ==========================================================================
    # Bei Anmeldung Liste der Benutzer anzeigen
    # ==========================================================================
    ACTION_MESSAGE=" Bei Anmeldung ${light_cyan}Liste der Benutzer${colors_off} anzeigen"
    if [ -s "$LDM_CONF_FILE" ] ||
       [ -s "$GDM_DCONF_FILE" ];
    then
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        declare -A SHOW_USER_CFILE_LIST
        declare -A SHOW_USER_IS_OK_LIST
        declare -A SHOW_USER_WRONG_LIST
        SHOW_USER_CFILE_LIST[0]="$LDM_CONF_FILE"
        SHOW_USER_IS_OK_LIST[0]="greeter-hide-users=false"
        SHOW_USER_WRONG_LIST[0]="^\s*#*\s*greeter-hide-users\s*=\s*(true|false)*$"
        SHOW_USER_CFILE_LIST[1]="$GDM_DCONF_FILE"
        SHOW_USER_IS_OK_LIST[1]="disable-user-list=false"
        SHOW_USER_WRONG_LIST[1]="^\s*#*\s*disable-user-list\s*=\s*(true|false)*$"
        # ----------------------------------------------------------------------
        # Prüfen, welche Eintragungen es zur Anzeige der Benutzerliste gibt
        # ----------------------------------------------------------------------
        IS_OK_USER_LIST_FOUND=0
        TOTAL_USER_LIST_FOUND=0
        for ((i = 0; i < ${#SHOW_USER_CFILE_LIST[@]}; i++));
        do
          SHOW_USER_CFILE=${SHOW_USER_CFILE_LIST[$i]}
          SHOW_USER_IS_OK=${SHOW_USER_IS_OK_LIST[$i]}
          SHOW_USER_WRONG=${SHOW_USER_WRONG_LIST[$i]}
          if [ -s "$SHOW_USER_CFILE" ];
          then
            FOUND=$(grep -c -i -E "$SHOW_USER_IS_OK" "$SHOW_USER_CFILE")
            ((IS_OK_USER_LIST_FOUND+=$FOUND))
            FOUND=$(grep -c -i -E "$SHOW_USER_WRONG" "$SHOW_USER_CFILE")
            ((TOTAL_USER_LIST_FOUND+=$FOUND))
          fi
        done
        # ----------------------------------------------------------------------
        # Falls erforderlich Änderungen durchführen
        # ----------------------------------------------------------------------
        if [ $TOTAL_USER_LIST_FOUND -gt 0 ];
        then
          if [ $IS_OK_USER_LIST_FOUND -ne $TOTAL_USER_LIST_FOUND ];
          then
            ask_yes_or_no_plus "login_user_list" "$ACTION_MESSAGE" "" "n"
            if [ $? -eq 1 ];
            then
              e_and_l -n "${ACTION_MESSAGE//96m/93m}  ... "
              ENTRIES_CHANGED=0
              for ((i = 0; i < ${#SHOW_USER_CFILE_LIST[@]}; i++));
              do
                SHOW_USER_CFILE=${SHOW_USER_CFILE_LIST[$i]}
                SHOW_USER_IS_OK=${SHOW_USER_IS_OK_LIST[$i]}
                SHOW_USER_WRONG=${SHOW_USER_WRONG_LIST[$i]}
                if [ -s "$SHOW_USER_CFILE" ];
                then
                  create_backup_file "$SHOW_USER_CFILE"
                  # ---------------------------------------
                  # 1. ALLE betroffenen Einträge maskieren
                  # ---------------------------------------
                  sed -i -E "s/$SHOW_USER_WRONG/THIS_IS_A_LISSY_LINE_TO_CHANGE/gi" "$SHOW_USER_CFILE" 2>/dev/null
                  # --------------------------------------------
                  # 2. Nur den ersten maskierten Eintrag ändern
                  # --------------------------------------------
                  sed -i -z -E "s/THIS_IS_A_LISSY_LINE_TO_CHANGE/$SHOW_USER_IS_OK/" "$SHOW_USER_CFILE" 2>/dev/null
                  # -------------------------------------------------
                  # 3. Alle verbliebenen maskierten Einträge löschen
                  # -------------------------------------------------
                  sed -i -E "s/THIS_IS_A_LISSY_LINE_TO_CHANGE//g" "$SHOW_USER_CFILE" 2>/dev/null
                  if [ $? -eq 0 ];
                  then
                    ((ENTRIES_CHANGED+=1))
                    remove_double_empty_lines "$SHOW_USER_CFILE"
                  fi
                fi
              done
              if [ $ENTRIES_CHANGED -gt 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG"
              fi
              e_and_l "$HALF_MINUS_LINE"
            fi
          else
            e_and_l "$ACTION_MESSAGE  ... $NC_TAG"
          fi
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE " "$NAPIOSDESK_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE " "nur LDM und GDM")"
    fi

    # ==========================================================================
    # Aktuellen Benutzer in Vorauswahl eintragen
    # ==========================================================================
    ACTION_MESSAGE=" Aktuellen ${light_cyan}Benutzer in Vorauswahl${colors_off} eintragen"
    if [ -s "$LDM_CONF_FILE" ];
    then
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        if [ $(grep -i -c -E "^\s*greeter\-hide\-users\s*=\s*false" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ] ||
           [ $(grep -i -c -E "^\s*user\-session\s*=\s*$USER_USERNAME" "$LDM_CONF_FILE" 2>/dev/null) -eq 0 ];
        then
          e_and_l "$HALF_MINUS_LINE"
          ask_yes_or_no_plus "login_user_preset" " Soll ${bold_white}$USER_USERNAME${colors_off} als ${light_cyan}Vorauswahl${colors_off} eingetragen werden" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
            create_backup_file "$LDM_CONF_FILE"
            sed -i -E "s/^\s*\#*\s*greeter\-hide\-users\s*=.*$/greeter-hide-users=false/gi" "$LDM_CONF_FILE"
            sed -i -E "s/^\s*\#*\s*user\-session\s*=.*$/user-session=$USER_USERNAME/gi" "$LDM_CONF_FILE"
            if [ $? -eq 0 ];
            then
              # ----------------------------------------------------------------
              # Zur Sicherheit auch automatische Anmeldung als Gast deaktivieren
              # ----------------------------------------------------------------
              THE_BAD_LINE=$(grep -i -E "^\s*autologin-guest\s*=\s*true" "$LDM_CONF_FILE" 2>/dev/null)
              if [ "$THE_BAD_LINE" != "" ];
              then
                sed -i -E "s/$THE_BAD_LINE/autologin-guest=false/gi" "$LDM_CONF_FILE"
              fi
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NAPIOSDESK_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "nur mit LightDM")"
    fi

    # ==========================================================================
    # Anmeldung mit Gastzugang deaktivieren
    # ==========================================================================
    ACTION_MESSAGE=" Deaktivierung der ${light_cyan}Anmeldung mit Gastzugang${colors_off}"
    if [ -s "$LDM_CONF_FILE" ];
    then
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        THE_GUESTUSER_LINE="^\s*allow-guest\s*=\s*true"
        if [ $(grep -i -c -E "$THE_GUESTUSER_LINE" "$LDM_CONF_FILE" 2>/dev/null) -gt 0 ];
        then
          THE_BAD_LINE=$(grep -i -E "$THE_GUESTUSER_LINE" "$LDM_CONF_FILE" 2>/dev/null)
          e_and_l "$HALF_MINUS_LINE"
          e_and_l " $WARN_TAG: Die Anmeldung enthält einen ${light_cyan}Gastzugang${colors_off}."
          ask_yes_or_no_plus "login_no_guest" " Soll die ${light_cyan}Anmeldung als Gast${colors_off} deaktiviert werden" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n "${ACTION_MESSAGE//96m/93m} ... "
            create_backup_file "$LDM_CONF_FILE"
            sed -i -E "s/$THE_BAD_LINE/allow-guest=false/gi" "$LDM_CONF_FILE"
            if [ $? -eq 0 ];
            then
              # ----------------------------------------------------------------
              # Zur Sicherheit auch automatische Anmeldung als Gast deaktivieren
              # ----------------------------------------------------------------
              THE_BAD_LINE=$(grep -i -E "^\s*autologin-guest\s*=\s*true" "$LDM_CONF_FILE" 2>/dev/null)
              if [ "$THE_BAD_LINE" != "" ];
              then
                sed -i -E "s/$THE_BAD_LINE/autologin-guest=false/gi" "$LDM_CONF_FILE"
              fi
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        else
          e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NAPIOSDESK_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "nur mit LightDM")"
    fi

    # ==========================================================================
    # Bei der Anmeldung Nummernblock aktivieren
    # ==========================================================================
    ACTION_MESSAGE=" Bei der Anmeldung ${light_cyan}Nummernblock${colors_off} einschalten"
    TEMP_MSG="$ACTION_MESSAGE ... "
    NUMLOCK_INSTALL_STATUS=0
    ASKED_NUMLOCKX_INST_NO=0
    if [ -d "$LDM_CONF_DIR" ];
    then
      if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
      then
        # ------------------------------------------------------------------------
        # numlockx installieren (sofern nicht bereits vorher passiert)
        # ------------------------------------------------------------------------
        if [ $(apt list "numlockx" 2>/dev/null | grep -i -c -E "numlockx") -gt 0 ];
        then
          if [ $(LANG=C dpkg-query -W -f='${Status}' "numlockx" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
          then
            ask_yes_or_no_plus "login_numlock" " Zur Aktivierung des Nummernblocks ${light_cyan}numlockx${colors_off} installieren" "" "n"
            if [ $? -eq 1 ];
            then
              e_and_l -n " Installiere ${light_yellow}numlockx${colors_off}, bitte warten         "
              apt install "numlockx" -y &>"$LOG_TEMP"
              NUMLOCK_INSTALL_STATUS=$?
              if [ $NUMLOCK_INSTALL_STATUS -eq 0 ];
              then
                e_and_l "... $OK_TAG"
              else
                e_and_l "... $ERROR_TAG"
                add_full_log
              fi
            else
              ASKED_NUMLOCKX_INST_NO=1
            fi
          fi
        else
          NUMLOCK_INSTALL_STATUS=1
        fi
        # ------------------------------------------------------------------------
        # Nur weitermachen, wenn numlockx installiert ist
        # ------------------------------------------------------------------------
        if [ $NUMLOCK_INSTALL_STATUS -eq 0 ];
        then
          # ----------------------------------------------------------------------
          # Relevante Einträge der jeweiligen Konfigurationsdateien
          # ----------------------------------------------------------------------
          declare -A NUMLOCK_CFILE_LIST
          declare -A NUMLOCK_IS_OK_LIST
          declare -A NUMLOCK_WRONG_LIST
          NUMLOCK_CFILE_LIST[0]="/usr/share/lightdm/lightdm.conf.d/01_debian.conf"
          NUMLOCK_IS_OK_LIST[0]="greeter-setup-script=/usr/bin/numlockx on"
          NUMLOCK_WRONG_LIST[0]="greeter-setup-script=/usr/bin/numlockx off"
          NUMLOCK_CFILE_LIST[1]="/etc/lightdm/slick-greeter.conf"
          NUMLOCK_IS_OK_LIST[1]="activate-numlock=true"
          NUMLOCK_WRONG_LIST[1]="activate-numlock=false"
          NUMLOCK_CFILE_LIST[2]="/usr/share/glib-2.0/schemas/30_ubuntu-mate.gschema.override"
          NUMLOCK_IS_OK_LIST[2]="activate-numlock=true"
          NUMLOCK_WRONG_LIST[2]="activate-numlock=false"
          # ----------------------------------------------------------------------
          # Einträge ändern bzw. neu anlegen - in allen in Frage kommenden Dateien,
          # damit jede Version (insbesondere Linux Mint) "seine" Datei findet ...
          # ----------------------------------------------------------------------
          ENTRIES_TOTAL=0
          ENTRIES_CHANGED=0
          ENTRIES_OK=0
          ENTRIES_FAIL=0
          for ((i = 0; i < ${#NUMLOCK_CFILE_LIST[@]}; i++));
          do
            NUMLOCK_CFILE=${NUMLOCK_CFILE_LIST[$i]}
            NUMLOCK_CFDIR=${NUMLOCK_CFILE%/*}
            NUMLOCK_IS_OK=${NUMLOCK_IS_OK_LIST[$i]}
            NUMLOCK_WRONG=${NUMLOCK_WRONG_LIST[$i]}
            ((ENTRIES_TOTAL+=1))
            # --------------------------------------------------------------------
            # Wenn eine Konfigurations-Datei existiert, diese erweitern
            # --------------------------------------------------------------------
            if [ -s "$NUMLOCK_CFILE" ];
            then
              # -----------------------------------------------------
              # Wenn nur "positive" Einträge existieren ist alles ok
              # -----------------------------------------------------
              if [ $(grep -i -c -E "^\s*$NUMLOCK_IS_OK" "$NUMLOCK_CFILE") -gt 0 ] &&
                [ $(grep -i -c -E "^\s*$NUMLOCK_WRONG" "$NUMLOCK_CFILE") -eq 0 ];
              then
                ((ENTRIES_OK+=1))
              # ------------------------------------------------------------------
              # ... sonst (wenn kein positiver oder negative Einträge existieren)
              # ------------------------------------------------------------------
              else
                create_backup_file "$NUMLOCK_CFILE"
                # -----------------------------------------------
                # Wenn negative Einträge existieren diese ändern
                # -----------------------------------------------
                if [ $(grep -i -c -E "^\s*$NUMLOCK_WRONG" "$NUMLOCK_CFILE") -gt 0 ];
                then
                  THE_WRONG_REG=$(echo ${NUMLOCK_WRONG} | sed 's/\//\\\//g')
                  THE_GOOD_REG=$(echo ${NUMLOCK_IS_OK} | sed 's/\//\\\//g')
                  sed -i "s/^\s*$THE_WRONG_REG/$THE_GOOD_REG/gi" "$NUMLOCK_CFILE" 2>/dev/null
                  if [ $? -eq 0 ];
                  then
                    ((ENTRIES_CHANGED+=1))
                    CHANGES_MADE=1
                  else
                    ((ENTRIES_FAIL+=1))
                  fi
                fi
                # --------------------------------------------------------
                # Wenn kein positiver Eintrag existiert diesen hinzufügen
                # --------------------------------------------------------
                if [ $(grep -i -c -E "^\s*$NUMLOCK_IS_OK" "$NUMLOCK_CFILE") -eq 0 ];
                then
                  # Extrawurst Ubuntu-Mate ...
                  if [ $(echo -e "$NUMLOCK_CFILE" | grep -c -i -E "ubuntu-mate") -gt 0 ];
                  then
                    # ------------------------------------------------------
                    # SED-Option /a fügt eine Zeile hinter dem Match ein ;)
                    # ------------------------------------------------------
                    sed -i -E "/^\s*\[org.ArcticaProject.arctica-greeter\]/a$NUMLOCK_IS_OK" "$NUMLOCK_CFILE" 2>/dev/null
                    glib-compile-schemas /usr/share/glib-2.0/schemas/ &>/dev/null
                  # ---------------------
                  # ... alle anderen ...
                  # ---------------------
                  else
                    echo -e $'\n'"$NUMLOCK_IS_OK" >> "$NUMLOCK_CFILE" 2>/dev/null
                  fi
                  if [ $? -eq 0 ];
                  then
                    ((ENTRIES_CHANGED+=1))
                    CHANGES_MADE=1
                  else
                    ((ENTRIES_FAIL+=1))
                  fi
                fi
                remove_double_empty_lines "$NUMLOCK_CFILE"
                # ----------------------------------------------------------------
              fi
            # ----------------------------------------------------------------
            # .... sonst eine neue Datei anlegen (nur wenn nicht Ubuntu-MATE)
            # ----------------------------------------------------------------
            else
              if [ $(echo -e "$NUMLOCK_CFILE" | grep -c -i -E "ubuntu-mate") -eq 0 ];
              then
                # ----------------------
                # Verzeichnis erstellen
                # ----------------------
                if [ "$NUMLOCK_CFDIR" != "" ] &&
                  [ ! -d "$NUMLOCK_CFDIR" ];
                then
                  mkdir -p "$NUMLOCK_CFDIR" 2>/dev/null
                fi
                # ----------------
                # Datei erstellen
                # ----------------
                CREATE_RESULT=0
                # ---------------------------------------------------------------
                # In Dateien, deren NAME "greeter" enthält, einen entsprechenden
                # Bereich anlegen
                # ---------------------------------------------------------------
                if [ $(echo -e "$NUMLOCK_CFILE" | grep -c -i -E "greeter") -gt 0 ];
                then
                  echo -e "[Greeter]" > "$NUMLOCK_CFILE" 2>/dev/null
                  CREATE_RESULT=$?
                fi
                # ---------------------------------------------------
                # Eintrag selbst in der Konfigurations-Datei anlegen
                # ---------------------------------------------------
                if [ $CREATE_RESULT -eq 0 ];
                then
                  echo -e "$NUMLOCK_IS_OK"$'\n' >> "$NUMLOCK_CFILE" 2>/dev/null
                  if [ $? -eq 0 ];
                  then
                    ((ENTRIES_CHANGED+=1))
                    CHANGES_MADE=1
                  else
                    ((ENTRIES_FAIL+=1))
                  fi
                else
                  ((ENTRIES_FAIL+=1))
                fi
              else
                # Nur um den Zähler zu erhöhen (reserviert für arctica etc.)
                ((ENTRIES_OK+=1))
              fi
            fi
          done
          # ----------------------------------------------------------
          # Je nach Ergebnis und ausgeführter Aktion Meldung ergänzen
          # ----------------------------------------------------------
          if [ $ENTRIES_OK -eq $ENTRIES_TOTAL ];
          then
            TEMP_MSG+="$NC_TAG"
          else
            if [ $ENTRIES_FAIL -gt 0 ];
            then
              TEMP_MSG+="$ERROR_TAG"
            else
              TEMP_MSG+="$OK_TAG"
            fi
            TEMP_MSG+=$'\n'
            TEMP_MSG+="$HALF_MINUS_LINE"
          fi
          # ----------------------------------------------------------

          # ----------------------------------------------------------------------
          # Sicherheitshalber zusätzlich die DCONF-Settings erweitern
          # (dabei keine weitere Ausgabe erzeugen)
          # ----------------------------------------------------------------------
          if [ "$DESKTOP_ENVIRONMENT" == "MATE" ];
          then
            CURRENT_NUMLOCK_SETTING="$(gsettings_get org.mate.peripherals-keyboard numlock-state 2>/dev/null)"
            if [ "$CURRENT_NUMLOCK_SETTING" != "on" ] &&
              [ "$CURRENT_NUMLOCK_SETTING" != "true" ];
            then
              gsettings_set "org.mate.peripherals-keyboard" "remember-numlock-state" "true" 2>/dev/null
              gsettings_set "org.mate.peripherals-keyboard" "numlock-state" "on" 2>/dev/null
              # CHANGES_MADE=1
            fi
          fi
          if [ "$DESKTOP_ENVIRONMENT" == "GNOME" ];
          then
            CURRENT_NUMLOCK_SETTING="$(gsettings_get org.gnome.desktop.peripherals.keyboard numlock-state 2>/dev/null)"
            if [ "$CURRENT_NUMLOCK_SETTING" != "on" ] &&
              [ "$CURRENT_NUMLOCK_SETTING" != "true" ];
            then
              gsettings_set "org.gnome.desktop.peripherals.keyboard" "remember-numlock-state" "true" 2>/dev/null
              gsettings_set "org.gnome.desktop.peripherals.keyboard" "numlock-state" "true" 2>/dev/null
              # CHANGES_MADE=1
            fi
          fi
          # ----------------------------------------------------------------------
          # In neueren Ubuntu-Versionen gibt es zudem folgende Einträge,
          # deren Wirkung jedoch noch nicht zuverlässig verifiziert ist:
          # gsettings_set "org.mate.peripherals-keyboard-xkb.kbd" "options" "['compat\tnumpad:mac']" 2>/dev/null
          # gsettings_set "org.gnome.libgnomekbd.keyboard" "options" "['compat\tnumpad:mac']" 2>/dev/null
          # gsettings_set "org.ArcticaProject.arctica-greeter" "activate-numlock" "true" 2>/dev/null
          # ----------------------------------------------------------------------
        else # numlockx nicht installiert
          TEMP_MSG+="${bold_red}nicht${colors_off} eingerichtet"
        fi
      else
        TEMP_MSG+="übersprungen ($NAPIOSDESK_TXT)"
        TEMP_MSG="$(clear_text "$TEMP_MSG")"
        TEMP_MSG="${dark_gray}$TEMP_MSG${colors_off}"
      fi
    else
      TEMP_MSG+="übersprungen (nur mit LightDM)"
      TEMP_MSG="$(clear_text "$TEMP_MSG")"
      TEMP_MSG="${dark_gray}$TEMP_MSG${colors_off}"
    fi
    if [ $ASKED_NUMLOCKX_INST_NO -eq 0 ];
    then
      e_and_l "$TEMP_MSG"
    fi

    # ==========================================================================
    # Hintergrundbild des Anmeldebildschirms ändern
    # ==========================================================================
    ACTION_MESSAGE=" Hintergrundbild von Anmeldung/Login ändern"
    if [ "$DESKTOP_ENVIRONMENT" != "labwc" ] &&
      [ "$DESKTOP_ENVIRONMENT" != "GNOME" ];
    then
      # ------------------------------------------------------------------------
      # Liste der Dateien, in denen das Hintergrundbild festgelegt sein kann
      # ------------------------------------------------------------------------
      ARCTICA_FILE="/usr/share/glib-2.0/schemas/30_ubuntu-mate.gschema.override"
      LDM_CFILE_LIST="lightdm-gtk-greeter.conf.d/99_linuxmint.conf lightdm-gtk-greeter.conf slick-greeter.conf"
      if [ -s "$ARCTICA_FILE" ] ||
        [ -s "$GDM_DCONF_FILE" ] ||
        [ -d "$LDM_CONF_DIR" ];
      then
        if [ ! -s "$ARCTICA_FILE" ];
        then
          # --------------------------------------------------------------------
          # Aktuelles Hintergrundbild ermitteln
          # --------------------------------------------------------------------
          CURRENT_LOGIN_BG=""
          # --------------------------------
          # Arctica
          # --------
          # Wird derzeit nicht unterstützt
          # --------------------------------
          # if [ -s "$ARCTICA_FILE" ];
          # then
          #   CURRENT_LOGIN_BG=$(grep -i -E "^\s*background\s*=" "$ARCTICA_FILE" | sed -E "s/^\s*background\s*=//" | sort -u | xargs 2>/dev/null)
          # else
            # ------------------------------
            # GDM
            # ------------------------------
            if [ -s "$GDM_DCONF_FILE" ];
            then
              CURRENT_LOGIN_BG=$(grep -i -E "^\s*picture-uri\s*=" "$GDM_DCONF_FILE" | sed -E "s/^\s*picture-uri\s*=//" | sed -E "s/file:\/\///gi" | sort -u | xargs 2>/dev/null)
            else
              # ----------------------------
              # LDM
              # ----------------------------
              for ldm_cfile in ${LDM_CFILE_LIST[@]};
              do
                LDM_GREETER_FILE="$LDM_CONF_DIR/$ldm_cfile"
                if [ -s "$LDM_GREETER_FILE" ] &&
                  [ "$CURRENT_LOGIN_BG" == "" ];
                then
                  CURRENT_LOGIN_BG=$(grep -i -E "^\s*background\s*=" ${LDM_GREETER_FILE} | sed -E "s/^\s*background\s*=//" | sort -u | xargs 2>/dev/null)
                fi
              done
            fi
          # fi
          if [ "$CURRENT_LOGIN_BG" == "" ]; then CURRENT_LOGIN_BG="Standard"; fi
          e_and_l "$HALF_MINUS_LINE"
          e_and_l " ${light_cyan}Hintergrundbild${colors_off}: ${dark_gray}$CURRENT_LOGIN_BG${colors_off}"
          # -------------------
          # Sicherheitsabfrage
          # -------------------
          ask_yes_or_no_plus "login_background" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            # -------------------------------
            # Neues Hintergrundbild eingeben
            # -------------------------------
            THE_NEW_BG_FILE="NONE"
            while [ "$THE_NEW_BG_FILE" == "NONE" ];
            do
              e_and_l -n " Neues Bild: "
              read -r THE_NEW_BG_FILE
              if [ "$THE_NEW_BG_FILE" != "" ] &&
                [[ ! -s "$THE_NEW_BG_FILE" || -d "$THE_NEW_BG_FILE" ]];
              then
                THE_NEW_BG_FILE="NONE"
              fi
            done
            # ------------------------------------------------------------------
            # Hintergrundbild ändern (in allen in Frage kommenden Dateien, damit
            # jede Version (insbesondere Ubuntu und Mint) "seine" Datei findet)
            # ------------------------------------------------------------------
            if [ "$THE_NEW_BG_FILE" != "$CURRENT_LOGIN_BG" ];
            then
              e_and_l -n " Ändere ${light_yellow}Hintergrundbild von Anmeldung/Login${colors_off} ... "
              if [ "$THE_NEW_BG_FILE" != "" ];
              then
                NEW_CFG_LINE="background=$THE_NEW_BG_FILE"
                NEW_URI_LINE="picture-uri='file://$THE_NEW_BG_FILE'"
              else
                NEW_CFG_LINE="# background="
                NEW_URI_LINE="# picture-uri="
              fi
              FOUND_AND_REPLACED=0
              # ----------------------------
              # Arctica
              # --------
              # Wird derzeit nicht unterstützt
              # ----------------------------
              # if [ -s "$ARCTICA_FILE" ];
              # then
              #   create_backup_file "$ARCTICA_FILE"
              #   # Alle aktuellen Vorkommen auskommentieren (deaktivieren)
              #   sed -i -E "s/^\s*background\s*=/# background=/gi" "$ARCTICA_FILE" 2>/dev/null
              #   # SED-Option /a fügt eine Zeile hinter dem Match ein ;)
              #   sed -i -E "/^\s*\[org.ArcticaProject.arctica-greeter\]/a$NEW_CFG_LINE" "$ARCTICA_FILE" 2>/dev/null
              #   if [ $? -eq 0 ];
              #   then
              #     glib-compile-schemas /usr/share/glib-2.0/schemas/ &>/dev/null
              #     ((FOUND_AND_REPLACED+=1))
              #   fi
              # fi
              # ----------------------------
              # GDM
              # ----------------------------
              # Alles richtig gemacht, Ubuntu verweigert aber trotzdem komplett!
              # Selbst Änderungen mit dem dconf-editor werden ignoriert ... :(
              # Der dconf-Pfad ist /com/ubuntu/login-screen/background-picture-uri
              # ----------------------------
              if [ -s "$GDM_DCONF_FILE" ];
              then
                create_backup_file "$GDM_DCONF_FILE"
                # --------------------------------------------------------
                # Alle aktuellen Vorkommen auskommentieren (deaktivieren)
                # --------------------------------------------------------
                sed -i -E "s/^\s*picture-uri\s*=/# picture-uri=/gi" "$GDM_DCONF_FILE" 2>/dev/null
                # --------------------------------------------------------
                # SED-Option /a fügt eine Zeile hinter dem Match ein ;)
                # --------------------------------------------------------
                sed -i -E "/^\s*\[org.gnome.desktop.background\]/a$NEW_URI_LINE" "$GDM_DCONF_FILE" 2>/dev/null
                if [ $? -eq 0 ];
                then
                  # -------------------------------------------------
                  # Zusätzlich noch in der dconf-Datenbank eintragen
                  # -------------------------------------------------
                  gsettings_set "com.ubuntu.login-screen" "background-picture-uri" "file://$THE_NEW_BG_FILE" &>/dev/null
                  gsettings_set "com.ubuntu.login-screen" "background-size" "cover" &>/dev/null
                  dconf update &>/dev/null
                  ((FOUND_AND_REPLACED+=1))
                fi
              fi
              # ------------------------------
              # LDM
              # ------------------------------
              for ldm_cfile in ${LDM_CFILE_LIST[@]};
              do
                LDM_GREETER_FILE="$LDM_CONF_DIR/$ldm_cfile"
                if [ -s "$LDM_GREETER_FILE" ];
                then
                  create_backup_file "$LDM_GREETER_FILE"
                  # --------------------------------------------------------
                  # Alle aktuellen Vorkommen auskommentieren (deaktivieren)
                  # --------------------------------------------------------
                  sed -i -E "s/^\s*background\s*=/# background=/gi" "$LDM_GREETER_FILE" 2>/dev/null
                  # --------------------------------------------------------
                  # SED-Option /a fügt eine Zeile hinter dem Match ein ;)
                  # --------------------------------------------------------
                  sed -i -E "/^\s*\[(G|g)reeter\]/a$NEW_CFG_LINE" "$LDM_GREETER_FILE" 2>/dev/null
                  # ------------------------------------------------------------
                  # Zudem Benutzer-Hintergrundbild auf gleiche Weise deaktivieren
                  # ------------------------------------------------------------
                  sed -i -E "s/^\s*draw-user-backgrounds\s*=/# draw-user-backgrounds=/gi" "$LDM_GREETER_FILE" 2>/dev/null
                  sed -i -E "s/^\s*user-background\s*=/# user-background=/gi" "$LDM_GREETER_FILE" 2>/dev/null
                  NO_USER_BG="draw-user-backgrounds=false"
                  sed -i -E "/^\s*background\s*=/a$NO_USER_BG" "$LDM_GREETER_FILE" 2>/dev/null
                  NO_USER_BG="user-background=false"
                  sed -i -E "/^\s*background\s*=/a$NO_USER_BG" "$LDM_GREETER_FILE" 2>/dev/null
                  if [ $? -eq 0 ]; then ((FOUND_AND_REPLACED+=1)); fi
                fi
              done
              # ------------------------------
              if [ $FOUND_AND_REPLACED -ne 0 ];
              then
                e_and_l "$OK_TAG ${dark_gray}($FOUND_AND_REPLACED)$colors_off"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG"
              fi
            else
              e_and_l " Das ist bereits das Hintergrundbild und wird daher ${bold_white}nicht${colors_off} geändert."
            fi
            # e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$(skip_text "$ACTION_MESSAGE" "nicht in Arctica")"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "nur LDM und GDM")"
      fi
    else
      if [ "$DESKTOP_ENVIRONMENT" == "GNOME" ];
      then
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NG_TXT")"
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE" "$NAPIOSDESK_TXT")"
      fi
    fi
    # ==========================================================================

  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Desktop${colors_off}"
  e_and_l "$HALF_LINE"

  if [ $DESKTOP_INSTALLED -eq 0 ];
  then

    e_and_l "$NO_DESKTOP_INFO"
    e_and_l -n "${dark_gray}"
    e_and_l " - Anzeige der Tastatur-LEDs"
    e_and_l " - Asiatische Schriftarten ausblenden"
    e_and_l " - Sichtbarkeit der Scrollbalken verbessern"
    e_and_l " - Autostart-Programme zugänglich machen"
    e_and_l " - Begrenzung des Thumbnail-Zwischenspeichers"
    e_and_l " - Fehlende Start-Einträge für Wine erstellen"
    e_and_l " - Starter auf dem Desktop ausführbar machen"
    e_and_l -n "${colors_off}"

  else

    # ============================================================================
    # Anzeige der Tastatur-LEDs einschalten
    # ============================================================================
    ACTION_MESSAGE=" Anzeige der ${light_cyan}Tastatur-LEDs${colors_off} einschalten"
    if [ "$DESKTOP_ENVIRONMENT" == "MATE" ];
    then
      if [ $(apt list "libmatekbd-common" 2>/dev/null | grep -i -c -E "libmatekbd-common") -gt 0 ] &&
        [ $(apt list "libmatekbd4" 2>/dev/null | grep -i -c -E "libmatekbd4") -gt 0 ];
      then
        LED_STATUS="$(gsettings_get org.mate.peripherals-keyboard-xkb.general duplicate-leds)"
        if [ "$LED_STATUS" != "true" ];
        then
          ask_yes_or_no_plus "desktop_keyboard_leds" "$ACTION_MESSAGE" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Schalte die Anzeige der ${light_yellow}Tastatur-LEDs${colors_off} ein  ... "
            INSTALL_STATUS=0
            if [ $(LANG=C dpkg-query -W -f='${Status}' "libmatekbd-common" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ] ||
              [ $(LANG=C dpkg-query -W -f='${Status}' "libmatekbd4" 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
            then
              sudo apt install --reinstall libmatekbd-common libmatekbd4 -y &>/dev/null
              INSTALL_STATUS=$?
            fi
            if [ $INSTALL_STATUS -eq 0 ];
            then
              gsettings_set "org.mate.peripherals-keyboard-xkb.general" "duplicate-leds" "true"
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG $LINENO"
              fi
            else
              e_and_l "$ERROR_TAG $LINENO"
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE      ... $NC_TAG"
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE     " "$NV_TXT")"
      fi
    else # kein MATE
      e_and_l "$(skip_text "$ACTION_MESSAGE     " "$NM_TXT")"
    fi

    # ==========================================================================
    # Asiatische Schriftarten ausblenden (nur für den aktuellen Benutzer)
    # ==========================================================================
    ACTION_MESSAGE=" Ausblenden der ${light_cyan}asiatischen Schriftarten${colors_off}    ... "
    FONT_CONF_DIR="$USER_CONFIG_DIR/fontconfig"
    FONT_CFG_FILE="$FONT_CONF_DIR/fonts.conf"
    COPY_FONTS_FILE=0
    DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/cfg/fonts.conf"
    DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
    LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
    wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
    if [ $? -eq 0 ] &&
      [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
      [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
    then
      if [ -s "$FONT_CFG_FILE" ];
      then
        SIZE_NEW_FONTS_FILE=$(stat -c %s "$LOCAL_DOWNLOAD_FILE")
        SIZE_OLD_FONTS_FILE=$(stat -c %s "$FONT_CFG_FILE")
        if [ $SIZE_NEW_FONTS_FILE -ne $SIZE_OLD_FONTS_FILE ];
        then
          COPY_FONTS_FILE=1
        else
          e_and_l "$ACTION_MESSAGE$NC_TAG"
        fi
      else
        COPY_FONTS_FILE=1
      fi
    else
      e_and_l "$ACTION_MESSAGE$ERROR_TAG $LINENO"
      add_full_log
    fi
    if [ $COPY_FONTS_FILE -eq 1 ];
    then
      ask_yes_or_no_plus "desktop_no_asia_fonts" " Sollen ${light_cyan}asiatische Schriftarten${colors_off} ausgeblendet werden" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n "${ACTION_MESSAGE//96m/93m}"
        chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
        if [ ! -d "$FONT_CONF_DIR" ];
        then
          mkdir -p "$FONT_CONF_DIR" &>/dev/null
        fi
        create_backup_file "$FONT_CFG_FILE"
        cp -f "$LOCAL_DOWNLOAD_FILE" "$FONT_CFG_FILE" &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          chown -R "$USER_USERNAME:$USER_USERNAME" "$FONT_CONF_DIR" &>/dev/null
          fc-cache &>/dev/null
          dpkg-reconfigure fontconfig &>/dev/null
          e_and_l "$OK_TAG"
          CHANGES_MADE=1
        else
          restore_backup_file "$FONT_CFG_FILE"
          e_and_l "$ERROR_TAG $LINENO"
          add_full_log
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    fi
    remove_file "$LOCAL_DOWNLOAD_FILE"

    # ==========================================================================
    # Sichtbarkeit der Scrollbalken verbessern (nur für den aktuellen Benutzer)
    # ==========================================================================
    ACTION_MESSAGE=" Sichtbarkeit der ${light_cyan}Scrollbalken${colors_off} verbessern"
    if [ "$DESKTOP_ENVIRONMENT" != "labwc" ];
    then
      GTK3_CONF_DIR="$USER_CONFIG_DIR/gtk-3.0"
      if [ -d "$GTK3_CONF_DIR" ];
      then
        GTK3_CFG_FILE="$GTK3_CONF_DIR/gtk.css"
        SCROLL_CONFIG_OK=0
        # ----------------------------------------------------------------------
        # Wenn es schon eine Konfig-Datei gibt, dann prüfen ob es auch gültige
        # Konfigurations-Einträge darin gibt
        # ----------------------------------------------------------------------
        if [ -s "$GTK3_CFG_FILE" ];
        then
          # ----------------------------------------------------
          # Prüfen ob es den Eintrag "Scrollbar Tweaks" gibt
          # (dann ist die Datei höchstwahrscheinlich von uns ;)
          # ----------------------------------------------------
          if [ $(cat "$GTK3_CFG_FILE" | grep -c -i "Scrollbar Tweaks") -gt 0 ];
          then
            # --------------------------------------------------
            # Prüfen ob es den zum Thema passenden Bereich gibt
            # --------------------------------------------------
            if [[ $(echo "$WINDOW_THEME" | grep -i -c -E "\-Dark") -eq 0 && $(grep -c -i "Light Mode" "$GTK3_CFG_FILE") -gt 0 ]] ||
              [[ $(echo "$WINDOW_THEME" | grep -i -c -E "\-Dark") -gt 0 && $(grep -c -i "Dark Mode" "$GTK3_CFG_FILE") -gt 0 ]];
            then
              SCROLL_CONFIG_OK=1
            fi
          fi
        fi
        # -------------------------------------
        # Passende Konfiguration herunterladen
        # -------------------------------------
        if [ $SCROLL_CONFIG_OK -eq 0 ];
        then
          ask_yes_or_no_plus "desktop_big_scrollbars" "$ACTION_MESSAGE" "" "j"
          if [ $? -eq 1 ];
          then
            e_and_l -n "${ACTION_MESSAGE//96m/93m}   ... "
            if [ $(echo "$WINDOW_THEME" | grep -i -c -E "\-Dark") -gt 0 ];
            then
              DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/cfg/gtk_dark.css"
            else
              DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/cfg/gtk_light.css"
            fi
            DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
            LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
            wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
            if [ $? -eq 0 ] &&
              [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
              [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
              if [ ! -d "$GTK3_CONF_DIR" ];
              then
                mkdir -p "$GTK3_CONF_DIR" &>/dev/null
              fi
              if [ $? -eq 0 ];
              then
                create_backup_file "$GTK3_CFG_FILE"
                cp -f "$LOCAL_DOWNLOAD_FILE" "$GTK3_CFG_FILE" &>"$LOG_TEMP"
                if [ $? -eq 0 ];
                then
                  chown -R "$USER_USERNAME:$USER_USERNAME" "$GTK3_CONF_DIR" &>/dev/null
                  e_and_l "$OK_TAG"
                  CHANGES_MADE=1
                else
                  restore_backup_file "$GTK3_CFG_FILE"
                  e_and_l "$ERROR_TAG $LINENO"
                  add_full_log
                fi
              else
                e_and_l "$ERROR_TAG $LINENO"
                add_full_log
              fi
            else
              e_and_l "$ERROR_TAG $LINENO"
              remove_file "$LOCAL_DOWNLOAD_FILE"
              add_full_log
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        else
          e_and_l "$ACTION_MESSAGE   ... $NC_TAG"
        fi
      else
        e_and_l "$ACTION_MESSAGE   ... $NA_TXT"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE  " "$NAPIOSDESK_TXT")"
    fi

    # ==========================================================================
    # Alle Autostart-Programme zugänglich (sichtbar) machen
    # ==========================================================================
    ACTION_MESSAGE=" Alle ${light_cyan}Autostart-Programme${colors_off} zugänglich machen"
    AUTOSTARTS_DIR="/etc/xdg/autostart"
    if [ -d "$AUTOSTARTS_DIR" ];
    then
      if [ $(grep -l -i -c -E "^\s*NoDisplay\s*=\s*true" "$AUTOSTARTS_DIR"/* | wc -l) -gt 0 ];
      then
        ask_yes_or_no_plus "activate_all_autostart" "$ACTION_MESSAGE" "" "j"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Mache alle ${light_yellow}Autostart-Programme${colors_off} zugänglich  ... "
          if [ ! -d "$AUTOSTARTS_DIR.bak" ];
          then
            mkdir -p "$AUTOSTARTS_DIR.bak" &>/dev/null
          fi
          if [ -d "$AUTOSTARTS_DIR.bak" ];
          then
            cp -n ${AUTOSTARTS_DIR}/* "$AUTOSTARTS_DIR.bak" &>/dev/null
            if [ $? -eq 0 ];
            then
              sed -i "s/^\s*NoDisplay\s*=\s*true/NoDisplay=false/gi" ${AUTOSTARTS_DIR}/*.desktop*
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                e_and_l "$ERROR_TAG $LINENO"
              fi
            else
              e_and_l "$ERROR_TAG $LINENO"
            fi
          else
            e_and_l "$ERROR_TAG $LINENO"
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NF_TXT")"
    fi

    # ==========================================================================
    # Begrenzung des Thumbnail-Zwischenspeichers
    # ==========================================================================
    GS_MAX_AGE=30   # Tage
    GS_MAX_SIZE=100 # MB
    VALUE_MESSAGE="$GS_MAX_AGE Tage und $GS_MAX_SIZE MB"
    GS_G_ERRORS=0
    GS_OLD_G_MAX_AGE=$(gsettings_get org.gnome.desktop.thumbnail-cache maximum-age)
    ((GS_G_ERRORS+=$?))
    GS_OLD_G_MAX_SIZE=$(gsettings_get org.gnome.desktop.thumbnail-cache maximum-size)
    ((GS_G_ERRORS+=$?))
    GS_M_ERRORS=0
    GS_OLD_M_MAX_AGE=$(gsettings_get org.mate.thumbnail-cache maximum-age)
    ((GS_M_ERRORS+=$?))
    GS_OLD_M_MAX_SIZE=$(gsettings_get org.mate.thumbnail-cache maximum-size)
    ((GS_M_ERRORS+=$?))
    ACTION_MESSAGE=" Begrenzung des ${light_cyan}Thumbnail-Zwischenspeichers${colors_off} ... "
    if [ $GS_G_ERRORS -eq 0 ] ||
      [ $GS_M_ERRORS -eq 0 ];
    then
      VALUES_DIFFERENT=0
      if [ $GS_G_ERRORS -eq 0 ];
      then
        if [[ $GS_OLD_G_MAX_AGE -ne $GS_MAX_AGE || $GS_OLD_G_MAX_SIZE -ne $GS_MAX_SIZE ]];
        then
          VALUES_DIFFERENT=1
        fi
      fi
      if [ $GS_M_ERRORS -eq 0 ];
      then
        if [[ $GS_OLD_M_MAX_AGE -ne $GS_MAX_AGE || $GS_OLD_M_MAX_SIZE -ne $GS_MAX_SIZE ]];
        then
          VALUES_DIFFERENT=1
        fi
      fi
      if [ $VALUES_DIFFERENT -eq 1 ];
      then
        ask_yes_or_no_plus "thumbnail_cache_limit" " Speicherplatz für ${light_cyan}Thumbnail-Zwischenspeicher${colors_off} begrenzen" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m}"
          # --------------------------------------------------------------------
          # Wenn es die GNOME-Einträge gibt, dann diese anpassen,
          # ansonsten wird dieser Schritt als OK übersprungen
          # --------------------------------------------------------------------
          GS_G_RESULT=0 # (0 = OK)
          if [ $GS_G_ERRORS -eq 0 ];
          then
            if [ $GS_OLD_G_MAX_AGE -ne $GS_MAX_AGE ] ||
              [ $GS_OLD_G_MAX_SIZE -ne $GS_MAX_SIZE ];
            then
              gsettings_set "org.gnome.desktop.thumbnail-cache" "maximum-age" "$GS_MAX_AGE"
              GS_G_RESULT=$?
              if [ $GS_G_RESULT -eq 0 ];
              then
                gsettings_set "org.gnome.desktop.thumbnail-cache" "maximum-size" "$GS_MAX_SIZE"
                GS_G_RESULT=$?
              fi
            fi
          fi
          # --------------------------------------------------------------------
          # Wenn es die MATE-Einträge gibt, dann diese anpassen,
          # ansonsten wird dieser Schritt als OK übersprungen
          # --------------------------------------------------------------------
          GS_M_RESULT=0 # (0 = OK)
          if [ $GS_M_ERRORS -eq 0 ];
          then
            if [ $GS_OLD_M_MAX_AGE -ne $GS_MAX_AGE ] ||
              [ $GS_OLD_M_MAX_SIZE -ne $GS_MAX_SIZE ];
            then
              gsettings_set "org.mate.thumbnail-cache" "maximum-age" "$GS_MAX_AGE"
              GS_M_RESULT=$?
              if [ $GS_M_RESULT -eq 0 ];
              then
                gsettings_set "org.mate.thumbnail-cache" "maximum-size" "$GS_MAX_SIZE"
                GS_M_RESULT=$?
              fi
            fi
          fi
          # --------------------------------------------------------------------
          if [ $GS_G_RESULT -eq 0 ] &&
            [ $GS_M_RESULT -eq 0 ];
          then
            e_and_l "$OK_TAG ${light_yellow}(NEU: $VALUE_MESSAGE)${colors_off}"
          else
            e_and_l "$ERROR_TAG"
          fi
          # e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$ACTION_MESSAGE$OK_TAG ${dark_gray}(Wert: $VALUE_MESSAGE)${colors_off}"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NF_TXT")"
    fi

    # ==========================================================================
    # Festlegung des X-Terminal-Emulator
    # -----------------------------------
    # Wird so selten benötigt, dass diese Funktion derzeit nicht angeboten wird
    # ==========================================================================
    # if update-alternatives --version &>/dev/null;
    # then
    #   CURRENT_X_TERM="$(LANG=C update-alternatives --display x-terminal-emulator | grep -i -E "current" | awk '{print $5}')"
    #   e_and_l " Der Standard ${light_cyan}X-Terminal-Emulator${colors_off} ist: ${light_blue}$CURRENT_X_TERM${colors_off}"
    #   ask_yes_or_no_plus "change_xterm" " Einen anderen X-Terminal-Emulator als Standard auswählen" "" "n"
    #   if [ $? -eq 1 ];
    #   then
    #     update-alternatives --config x-terminal-emulator
    #   fi
    # else
    #   e_and_l "$(skip_text " Festlegung d. Standard X-Terminal-Emulator" "$NA_TXT")"
    # fi

    # ==========================================================================
    # Erstellung diverser Menü-Einträge (Starter) für Wine
    # ACHTUNG: Bei Änderungen auch "wine_post_inst" anpassen!
    # ==========================================================================
    ACTION_MESSAGE=" Fehlende ${light_cyan}Start-Einträge für Wine${colors_off} erstellen"
    # if [ $(LANG=C dpkg-query -W -f='${Status}' "wine" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
    if [ "$WINE_VERSION_APT" != "" ] ||
      [ "$WINE_VERSION_FLAT" != "" ];
    then
      # ------------------------------------------------------------------------
      # Liste der zu erstellenden Starter zusammenbauen
      # ------------------------------------------------------------------------
      tmp_list=""
      declare -A WINE_STARTER_NAME
      declare -A WINE_STARTER_EXEC
      # ---------------------------------------------
      # Wine installiert aus dem Standard-Repository
      # ---------------------------------------------
      if [ "$WINE_VERSION_APT" != "" ];
      then
        tmp_list+="$WINE_STARTER_LIST_APT";
        WINE_STARTER_NAME[wine-browsedrive]='Laufwerk C:'
        WINE_STARTER_EXEC[wine-browsedrive]='xdg-open .wine/dosdevices/c:'
        WINE_STARTER_NAME[wine-control]='Kontrollpanel'
        WINE_STARTER_EXEC[wine-control]='wine control'
        WINE_STARTER_NAME[wine-explorer]='Windows Explorer'
        WINE_STARTER_EXEC[wine-explorer]='wine explorer'
        WINE_STARTER_NAME[wine-iexplore]='Internet Explorer'
        WINE_STARTER_EXEC[wine-iexplore]='wine iexplore'
        WINE_STARTER_NAME[wine-regedit]='Registry Editor'
        WINE_STARTER_EXEC[wine-regedit]='wine regedit'
        WINE_STARTER_NAME[wine-taskmgr]='Taskmanager'
        WINE_STARTER_EXEC[wine-taskmgr]='wine taskmgr'
        WINE_STARTER_NAME[wine-uninstaller]='Software UnInstaller'
        WINE_STARTER_EXEC[wine-uninstaller]='wine uninstaller'
        WINE_STARTER_NAME[wine-winecfg]='Konfiguration'
        WINE_STARTER_EXEC[wine-winecfg]='winecfg'
        WINE_STARTER_NAME[wine-wineconsole]='Windows Konsole'
        WINE_STARTER_EXEC[wine-wineconsole]='wine wineconsole'
        WINE_STARTER_NAME[wine-winemine]='MineSweeper'
        WINE_STARTER_EXEC[wine-winemine]='wine winemine'
      fi
      # -----------------------------
      # Wine installiert als Flatpak
      # -----------------------------
      if [ "$WINE_VERSION_FLAT" != "" ];
      then
        if [ "$tmp_list" != "" ]; then tmp_list+=" "; fi
        tmp_list+="$WINE_STARTER_LIST_FLAT";
        WINE_STARTER_NAME[wine-winetricks-flatpak]='Winetricks (Flatpak)'
        WINE_STARTER_EXEC[wine-winetricks-flatpak]='flatpak run --command=winetricks org.winehq.Wine'
        WINE_STARTER_NAME[wine-regedit-flatpak]="Registry Editor (Flatpak)"
        WINE_STARTER_EXEC[wine-regedit-flatpak]='flatpak run --command=regedit org.winehq.Wine'
        WINE_STARTER_NAME[wine-winecfg-flatpak]="Konfiguration (Flatpak)"
        WINE_STARTER_EXEC[wine-winecfg-flatpak]='flatpak run --command=winecfg org.winehq.Wine'
        WINE_STARTER_NAME[wine-wineconsole-flatpak]="Windows Konsole (Flatpak)"
        WINE_STARTER_EXEC[wine-wineconsole-flatpak]='flatpak run --command=wineconsole org.winehq.Wine'
        WINE_STARTER_NAME[wine-winemine-flatpak]="MineSweeper (Flatpak)"
        WINE_STARTER_EXEC[wine-winemine-flatpak]='flatpak run --command=winemine org.winehq.Wine'
      fi
      # ---------------------------------------------
      # Prüfen ob schonn alle Starter vorhanden sind
      # ---------------------------------------------
      WINE_STARTER_MISSING=0
      for starter_file in ${tmp_list[@]};
      do
        if [ ! -s "$GLOBAL_STARTER_DIR/$starter_file.desktop" ];
        then
          ((WINE_STARTER_MISSING+=1))
          break
        fi
      done
      # -----------------------------------------
      # Wenn Starter fehlen, diese neu erstellen
      # -----------------------------------------
      if [ $WINE_STARTER_MISSING -gt 0 ];
      then
        e_and_l -n "$ACTION_MESSAGE ... "
        WINE_STARTER_ERRORS=0
        for starter_file in ${tmp_list[@]};
        do
          if [ "$starter_file" != "" ];
          then
            WINE_STARTER_FILE="$GLOBAL_STARTER_DIR/$starter_file.desktop"
            ICON_NAME="${starter_file/-flatpak/}"
            if [ ! -s "$WINE_STARTER_FILE" ];
            then
              echo -e "[Desktop Entry]" > "$WINE_STARTER_FILE" 2>/dev/null
              if [ $? -eq 0 ];
              then
                echo -e "Type=Application" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "Name=Wine ${WINE_STARTER_NAME[$starter_file]}" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "Exec=${WINE_STARTER_EXEC[$starter_file]}" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "Icon=$ICON_NAME" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "Terminal=false" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "StartupNotify=false" >> "$WINE_STARTER_FILE" 2>/dev/null
                echo -e "Categories=Wine;" >> "$WINE_STARTER_FILE" 2>/dev/null
                chown -R "root:root" "$WINE_STARTER_FILE" &>/dev/null
                chmod -R 0644 "$WINE_STARTER_FILE" &>/dev/null
                download_icon_file "$ICON_NAME" 0
                if [ ${OPTION_FLAG[addstart]} -ne 0 ];
                then
                  KAT_SHORT_NAME="${KATEGORIE_TEXT[w]}"
                  copy_starter_to_desktop "$WINE_STARTER_FILE" "" 1
                fi
              else
                ((WINE_STARTER_ERRORS+=1))
              fi
            fi
          fi
        done
        if [ $WINE_STARTER_ERRORS -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi

    # ==========================================================================
    # Alle Starter auf dem Desktop ausführbar machen
    # ==========================================================================
    DESKTOP_STARTER_LIST="$DOWNLOAD_DIR/desktop_starter_list.tmp"
    find "$DESKTOP_DIR" -type f -iregex ".*\.desktop$" 1>"$DESKTOP_STARTER_LIST" 2>/dev/null
    if [ -s "$DESKTOP_STARTER_LIST" ];
    then
      ANZAHL_STARTER=$(cat "$DESKTOP_STARTER_LIST" | wc -l)
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " Es wurden ${bold_yellow}$ANZAHL_STARTER${colors_off} ${light_cyan}Starter${colors_off} auf dem Desktop des Benutzers gefunden."
      STARTER_IN_SUBDIRS=$(cat "$DESKTOP_STARTER_LIST" | grep -E "$DESKTOP_DIR\/.*\/" | wc -l)
      if [ $STARTER_IN_SUBDIRS -gt 0 ];
      then
        e_and_l " Davon sind ${light_yellow}$STARTER_IN_SUBDIRS${colors_off} Starter in Unterordnern enthalten."
        if [ "$DESKTOP_ENVIRONMENT" == "XFCE" ];
        then
          e_and_l " $HINWEIS_TAG: Auf dem XFCE-Desktop werden zu Startern in Unterordnern nicht die"
          e_and_l " Anwendungsnamen sondern nur deren Dateinamen angezeigt. Dies ist ein Manko"
          e_and_l " in XFCE und kann auch mit korrekten Zugriffsrechten nicht geändert werden."
        fi
      fi
      ask_yes_or_no_plus "all_starter_trusted" " Sollen alle Starter ausführbar gemacht werden" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Mache die ${light_yellow}Starter ausführbar${colors_off}, bitte warten ... "
        while read starter_file;
        do
          if [ "$starter_file" != "" ];
          then
            chmod -R 0755 "$starter_file" &>/dev/null
            make_starter_trusted "$starter_file"
          fi
        done < "$DESKTOP_STARTER_LIST"
        e_and_l "$OK_TAG"
      fi
    else
      e_and_l " Alle ${light_cyan}Starter auf Desktop ausführbar${colors_off} machen ... $NF_TAG"
    fi
    remove_file "$DESKTOP_STARTER_LIST"

  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Konsole${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Erweitertes Prompt einrichten (nur für den aktuellen Benutzer)
  # ============================================================================
  SIMPLE_PROMPT="PS1='\${debian_chroot:+(\$debian_chroot)}\\\u@\h:\\\w\\\$ '"
  COLOR_PROMPT="PS1='\${debian_chroot:+(\$debian_chroot)}\\\[\\\033[0;92m\\\]\\\u\\\[\\\033[0;37m\\\]|\\\[\\\033[0;94m\\\]\\\h\\\[\\\033[0;37m\\\]|\\\[\\\033[1;34m\\\]\\\w\\\[\\\033[00m\\\]\\\$ '"
  SUPER_PROMPT1="PS1='\\\n\\\[\\\033[1;30m\\\]┌─\${debian_chroot:+(\$debian_chroot)─}\\\[\\\033[0;92m\\\] \\\u \\\[\\\033[1;30m\\\]|\\\033[0;94m\\\] \\\h \\\[\\\033[1;30m\\\]|\\\[\\\033[1;34m \\\w\\\n\\\[\\\033[1;30m\\\]└─\\\[\\\033[0m\\\] \\\$ '"
  SUPER_PROMPT2="PS1='\\\n\\\[\\\033[1;30m\\\]┌─\${debian_chroot:+(\$debian_chroot)─}(\\\[\\\033[0;92m\\\]\\\u\\\[\\\033[1;30m\\\]@\\\033[0;94m\\\]\\\h\\\[\\\033[1;30m\\\])─[\\\[\\\033[1;34m\\\w\\\[\\\033[1;30m\\\]]\\\n└─\\\[\\\033[0m\\\] \\\$ '"
  USER_BASHRC_FILE="$USER_HOME_DIR/.bashrc"
  ACTION_MESSAGE=" Erweitertes ${light_cyan}Prompt${colors_off} für die Kommandozeile"
  if [ -s "$USER_BASHRC_FILE" ];
  then
    if [ $(grep -c -E "Extended Prompt" "$USER_BASHRC_FILE") -eq 0 ];
    then
      ask_yes_or_no_plus "extended_prompt" "$ACTION_MESSAGE einrichten" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Richte erweitertes ${light_yellow}Konsolen-Prompt${colors_off} ein     ... "
        create_backup_file "$USER_BASHRC_FILE"
        echo -e "" >> "$USER_BASHRC_FILE"
        echo -e "# ----------------"$'\n'"# Extended Prompt"$'\n'"# ----------------" >> "$USER_BASHRC_FILE"
        echo -e "if [ -x /usr/bin/tput ] && tput setaf 1 &>/dev/null;" >>  "$USER_BASHRC_FILE"
        echo -e "then" >>  "$USER_BASHRC_FILE"
        echo -e "  # $COLOR_PROMPT"  >>  "$USER_BASHRC_FILE"
        echo -e "  $SUPER_PROMPT1" >>  "$USER_BASHRC_FILE"
        echo -e "  # $SUPER_PROMPT2" >>  "$USER_BASHRC_FILE"
        echo -e "else" >>  "$USER_BASHRC_FILE"
        echo -e "  $SIMPLE_PROMPT" >>  "$USER_BASHRC_FILE"
        echo -e "fi" >>  "$USER_BASHRC_FILE"
        echo -e "# ----------------" >>  "$USER_BASHRC_FILE"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          CHANGES_MADE=1
          remove_double_empty_lines "$USER_BASHRC_FILE"
        else
          e_and_l "$ERROR_TAG $LINENO"
        fi
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE   ... $NC_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE  " "nur für Bash")"
  fi

  # ============================================================================
  # Erweiterung des Suchpfad für Binär-Dateien (nur für den aktuellen Benutzer)
  # ============================================================================
  ACTION_MESSAGE=" Erweiterung des ${light_cyan}Suchpfad${colors_off} für Binär-Dateien"
  USER_BASHRC_FILE="$USER_HOME_DIR/.bashrc"
  if [ -s "$USER_BASHRC_FILE" ];
  then
    # Suche im aktuellen Pfad beginnen
    THE_NEW_PATH="::"
    # 1. Suche nach eigenen Skripten in ~/bin
    if [ -d "$USER_HOME_DIR/bin" ] &&
       [ $(echo "$ORIGINAL_USER_PATH" | grep -i -c -E "$USER_HOME_DIR\/bin") -eq 0 ];
    then
      THE_NEW_PATH+="$USER_HOME_DIR/bin:"
    fi
    # 2. Suche in ~/.local/bin
    if [ -d "$USER_HOME_DIR/.local/bin" ] &&
       [ $(echo "$ORIGINAL_USER_PATH" | grep -i -c -E "$USER_HOME_DIR\/\.local\/bin") -eq 0 ];
    then
      THE_NEW_PATH+="$USER_HOME_DIR/.local/bin:"
    fi
    # 3. Suche nach Binärdateien in /usr/sbin und /sbin (Standard für sudo)
    if [ -d "/usr/sbin" ] &&
       [ $(echo "$ORIGINAL_USER_PATH" | grep -i -c -E "\:\/usr\/sbin") -eq 0 ];
    then
      THE_NEW_PATH+="/usr/sbin:"
    fi
    if [ -d "/sbin" ] &&
       [ $(echo "$ORIGINAL_USER_PATH" | grep -i -c -E "\:\/sbin") -eq 0 ];
    then
      THE_NEW_PATH+="/sbin:"
    fi
    if [ "$THE_NEW_PATH" != "" ];
    then
      THE_NEW_PATH+="\$PATH"
      if [ $(grep -c -E "^\s*export\s*PATH\s*\=\s*${THE_NEW_PATH/$/\\\$}" "$USER_BASHRC_FILE") -eq 0 ];
      then
        ask_yes_or_no_plus "extended_path" "$ACTION_MESSAGE" "" "j"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Erweitere den ${light_yellow}Suchpfad${colors_off} für Binär-Dateien   ... "
          create_backup_file "$USER_BASHRC_FILE"
          # Wenn es schon einen aktiven PATH-Eintrag gibt, diesen ersetzen ...
          if [ $(grep -c -E "^\s*export\s*PATH\s*\=" "$USER_BASHRC_FILE") -gt 0 ];
          then
            sed -i -E "s/^\s*export\s*PATH\s*\=\s*.*/export PATH=${THE_NEW_PATH//\//\\\/}/gi" "$USER_BASHRC_FILE"
            THE_RESULT=$?
          else
            # ... sonst einen neuen Eintrag anlegen
            echo -e "" >> "$USER_BASHRC_FILE"
            echo -e "# --------------"$'\n'"# Extended Path"$'\n'"# --------------" >> "$USER_BASHRC_FILE"
            echo -e "export PATH=$THE_NEW_PATH" >>  "$USER_BASHRC_FILE"
            echo -e "# --------------" >>  "$USER_BASHRC_FILE"
            THE_RESULT=$?
          fi
          if [ $THE_RESULT -eq 0 ];
          then
            e_and_l "$OK_TAG"
            CHANGES_MADE=1
            remove_double_empty_lines "$USER_BASHRC_FILE"
          else
            e_and_l "$ERROR_TAG $LINENO"
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "nur für Bash")"
  fi

  # ============================================================================
  # Alias Definitionen für Befehle einrichten (für ALLE Benutzer)
  # ============================================================================
  GLOBAL_BASHRC_FILE="/etc/bash.bashrc"
  USER_BASHRC_FILE="$USER_HOME_DIR/.bashrc"
  BASH_ALIAS_FILE="/etc/bash_aliases"
  ACTION_MESSAGE=" Definitionen der ${light_cyan}Befehls-Aliase${colors_off} erweitern"
  if [ -s "$GLOBAL_BASHRC_FILE" ];
  then
    # ------------------------
    # bash_aliases downloaden
    # ------------------------
    DOWNLOAD_FILE_URL="$RESSOURCE_SERVER_DIR/cfg/bash_aliases"
    DOWNLOAD_FILE_NAME="${DOWNLOAD_FILE_URL##*/}"
    LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
    wget -nv -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
    if [ $? -eq 0 ] &&
       [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
       [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
    then
      # ---------------------------------------------------------------------
      # bash_aliases nur ersetzen, wenn die neue Datei eine andere Größe hat
      # bzw. durch kopieren neu anlegen, wenn sie noch nicht existiert
      # ---------------------------------------------------------------------
      COPY_NEW_ALIAS_FILE=0
      if [ -s "$BASH_ALIAS_FILE" ];
      then
        SIZE_NEW_ALIAS_FILE=$(stat -c %s "$LOCAL_DOWNLOAD_FILE")
        SIZE_OLD_ALIAS_FILE=$(stat -c %s "$BASH_ALIAS_FILE")
        if [ $SIZE_NEW_ALIAS_FILE -ne $SIZE_OLD_ALIAS_FILE ];
        then
          COPY_NEW_ALIAS_FILE=1
        fi
      else
        COPY_NEW_ALIAS_FILE=1
      fi
      if [ $COPY_NEW_ALIAS_FILE -eq 1 ];
      then
        ask_yes_or_no_plus "bash_aliases" "$ACTION_MESSAGE" "" "j"
        if [ $? -eq 1 ];
        then
          e_and_l -n " Richte Definitionen der ${light_yellow}Befehls-Aliase${colors_off} ein ... "
          # ----------------------
          # bash_aliases kopieren
          # ----------------------
          create_backup_file "$BASH_ALIAS_FILE"
          cp -f "$LOCAL_DOWNLOAD_FILE" "$BASH_ALIAS_FILE" &>/dev/null
          if [ $? -eq 0 ];
          then
            chmod -R 0644 "$BASH_ALIAS_FILE" &>/dev/null
            # ---------------------------
            # /etc/bash.bashrc erweitern
            # ---------------------------
            if [ $(grep -i -c -E "\/etc\/bash_aliases" "$GLOBAL_BASHRC_FILE") -eq 0 ];
            then
              create_backup_file "$GLOBAL_BASHRC_FILE"
# START ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cat >> "$GLOBAL_BASHRC_FILE" <<EOF

# ------------------
# Alias Definitions
# ------------------
if [ -s /etc/bash_aliases ];
then
  . /etc/bash_aliases
fi
# ------------------
EOF
# ENDE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              if [ $? -eq 0 ];
              then
                # --------------------------------------------------------
                # Aktuelle Aliase des Benutzers in ~/.bashrc deaktivieren
                # --------------------------------------------------------
                create_backup_file "$USER_BASHRC_FILE"
                sed -i "s/# alias l/alias l/gi" "$USER_BASHRC_FILE"
                sed -i "s/alias l/# alias l/gi" "$USER_BASHRC_FILE"
                e_and_l "$OK_TAG"
                CHANGES_MADE=1
              else
                restore_backup_file "$GLOBAL_BASHRC_FILE"
                e_and_l "$ERROR_TAG $LINENO"
              fi
            else
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            fi
          else
            restore_backup_file "$BASH_ALIAS_FILE"
            e_and_l "$ERROR_TAG $LINENO"
          fi
          # e_and_l "$HALF_MINUS_LINE"
        fi
      else
        e_and_l "$ACTION_MESSAGE  ... $NC_TAG"
      fi
    else
      e_and_l "$ACTION_MESSAGE  ... $ERROR_TAG $LINENO"
      add_full_log
    fi
    remove_file "$LOCAL_DOWNLOAD_FILE"
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE " "nur für Bash")"
  fi

  # ============================================================================
  # Hinweis auf Änderungen
  # ============================================================================
  if [ $CHANGES_MADE -gt 0 ];
  then
    e_and_l "$HALF_LINE"
    e_and_l " $HINWEIS_TAG: Einzelne Änderungen werden ev. erst bei der nächsten Anmeldung aktiv"
  fi

  # ============================================================================
  # Durchführung weiterer Festplatten-Optimierungen
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Festplatten-Optimierungen${colors_off}"
  e_and_l "$HALF_LINE"
  # ---------------------------
  # S.M.A.R.T Tools einrichten
  # ---------------------------
  SMART_TOOLS_AVAILABLE=0
  if [ $(LANG=C dpkg-query -W -f='${Status}' smartmontools 2>/dev/null | grep -i -c -E "ok installed") -eq 0 ];
  then
    if [ $(apt list "smartmontools" 2>/dev/null | grep -i -c -E "smartmontools") -gt 0 ];
    then
      e_and_l -n " Installiere ${bold_yellow}smartmontools${colors_off}, bitte warten    "
      apt install smartmontools -y &>"$LOG_TEMP"
      if [ $? -eq 0 ];
      then
        e_and_l "... $OK_TAG"
        SMART_TOOLS_AVAILABLE=1
      else
        e_and_l "... $ERROR_TAG"
      fi
      add_full_log
    fi
  else
    SMART_TOOLS_AVAILABLE=1
  fi
  # ----------------------------
  # Update der Geräte-Datenbank
  # ----------------------------
  if [ $SMART_TOOLS_AVAILABLE -eq 1 ];
  then
    e_and_l -n " Update der ${light_cyan}Geräte-Datenbank${colors_off}, bitte warten  ... "
    update-smart-drivedb &>"$LOG_TEMP"
    if [ $? -eq 0 ];
    then
      e_and_l "$OK_TAG"
    else
      e_and_l "${bold_red}$NA_TXT${colors_off}"
    fi
    add_full_log
  fi
  # -------------------------
  # Liste der Disks erzeugen
  # -------------------------

  NTFS_COUNT=0
  declare -A NTFS_PARTITONS

  THE_DISK_LIST="$DOWNLOAD_DIR/disk-list"
  remove_file "$THE_DISK_LIST"
  LANG=C lsblk -d -o name,rota,type 2>/dev/null | grep -i disk 1>"$THE_DISK_LIST" 2>/dev/null
  if [ -s "$THE_DISK_LIST" ];
  then
    # --------------------------------------------------------------------------
    # Maximale Länge jeder Teil-Zeichenfolge
    # --------------------------------------------------------------------------
    MAX_INFO_LENGTH=62
    # --------------------------------------------------------------------------
    # Für jede gefundene Disk die S.M.A.R.T-Einstellungen und den I/O-Scheduler
    # sowie für SSDs zusätzlich die Ausrichtung prüfen (SMART ggf. aktivieren)
    # --------------------------------------------------------------------------
    while read disk_data;
    do
      # ------------------------------------------------------------------------
      # Informationen zur Disk ermitteln
      # ------------------------------------------------------------------------
      disk_name="$(echo ${disk_data} | awk '{print $1}' | xargs)"
      disk_rota=$(echo ${disk_data} | awk '{print $2}' | xargs)
      DEVICE_NAME="/dev/${disk_name}"
      #-----------------------------------------------------------------------------
      # Ausgeworfene Geräte neu verbinden um alle Informationen auslesen zu können
      #-----------------------------------------------------------------------------
      DEVICE_RECONNECTED=0
      # if [ "${DEVICE_NAME}" != "/dev/$root_partition" ] &&
      if [ "${DEVICE_NAME}" != "$root_partition" ] &&
         [ $(ls -la ${DEVICE_NAME}* 2>/dev/null | wc -l ) -eq 1 ];
      then
        eject -t ${DEVICE_NAME} &>/dev/null
        if [ $? -eq 0 ];
        then
          DEVICE_RECONNECTED=1
        fi
      fi
      # --------------------------------
      # Hersteller (Family / Vendor)
      # --------------------------------
      DISK_FAMILY=""
      # lsblk
      if [ -b ${DEVICE_NAME} ];
      then
        DISK_FAMILY=$(LANG=C lsblk -d -n -o vendor ${DEVICE_NAME} 2>/dev/null | head -n 1 | sed -E "s/[\"\']//g" | xargs 2>/dev/null)
      fi
      # smartctl (1)
      if [ "$DISK_FAMILY" == "" ] || [ "$DISK_FAMILY" == "ATA" ] || [ "$DISK_FAMILY" == "USB" ];
      then
        DISK_FAMILY=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^\s*vendor\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # smartctl (2)
      if [ "$DISK_FAMILY" == "" ] || [ "$DISK_FAMILY" == "ATA" ] || [ "$DISK_FAMILY" == "USB" ];
      then
        DISK_FAMILY=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^s*model\s*family\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # Ausgabe bereinigen
      DISK_FAMILY=$(echo ${DISK_FAMILY//_/ } | sed -E "s/^ATA\s*//" | sed -E "s/^USB\s*//" | xargs 2>/dev/null)
      if [ ${#DISK_FAMILY} -gt $MAX_INFO_LENGTH ]; then DISK_FAMILY=${DISK_FAMILY:0:$MAX_INFO_LENGTH}; fi
      # --------------------------------
      # Bezeichnung (Model)
      # --------------------------------
      DISK_MODEL=""
      # lsblk
      if [ -b ${DEVICE_NAME} ];
      then
        DISK_MODEL=$(LANG=C lsblk -d -n -o model ${DEVICE_NAME} 2>/dev/null | head -n 1 | sed -E "s/[\"\']//g" | xargs 2>/dev/null)
      fi
      # smartctl (1)
      if [ "$DISK_MODEL" == "" ];
      then
        DISK_MODEL=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^\s*device\s*model\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # smartctl (2)
      if [ "$DISK_MODEL" == "" ];
      then
        DISK_MODEL=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^\s*product\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # parted
      if [ "$DISK_MODEL" == "" ];
      then
        DISK_MODEL=$(LANG=C parted -s ${DEVICE_NAME} print 2>/dev/null | grep -i -E "^\s*model\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # udevadm
      if [ "$DISK_MODEL" == "" ];
      then
        if udevadm --version &>/dev/null;
        then
          DISK_MODEL=$(LANG=C udevadm info --name=${DEVICE_NAME} 2>/dev/null | grep -i -E ".*id_model=" | sed -E "s/[\"\']//g" | cut -d"=" -f 2 | xargs 2>/dev/null)
        fi
      fi
      # Ausgabe bereinigen
      DISK_MODEL=$(echo ${DISK_MODEL//_/ } | sed -E "s/^ATA\s*//" | sed -E "s/^USB\s*//" | xargs 2>/dev/null)
      if [ ${#DISK_MODEL} -gt $MAX_INFO_LENGTH ]; then DISK_MODEL=${DISK_MODEL:0:$MAX_INFO_LENGTH}; fi
      # --------------------------------
      # Seriennummer (Serial)
      # --------------------------------
      DISK_SERIAL=""
      # lsblk
      if [ -b ${DEVICE_NAME} ];
      then
        DISK_SERIAL=$(LANG=C lsblk -d -n -o serial ${DEVICE_NAME} 2>/dev/null | head -n 1 | sed -E "s/[\"\']//g" | xargs 2>/dev/null)
      fi
      # smartctl
      if [ ${#DISK_SERIAL} -lt 5 ];
      then
        DISK_SERIAL=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^\s*serial\s*number\s*:" | sed -E "s/[\"\']//g" | cut -d":" -f 2| xargs 2>/dev/null)
      fi
      # udevadm
      if [ ${#DISK_SERIAL} -lt 5 ];
      then
        if udevadm --version &>/dev/null;
        then
          DISK_SERIAL=$(LANG=C udevadm info --name=${DEVICE_NAME} 2>/dev/null | grep -i -E "\s*E:\s*ID_SERIAL_SHORT\s*=" | head -n 1 | sed -E "s/[\"\']//g" | sed -E "s/\s*E:\s*ID_SERIAL_SHORT\s*=//i" | xargs 2>/dev/null)
        fi
      fi
      # Ausgabe bereinigen
      DISK_SERIAL=$(echo ${DISK_SERIAL//_/ } | xargs 2>/dev/null)
      if [ ${#DISK_SERIAL} -gt $MAX_INFO_LENGTH ]; then DISK_SERIAL="~${DISK_SERIAL:(-$MAX_INFO_LENGTH):$MAX_INFO_LENGTH}"; fi
      # --------------------------------
      # Kapazität
      # --------------------------------
      NUMBER_HAS_FORMAT=0
      DISK_CAPACITY=""
      # lsblk
      if [ -b ${DEVICE_NAME} ];
      then
        DISK_CAPACITY=$(LANG=C lsblk -d -n -o size ${DEVICE_NAME} 2>/dev/null | head -n 1 | sed -E "s/[\"\']//g" | xargs 2>/dev/null)
      fi
      # smartctl
      if [ "$DISK_CAPACITY" == "" ];
      then
        DISK_CAPACITY=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "^\s*user\s*capacity\s*:" | sed -E "s/[\"\']//g" | cut -d ":" -f 2 | awk '{print $1}' | sed "s/[^0-9]//g" | xargs 2>/dev/null)
      fi
      # parted
      if [ "$DISK_CAPACITY" == "" ];
      then
        DISK_CAPACITY=$(LANG=C parted -s ${DEVICE_NAME} print 2>/dev/null | grep -i -E "^Disk ${DEVICE_NAME}" | sed -E "s/[\"\']//g" | cut -d":" -f 2 | xargs 2>/dev/null)
      fi
      # Wenn die Ausgabe schon formatiert ist, diese nicht mehr neu formatieren
      if [ $(echo ${DISK_CAPACITY} | grep -c -i -E "[BKMGT]") -gt 0 ]; then NUMBER_HAS_FORMAT=1; fi
      if [ $NUMBER_HAS_FORMAT -eq 0 ] &&
        [ "$DISK_CAPACITY" != "" ];
      then
        DISK_SIZE=$(show_human_bytes ${DISK_CAPACITY} "M")
        if [ ${#DISK_SIZE} -gt 7 ];
        then
          DISK_SIZE=$(show_human_bytes ${DISK_CAPACITY} "G")
        fi
      else
        DISK_SIZE="$DISK_CAPACITY"
      fi
      if [ "$DISK_SIZE" == "0" ] ||
         [ "$DISK_SIZE" == "0B" ];
      then
        DISK_SIZE=""
      fi
      DISK_CAPACITY="$DISK_SIZE"
      # Ausgabe bereinigen
      if [ ${#DISK_CAPACITY} -gt $MAX_INFO_LENGTH ]; then DISK_CAPACITY=${DISK_CAPACITY:0:$MAX_INFO_LENGTH}; fi
      #-----------------------------------------------------------------------------
      # Vormals ausgeworfene und durch uns neu verbundene Geräte wieder auswerfen
      #-----------------------------------------------------------------------------
      if [ $DEVICE_RECONNECTED -eq 1 ];
      then
        eject ${DEVICE_NAME} &>/dev/null
      fi
      # ------------------
      # Start der Ausgabe
      # ------------------
      # disk_name=$(echo ${disk_name:0:8} | xargs)
      e_and_l "$HALF_LINE"
      e_and_l " Prüfe ${bold_white}$DEVICE_NAME${colors_off}"
      if [ "$DISK_FAMILY" != "" ]; then e_and_l " Hersteller:   ${light_cyan}$DISK_FAMILY${colors_off}"; fi
      if [ "$DISK_MODEL"  != "" ]; then e_and_l " Bezeichnung:  ${light_cyan}$DISK_MODEL${colors_off}"; fi
      if [ "$DISK_SERIAL" != "" ]; then e_and_l " Seriennummer: ${light_yellow}$DISK_SERIAL${colors_off}"; fi
      if [ "$DISK_SIZE"   != "" ]; then e_and_l " Kapazität:    ${light_yellow}$DISK_SIZE${colors_off}"; fi
      # ------------------------------------------------------------------------
      # Partitionen
      # ------------------------------------------------------------------------
      THE_PARTITION_LIST="$DOWNLOAD_DIR/partition_list.tmp"
      parted -s -m ${DEVICE_NAME} unit B print 2>/dev/null | awk 'NR>2' > "$THE_PARTITION_LIST"
      if [ -s "$THE_PARTITION_LIST" ];
      then
        e_and_l " Partitionen:"
        e_and_l " ${dark_gray}Nr  Größe     Typ         Mark  Name                Bezeichnung         Align${colors_off}"
        while read partition;
        do
          # ---------------------------------------------------------------------
          # Leere Einträge (::) erweitern, damit "cut" und "awk" richtig trennen
          # ---------------------------------------------------------------------
          partition=${partition/::/:_:}
          # -------
          # Nummer
          # -------
          PARTITION_NR=$(echo $partition | cut -d":" -f 1 | xargs 2>/dev/null)
          if [ $PARTITION_NR -lt 10 ]; then e_and_l -n " "; fi
          e_and_l -n " ${light_cyan}$PARTITION_NR${colors_off}"
          # ------------------------------------
          # Vollständigen Gerätenamen ermitteln
          # ------------------------------------
          FULL_DEVICE_NAME="${DEVICE_NAME}"
          if [ $(echo ${DEVICE_NAME} | grep -c -i -E "(mmcblk|nvme)") -gt 0 ];
          then
            FULL_DEVICE_NAME+="p"
          fi
          FULL_DEVICE_NAME+="$PARTITION_NR"
          # ------------------------
          # NTFS-Partitionen merken
          # ------------------------
          if [ $(echo "$partition" | grep -c -i -E "ntfs") -gt 0 ];
          then
            NTFS_PARTITONS[$NTFS_COUNT]="$FULL_DEVICE_NAME"
            ((NTFS_COUNT+=1))
          fi
          # ------
          # Größe
          # ------
          PART_SIZE_CHARS=8
          PARTITION_SIZE=$(echo $partition | cut -d":" -f 4 | xargs 2>/dev/null)
          PARTITION_SIZE=${PARTITION_SIZE//B/}
          PARTITION_SIZE=$(show_human_bytes ${PARTITION_SIZE})
          PARTITION_SIZE=${PARTITION_SIZE:0:$PART_SIZE_CHARS}
          e_and_l -n "  ${light_yellow}$PARTITION_SIZE${colors_off}"
          ((ANZ_SPACES=$PART_SIZE_CHARS-${#PARTITION_SIZE}))
          insert_spaces $ANZ_SPACES
          # ----
          # Typ
          # ----
          PART_TYPE_CHARS=10
          PARTITION_TYPE=$(echo $partition | cut -d":" -f 5 | xargs 2>/dev/null)
          if [ "$PARTITION_TYPE" == "_" ] ||
            [ "$PARTITION_TYPE" == "primary" ];
          then
            PARTITION_TYPE="unknown"
          fi
          PARTITION_TYPE=${PARTITION_TYPE:0:$PART_TYPE_CHARS}
          e_and_l -n "  ${light_blue}$PARTITION_TYPE${colors_off}"
          ((ANZ_SPACES=$PART_TYPE_CHARS-${#PARTITION_TYPE}))
          insert_spaces $ANZ_SPACES "." "${dark_gray}"
          # -----------
          # Markierung
          # -----------
          PART_MARK_CHARS=4
          PARTITION_MARK=$(echo $partition | cut -d":" -f 7 | sed -E "s/_//gi" | sed -E "s/;//gi" | xargs 2>/dev/null)
          PARTITION_MARK=${PARTITION_MARK:0:$PART_MARK_CHARS}
          e_and_l -n "  ${light_blue}$PARTITION_MARK${colors_off}"
          ((ANZ_SPACES=$PART_MARK_CHARS-${#PARTITION_MARK}))
          insert_spaces $ANZ_SPACES "." "${dark_gray}"
          # -----
          # Name
          # -----
          PART_NAME_CHARS=18
          PARTITION_NAME=$(echo $partition | cut -d":" -f 6 | sed -E "s/_//gi" | xargs 2>/dev/null)
          PARTITION_NAME=${PARTITION_NAME:0:$PART_NAME_CHARS}
          e_and_l -n "  ${light_blue}$PARTITION_NAME${colors_off}"
          ((ANZ_SPACES=$PART_NAME_CHARS-${#PARTITION_NAME}))
          insert_spaces $ANZ_SPACES "." "${dark_gray}"
          # ------------
          # Bezeichnung
          # ------------
          PARTITION_LABEL=""
          PART_LABEL_CHARS=18
          if [ -b ${DEVICE_NAME} ];
          then
            PARTITION_LABEL=$(lsblk -l -n -o label ${FULL_DEVICE_NAME} 2>/dev/null | xargs 2>/dev/null)
          fi;
          PARTITION_LABEL=${PARTITION_LABEL:0:$PART_LABEL_CHARS}
          e_and_l -n "  ${light_blue}$PARTITION_LABEL${colors_off}"
          ((ANZ_SPACES=$PART_LABEL_CHARS-${#PARTITION_LABEL}))
          insert_spaces $ANZ_SPACES "." "${dark_gray}"
          # ------------
          # Ausrichtung
          # ------------
          # if [ $disk_rota -eq 0 ];
          # then
            e_and_l -n "  "
            if [ "$PARTITION_TYPE" != "unknown" ] &&
               [ "$PARTITION_TYPE" != "extended" ];
            then
              PARTITION_DEVICE="${DEVICE_NAME}${PARTITION_NR}"
              if [ ! -e "$PARTITION_DEVICE" ];
              then
                PARTITION_DEVICE="${DEVICE_NAME}p${PARTITION_NR}"
              fi
              if [ -e "$PARTITION_DEVICE" ];
              then
                PARTITION_ALIGNMENT=$(parted ${PARTITION_DEVICE} align-check opt 1 2>"$LOG_TEMP" | awk '{print $1}' | xargs)
                if [ "$PARTITION_ALIGNMENT" != "" ];
                then
                  if [ $PARTITION_ALIGNMENT -eq 1 ];
                  then
                    e_and_l "$OK_TAG"
                  else
                    e_and_l "$ERROR_TAG"
                    add_full_log
                  fi
                else
                  e_and_l "${light_yellow}n.e.${colors_off}"
                fi
              else
                e_and_l "${light_yellow}n.e.${colors_off}"
              fi
            else
              e_and_l "${light_yellow}n.e.${colors_off}"
            fi
          # else
          #   e_and_l "nicht geprüft ${dark_gray}(keine SSD)${colors_off}"
          # fi
        done < "$THE_PARTITION_LIST"
      fi
      remove_file "$THE_PARTITION_LIST"
      e_and_l " Sonstige Parameter:"
      # ------------------------------------------------------------------------
      # S.M.A.R.T
      # ------------------------------------------------------------------------
      e_and_l -n " Einstellung der ${light_cyan}SMART-Überwachung${colors_off} ... Überwachung "
      if [ $(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i support | grep -i -c " available") -gt 0 ];
      then
        # ---------------------
        # S.M.A.R.T aktivieren
        # ---------------------
        if [ $(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i support | grep -i -c " enabled") -eq 0 ];
        then
          smartctl -s on ${DEVICE_NAME} &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "${bold_green}wurde aktiviert${colors_off}"
          else
            e_and_l "$ERROR_TAG"
            add_full_log
          fi
        else
          e_and_l "${bold_green}aktiv${colors_off}"
        fi
        # --------------------------
        # S.M.A.R.T Fehler auslesen
        # --------------------------
        e_and_l -n " Status des ${light_cyan}SMART-Fehlerprotokolls${colors_off} ... Fehlerliste "
        ERROR_LIST=$(LANG=C smartctl -d sat,auto --quietmode=errorsonly --all ${DEVICE_NAME} 2>"$LOG_TEMP")
        if [ "$ERROR_LIST" == "" ];
        then
          e_and_l "${bold_green}leer${colors_off}"
        else
          e_and_l "${bold_yellow}enthält${colors_off} ${bold_red}Warnungen / Fehler${colors_off}"
          do_log "$ERROR_LIST"
          add_full_log
        fi
      else
        e_and_l "${bold_red}$NA_TXT${colors_off}"
      fi
      # ------------------------------------------------------------------------
      # I/O-Scheduler
      # ------------------------------------------------------------------------
      if [ -f "/sys/block/${disk_name}/queue/scheduler" ];
      then
        e_and_l -n " Einstellung des ${light_cyan}I/O-Schedulers${colors_off}    ... "
        if [ $(grep -i -E "mq-deadline" "/sys/block/${disk_name}/queue/scheduler" | grep -i -c -E "none") -gt 0 ];
        then
          e_and_l "QueueConfig $OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
      fi
      # ------------------------------------------------------------------------
      # Laufzeit
      # ------------------------------------------------------------------------
      POH_FROM_SMART=""
      e_and_l -n " Angabe der ${light_cyan}Summe der Laufzeit${colors_off}     ... "
      # 1. Angabe aus dem GP-Logs auslesen
      DISK_POWER_ON=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -E "0x01\s*0x010\s*4" | awk '{print $4}' | xargs)
      # Wenn nicht im GP-Log gefunden den SMART-Wert einlesen
      if [ "$DISK_POWER_ON" == "" ];
      then
        DISK_POWER_ON=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i -E "Power_On_Hours" | awk '{print $8}' | xargs)
        POH_FROM_SMART=" (SMART)"
      fi
      # 2. Angabe des Zeitstempels auslesen und formatieren
      DISK_TIMESTAMP=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i timestamp | awk '{print $4}' | xargs)
      if [ "$DISK_TIMESTAMP" != "" ];
      then
        DISK_TIMESTAMP=$((DISK_TIMESTAMP / 1000)) # Timestamp ist in 1000stel Sekunden gespeichert
      else
        if [ "$DISK_POWER_ON" != "" ];
        then
          DISK_TIMESTAMP=$((DISK_POWER_ON * 60 * 60)) # Stunden in Sekunden umrechnen
        else
          DISK_TIMESTAMP=""
        fi
      fi
      DISK_UPTIME=$(time_to_string $DISK_TIMESTAMP true false)
      e_and_l -n "${light_yellow}$DISK_UPTIME${colors_off}"
      if [ "$DISK_POWER_ON" != "" ];
      then
        if [ "$DISK_TIMESTAMP" != "" ]; then e_and_l -n " / "; fi
        e_and_l -n "${light_yellow}~ ${DISK_POWER_ON} Stunden${dark_gray}$POH_FROM_SMART${colors_off}"
      fi
      e_and_l ""
      # ------------------------------------------------------------------------
      # Anzahl geschriebene Bytes
      # ------------------------------------------------------------------------
      DISK_TOTAL_LBA=$(LANG=C smartctl -x -d sat,auto ${DEVICE_NAME} 2>/dev/null | grep -i lbas_wr | awk '{print $8}' | xargs)
      if [ "$DISK_TOTAL_LBA" != "" ];
      then
        e_and_l -n " Anzahl der ${light_cyan}geschriebenen Bytes${colors_off}    ... "
        TOTAL_BYTES_WRITTEN=$((DISK_TOTAL_LBA * 512))
        TOTAL_BYTES_WRITTEN=$(show_human_bytes ${TOTAL_BYTES_WRITTEN} "M")
        e_and_l "${light_yellow}$TOTAL_BYTES_WRITTEN${colors_off}"
      fi
      # ---------------------------------------
    done < "$THE_DISK_LIST"
    # --------------------------------------------------------------------------
    # NTFS-Dirty-Flags bereinigen (nur wenn NTFS-Partitionen vorhanden sind)
    # --------------------------------------------------------------------------
    e_and_l "$HALF_LINE"
    ACTION_MESSAGE=" Lösche ${light_cyan}Dirty Flags${colors_off} von NTFS-Partitionen ..."
    if [ $NTFS_COUNT -gt 0 ];
    then
      if ntfsfix --version &>/dev/null;
      then
        e_and_l " Es wurden ${bold_yellow}$NTFS_COUNT${colors_off} Partition(en) mit ${bold_white}NTFS${colors_off}-Dateisystem gefunden."
        ask_yes_or_no_plus "" " Sollen deren ${light_cyan}Dirty Flags${colors_off} gelöscht werden" "" "n"
        if [ $? -eq 1 ];
        then
          nc=0
          while [ $nc -lt $NTFS_COUNT ];
          do
            e_and_l -n " Lösche Dirty Flag von ${light_yellow}${NTFS_PARTITONS[$nc]}${colors_off} ... "
            ntfsfix -d "${NTFS_PARTITONS[$nc]}" &>/dev/null
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
            fi
            ((nc+=1))
          done
        fi
      else
        e_and_l "$(skip_text "$ACTION_MESSAGE " "$NA_TXT")"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE " "$NV_TXT")"
    fi
    # --------------------------------------------------------------------------
    # Weitere Aktionen nur wenn eine SSD vorhanden ist
    # --------------------------------------------------------------------------
    SSD_FOUND=0
    while read disk_data;
    do
      disk_rota=$(echo ${disk_data} | awk '{print $2}' | xargs)
      if [ $disk_rota -eq 0 ]; then SSD_FOUND=1; fi
    done < "$THE_DISK_LIST"
    if [ $SSD_FOUND -ne 0 ];
    then
      # ------------------------------------------------------------------------
      # Auf Raspberry Pi können wir uns das sparen, weil der kein AHCI hat ...
      # ------------------------------------------------------------------------
      if [ $IS_RASPBERRY_PI -eq 0 ];
      then
        # ----------------------------------------------------------------------
        # AHCI-Modus prüfen
        # ----------------------------------------------------------------------
        e_and_l "$HALF_LINE"
        e_and_l -n " Prüfe die System-Parameter des ${light_cyan}AHCI-Modus${colors_off} ... "
        if [ $(LANG=C dmesg | grep -i -E "scsi" | grep -i -c -E "ahci") -gt 0 ];
        then
          e_and_l "$OK_TAG"
          # --------------------------------------------------------------------
          # Trimming der SSDs
          # --------------------------------------------------------------------
          ask_yes_or_no_plus "trim_ssd" " ${light_cyan}Trimming der SSD(s)${colors_off} durchführen" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Führe ${light_yellow}Trimming der SSD${colors_off} durch, bitte warten ... "
            fstrim --all &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
        else
          e_and_l "$ERROR_TAG"
          e_and_l " AHCI scheint nicht aktiv zu sein."
        fi
      fi
    fi
    # --------------------------------------------------------------------------
  else
    e_and_l " $ERROR_TAG: Es wurden keine Festplatten/Laufwerke gefunden."
  fi
  remove_file "$THE_DISK_LIST"

fi

#===============================================================================
# Ermittlung vormals deaktivierter Komponenten (ohne Snap)
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[revive]} -eq 1 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Reaktivierung vormals deaktivierter Komponenten${colors_off} ${dark_gray}[revive]${colors_off}"
  e_and_l "$FULL_LINE"
  if [ $SNAP_INSTALLED -gt 0 ] &&
     [ $SNAP_ACTIVE -eq 0 ];
  then
    e_and_l " $HINWEIS_TAG: Dies betrifft nicht die Snap-Paketverwaltung - um diese wieder zu"
    e_and_l " reaktivieren, muss die Option \"snapcont\" verwendet werden."
  fi
  e_and_l -n " Starte Suche deaktivierter Komponenten, bitte warten ... "
  NOTHING_FOUND_TEXT="Es wurden keine deaktivierten Komponenten gefunden"
  echo -e -n "" > "$DEACTIVATED_ITEMS_LIST"
  find / -iname "*.deactivated" -type d,f 1>>"$DEACTIVATED_ITEMS_LIST" 2>/dev/null
  # Doppelte Einträge entfernen
  if [ -s "$DEACTIVATED_ITEMS_LIST" ];
  then
    THE_TEMP_FILE="$DOWNLOAD_DIR/tmp_rv_item_list.tmp"
    awk '!seen[$0]++' "$DEACTIVATED_ITEMS_LIST" > "$THE_TEMP_FILE" 2>/dev/null
    remove_file "$DEACTIVATED_ITEMS_LIST"
    mv -f "$THE_TEMP_FILE" "$DEACTIVATED_ITEMS_LIST" &>/dev/null
  fi
  e_and_l "$FERTIG_TAG"
  do_revive_items
fi

#===============================================================================
# Reparaturen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[repair]} -eq 1 ];
then

  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Reparaturen${colors_off} ${dark_gray}[repair]${colors_off}"
  e_and_l "$FULL_LINE"

  # ============================================================================
  # Symbolische Links zu Kernel-Versionen aktualisieren
  # ============================================================================
  e_and_l " ${bold_blue}Kernel${colors_off}"
  e_and_l "$HALF_LINE"
  LATEST_KERNEL_FILE="$(ls -1 /boot/vmlinuz-* | sort -V | tail -1)"
  LATEST_KERNEL_NAME="$(echo ${LATEST_KERNEL_FILE} | sed -E "s/.*vmlinuz-(.*)/\1/")"
  LATEST_KERNEL_VERSION="$(echo ${LATEST_KERNEL_NAME} | sed -E 's/([\.0-9\-]*).*/\1/' | sed -E 's/\-$//')"
  CURRENT_KERNEL_VALUE=$(get_version_value ${CURRENT_KERNEL_VERSION})
  LATEST_KERNEL_VALUE=$(get_version_value ${LATEST_KERNEL_VERSION})
  if [ $CURRENT_KERNEL_VALUE -lt $LATEST_KERNEL_VALUE ];
  then
    if linux-update-symlinks --help &>/dev/null;
    then
      e_and_l " Die neuere Version ${bold_yellow}$LATEST_KERNEL_VERSION${colors_off} als die verwendete ${bold_white}$CURRENT_KERNEL_VERSION${colors_off} ist installiert."
      ask_yes_or_no_plus "update_kernel_symlinks" " Soll ab nächstem Neustart der ${light_cyan}neuere Kernel${colors_off} verwendet werden" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Erstelle ${light_yellow}symbolische Verknüpfungen${colors_off} zu neuesten Kernel-Dateien ... "
        linux-update-symlinks upgrade "$LATEST_KERNEL_NAME" "$LATEST_KERNEL_FILE" &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
          e_and_l " $HINWEIS_TAG: Sofern ein Boot-Loader mit einer anderen Partition verwendet wird,"
          e_and_l " kann es sein, dass die verwendete Kernel-Version in diesem fest eingetragen"
          e_and_l " ist und dort - idealerweise mit Verwendung der symbolischen Verknüpfungen -"
          e_and_l " zusätzlich angepasst werden muss, damit die Änderungen wirksam werden."
        else
          e_and_l "$ERROR_TAG"
        fi
        add_full_log
      fi
    else # Kein Befehl zur Symlink-Anlage (könnten wir auch manuell machen)
      e_and_l "$(skip_text " Erstellung neuer Symlinks zu Kernel-Dateien" "$NA_TXT")"
    fi
  else # Neuester Kernel bereits in Verwendung
    e_and_l " Prüfung auf installierte ${light_cyan}neuere Kernel-Version${colors_off} ... $NF_TAG"
  fi

  # ============================================================================
  # Reparatur von fehlerhaften EFI-System-Einträgen (/boot/efi) in der fstab
  # ---------------------------------------------------------------------------
  # Bspw. nach Kopieren einzelner System-Partitionen auf ein anderes Laufwerk
  # ist es sehr wahrscheinlich, dass die UUID der EFI-System-Partition nicht
  # mehr den Eintragungen in der/n fstab/s des anderen Laufwerks entspricht.
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Boot-Partition${colors_off}"
  e_and_l "$HALF_LINE"
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}fehlerhafte EFI-System-Einträge${colors_off}"
  if [ "$BOOT_MODE" == "EFI" ] &&
     [ "$uuid_efi_system" != "" ];
  then
    if [ -s "$ETC_FSTAB" ];
    then
      EFI_ENTRY_ERRORS="$(check_esp_errors)"
      if [ "$EFI_ENTRY_ERRORS" != "" ];
      then
        e_and_l " $ACHTUNG_TAG: Es wurden ${light_cyan}fehlerhafte Einträge für EFI-System-Partitionen${colors_off} gefunden."
        e_and_l " Diese können den Bootvorgang erheblich verzögern und sogar zu dessen Abbruch"
        e_and_l " führen. Nachstehende Einträge wurden überprüft."
        e_and_l "$HALF_MINUS_LINE"
        e_and_l -n " ESP in der Dateisystem-Tabelle: "
        if [ "$uuid_efi_fstab" != "" ];
        then
          e_and_l -n "UUID ${light_yellow}$uuid_efi_fstab"
        else
          e_and_l -n "${light_yellow}kein Eintrag gefunden!"
        fi
        e_and_l "${colors_off}"
        e_and_l -n " ESP auf dem Laufwerk ${light_magenta}$boot_device${colors_off} : "
        if [ "$uuid_efi_system" != "" ];
        then
          e_and_l -n "UUID ${light_yellow}$uuid_efi_system"
        else
          e_and_l -n "keine Partition gefunden!"
        fi
        e_and_l "${colors_off}"
        e_and_l -n " Partition mit Ordner ${light_magenta}/boot/efi${colors_off}: "
        if [ "$uuid_efi_mount" != "" ] &&
           [ -d "/boot/efi" ];
        then
          e_and_l -n "UUID ${light_yellow}$uuid_efi_mount"
        else
          e_and_l -n "${light_yellow}Ordner exisitiert nicht!"
        fi
        e_and_l "${colors_off}"
        e_and_l " Folgende Fehler wurden gefunden:"
        if [ $(echo "$EFI_ENTRY_ERRORS" | grep -c "1") -gt 0 ];
        then
          e_and_l " - die EFI-System-Partition ist nicht in der Dateisystem-Tabelle eingetragen"
        fi
        if [ $(echo "$EFI_ENTRY_ERRORS" | grep -c "2") -gt 0 ];
        then
          e_and_l " - die in der Dateisystem-Tabelle eingetrage ESP ist nicht die dieses Laufwerks"
        fi
        if [ $(echo "$EFI_ENTRY_ERRORS" | grep -c "3") -gt 0 ];
        then
          e_and_l " - die in der Dateisystem-Tabelle eingetrage ESP ist nicht korrekt eingehangen"
        fi
        if [ $(echo "$EFI_ENTRY_ERRORS" | grep -c "4") -gt 0 ];
        then
          e_and_l " - Ordner /boot/efi liegt nicht auf der dafür in fstab eingetragenen Partition"
        fi
        if [ $(echo "$EFI_ENTRY_ERRORS" | grep -c "5") -gt 0 ];
        then
          e_and_l " - die Partition mit dem Ordner /boot/efi ist nicht die EFI-System-Partition"
        fi
        e_and_l "$HALF_MINUS_LINE"
        ask_yes_or_no_plus "" " Sollen die ${light_cyan}fehlerhaften EFI-System-Einträge${colors_off} korrigiert werden" "" "n"
        if [ $? -eq 1 ];
        then
          create_backup_file "$ETC_FSTAB"
          e_and_l -n " Korrigiere ${light_yellow}fehlerhafte EFI-System-Einträge${colors_off} ... "
          NEW_UUID_ENTRY="UUID=$uuid_efi_system /boot/efi vfat umask=0077 0 1"
          ESP_REPAIR_ERRORS=0
          # ----------------------------------------------------
          # Wenn es schon einen Eintrag gibt, diesen ändern ...
          # ----------------------------------------------------
          if [ $(cat "$ETC_FSTAB" | grep -c -i -E "^\s*\#*\s*UUID\s*\=.*\/boot\/efi") -gt 0 ];
          then
            sed -i -E "s/^\s*\#*\s*UUID\s*\=.*\/boot\/efi.*/${NEW_UUID_ENTRY//\//\\\/}/gi" "$ETC_FSTAB"
            ESP_REPAIR_ERRORS=$?
          # -----------------------------------------
          # ... sonst einen neuen Eintrag hinzufügen
          # -----------------------------------------
          else
            echo -e "" >> "$ETC_FSTAB" 2>/dev/null
            echo -e "$NEW_UUID_ENTRY" >> "$ETC_FSTAB" 2>/dev/null
            ESP_REPAIR_ERRORS=$?
          fi
          if [ $ESP_REPAIR_ERRORS -eq 0 ];
          then
            # ----------------------------
            # Doppelte Einträge entfernen
            # ----------------------------
            THE_TEMP_FILE="$DOWNLOAD_DIR/etc_fstab.tmp"
            awk '!seen[$0]++' "$ETC_FSTAB" > "$THE_TEMP_FILE" 2>/dev/null
            remove_file "$ETC_FSTAB"
            mv -f "$THE_TEMP_FILE" "$ETC_FSTAB" &>/dev/null
            # ----------------------------
            e_and_l "$OK_TAG"
            e_and_l "$REBOOT_MSG"
          else
            restore_backup_file "$ETC_FSTAB"
            e_and_l "$ERROR_TAG"
          fi
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NF_TAG"
      fi
    else
      e_and_l "$(skip_text "$ACTION_MESSAGE" "keine fstab!")"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "nur bei EFI-Boot")"
  fi

  # ============================================================================
  # Deaktivierung verwaister Partitions-Einträge in der fstab
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}System-Partitionen${colors_off}"
  e_and_l "$HALF_LINE"
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}verwaiste Partitions-Einträge${colors_off}"
  if [ -s "$ETC_FSTAB" ];
  then
    DEVICE_UUID_LIST="$(ls -1 /dev/disk/by-uuid)"
    FSTAB_UUID_LIST="$DOWNLOAD_DIR/uuid_list.tmp"
    cat "$ETC_FSTAB" | grep -i -E "^\s*uuid\s*=" | cut -d"=" -f 2 | awk '{print $1" => "$2" ("$3")"}' 1>"$FSTAB_UUID_LIST" 2>/dev/null
    if [ -s "$FSTAB_UUID_LIST" ];
    then
      MISSING_UUID_LIST=()
      while read uuid_part;
      do
        if [ "$uuid_part" != "" ];
        then
          THE_PURE_UUID=$(echo $uuid_part | awk '{print $1}' | xargs 2>/dev/null)
          if [ $(echo -n "$DEVICE_UUID_LIST" | grep -i -c -E "$THE_PURE_UUID") -eq 0 ];
          then
            MISSING_UUID_LIST+=("$uuid_part")
          fi
        fi
      done < "$FSTAB_UUID_LIST"
      if [ ${#MISSING_UUID_LIST[@]} -gt 0 ];
      then
        e_and_l " $ACHTUNG_TAG: Es wurden ${light_cyan}verwaiste Partitions-Einträge${colors_off} gefunden. Dies kann zu"
        e_and_l " erheblichen Verzögerungen und sogar zum Abbruch des Bootvorgangs führen."
        ask_yes_or_no_plus "remove_orphan_uuid" " Sollen die verwaisten Einträge auswählbar deaktiviert werden" "" "j"
        if [ $? -eq 1 ];
        then
          create_backup_file "$ETC_FSTAB"
          e_and_l " ${light_yellow}Deaktivierung von Partitions-Einträgen${colors_off} in der Dateisystem-Tabelle:"
          for uuid_part in "${MISSING_UUID_LIST[@]}";
          do
            if [ "$uuid_part" != "" ];
            then
              QUESTION=" ${light_yellow}"
              QUESTION+="$(echo ${uuid_part} | awk '{print $1}')"
              QUESTION+="${colors_off}${dark_gray} => ${colors_off}${light_cyan}"
              QUESTION+="$(echo ${uuid_part} | awk '{print $3}')"
              QUESTION+="${colors_off}"
              # ask_yes_or_no_pure "$QUESTION"
              ask_yes_or_no_plus "" "$QUESTION" "" "n"
              if [ $? -eq 1 ];
              then
                THE_PURE_UUID=$(echo $uuid_part | awk '{print $1}' | xargs 2>/dev/null)
                e_and_l -n " Deaktiviere ${light_yellow}$THE_PURE_UUID${colors_off} ... "
                sed -i -E "s/^\s*UUID\s*=\s*$THE_PURE_UUID/# UUID=$THE_PURE_UUID/gi" "$ETC_FSTAB" 2>/dev/null
                if [ $? -eq 0 ];
                then
                  e_and_l "$OK_TAG"
                else
                  restore_backup_file "$ETC_FSTAB"
                  e_and_l "$ERROR_TAG"
                fi
              fi
            fi
          done
        fi
      else
        e_and_l "$ACTION_MESSAGE ... $NF_TAG"
      fi
    else
      e_and_l "$ACTION_MESSAGE ... $NF_TAG"
    fi
    remove_file "$FSTAB_UUID_LIST"
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE " "keine fstab!")"
  fi

  # ============================================================================
  # Erneuerung / Installation des GRUB-Bootloaders
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}GRUB-Bootloader${colors_off}"
  e_and_l "$HALF_LINE"
  if [ -d /boot/grub ];
  then
    e_and_l " Wenn sich auf dem Rechner Betriebs-Systeme befinden, die sich beim Booten des"
    e_and_l " Rechners nicht auswählen oder starten lassen, kann versucht werden dies durch"
    e_and_l " die Erneuerung des ${bold_white}GRUB-Bootloaders${colors_off} und dessen Konfiguration zu korrigieren."
    e_and_l " Darüber hinaus kann damit auch das Aussehen des Boot-Menüs geändert werden."
  else
    e_and_l " $HINWEIS_TAG: Auf diesem System scheint kein ${bold_white}GRUB-Bootloader${colors_off} installiert zu sein."
    e_and_l " Wenn ein anderer Bootloader vorhanden ist, wird dieser durch die Installation"
    e_and_l " des GRUB-Bootloaders überschrieben. Der ${bold_white}GRUB-Bootloader${colors_off} sollte daher nur bei"
    e_and_l " Boot-Problemen des Systems neu installiert werden."
  fi
  # ----------------------------------------------------------------------------
  # Auf EFI-Systemen zusätzliche Voraussetzungen prüfen
  # ----------------------------------------------------------------------------
  EFI_ENTRY_ERRORS=""
  if [ "$BOOT_MODE" == "EFI" ] &&
     [ "$uuid_efi_system" != "" ];
  then
    # -------------------------------------------------------------------------
    # Wenn es in der Dateisystem-Tabelle einen aktiven Eintrag für /boot/efi
    # gibt und dieser nicht eingehangen ist (bspw. nach vorheriger Korrektur),
    # dann die Partition mit /boot/efi einhängen (mounten)
    # -------------------------------------------------------------------------
    if [ $(cat "$ETC_FSTAB" 2>/dev/null | grep -c -i -E "^\s*[^#]*\s*[a-z0-9\=\-]*(\s|\t)+/boot/efi") -gt 0 ] &&
       [ $(mount 2>/dev/null | grep -c -i -E "$efi_system_partition.*/boot/efi") -eq 0 ];
    then
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $WARN_TAG: Die EFI-System-Partition ${light_magenta}$efi_system_partition${colors_off} ist nicht eingehangen."
      e_and_l " Zur korrekten Erstellung eines neuen Bootloaders muss diese eingehangen sein."
      ask_yes_or_no_plus "" " Jetzt die EFI-System-Partition auf ${light_cyan}/boot/efi${colors_off} einhängen" "" "j"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Hänge die EFI-System-Partition ${light_yellow}$efi_system_partition${colors_off} auf ${light_yellow}/boot/efi${colors_off} ein ... "
        if [ ! -d /boot/efi ];
        then
          mkdir -p /boot/efi &>/dev/null
        fi
        mount "$efi_system_partition" /boot/efi &>/dev/null
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
      fi
      e_and_l "$HALF_MINUS_LINE"
    fi
    # ----------------------------------------------------------------
    # Wenn es jetzt immer noch Fehler gibt, dann Warnhinweis anzeigen
    # ----------------------------------------------------------------
    EFI_ENTRY_ERRORS="$(check_esp_errors)"
    if [ "$EFI_ENTRY_ERRORS" != "" ];
    then
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $WARN_TAG: Es wurden fehlerhafte Einträge für EFI-System-Partitionen gefunden."
      e_and_l " Damit die Erstellung eines neuen Bootloaders korrekt durchgeführt werden kann,"
      e_and_l " sollten diese Einträge erst korrigiert werden."
    fi
  fi
  # ----------------------------------------------------------------------------
  if [ -d /boot/grub ] &&
     [ "$EFI_ENTRY_ERRORS" == "" ];
  then
    GRUB_QUESTION="Neuen ${light_cyan}GRUB-Bootloader${colors_off} mit neuen Starteinträgen erstellen"
  else
    GRUB_QUESTION="Trotzdem ${light_cyan}GRUB-Bootloader${colors_off} neu erstellen (${bold_white}nicht empfohlen${colors_off})"
  fi
  ask_yes_or_no_plus "" " $GRUB_QUESTION" "" "n"
  if [ $? -eq 1 ];
  then
    GRUB_ACTION=2
    while [ $GRUB_ACTION -eq 2 ];
    do
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " ${bold_white}Konfiguration${colors_off} von GRUB"
      # -----------------------------
      # Option Letzte Auswahl merken
      # -----------------------------
      e_and_l "$HALF_MINUS_LINE"
      ask_yes_or_no_plus "" " Soll GRUB sich den ${light_yellow}zuletzt ausgewählten Eintrag${colors_off} merken" "" "j"
      if [ $? -eq 1 ];
      then
        GRUB_DEFAULT_ENTRY="GRUB_DEFAULT=saved"
        GRUB_SAVEDEFAULT_ENTRY="GRUB_SAVEDEFAULT=true"
        GRUB_TIMEOUT_ENTRY=""
      else
        GRUB_DEFAULT_ENTRY="GRUB_DEFAULT=0"
        GRUB_SAVEDEFAULT_ENTRY=""
      fi
      # ------------------------------
      # Option Anzeigedauer des Menüs
      # ------------------------------
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " Wie lange soll das ${light_yellow}Startmenü${colors_off} anzeigt werden, bevor der vorselektierte Eintrag"
      e_and_l " automatisch ausgewählt wird (Zeit in Sekunden von 0 bis 60)?"
      GRUB_TIMEOUT_DURATION=-1
      while [ $GRUB_TIMEOUT_DURATION -lt 0 ] ||
            [ $GRUB_TIMEOUT_DURATION -gt 60 ];
      do
        e_and_l -n " Bitte ${light_yellow}Anzeigedauer${colors_off} eingeben: "
        read -r GRUB_TIMEOUT_DURATION
        GRUB_TIMEOUT_DURATION=$(echo ${GRUB_TIMEOUT_DURATION} | sed -E "s/[^0-9]*//gi" | xargs 2>/dev/null)
        if [ "$GRUB_TIMEOUT_DURATION" == "" ];
        then
          GRUB_TIMEOUT_DURATION=-1
        fi
      done
      # -----------------------
      # Option Hintergrundbild
      # -----------------------
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " Zur Anzeige eines ${light_yellow}Hintergrundbilds${colors_off} dessen vollständigen Dateipfad eingeben."
      e_and_l " Eingabe leer lassen, um die Einstellung des Hintergrundbilds nicht zu ändern,"
      e_and_l " oder zum Zurücksetzen des Bildes auf die Standard-Einstellung ${light_yellow}reset${colors_off} eingeben."
      GRUB_BG_FILE="NONE"
      while [ "$GRUB_BG_FILE" == "NONE" ];
      do
        e_and_l -n " Hintergrundbild: "
        read -r GRUB_BG_FILE
        if [ "$GRUB_BG_FILE" != "reset" ];
        then
          if [ "$GRUB_BG_FILE" != "" ] &&
             [[ ! -s "$GRUB_BG_FILE" || -d "$GRUB_BG_FILE" ]];
          then
            GRUB_BG_FILE="NONE"
          fi
        fi
      done
      # --------------
      # Option Farben
      # --------------
      color_select "Menü-Einträge und Rahmen"
      GRUB_FG_COLOR_CODE=$?
      GRUB_FG_COLOR_NAME="${ANSI_COLOR_NAMES[$GRUB_FG_COLOR_CODE]}"
      color_select "Ausgewählter Menüeintrag"
      GRUB_HL_COLOR_CODE=$?
      GRUB_HL_COLOR_NAME="${ANSI_COLOR_NAMES[$GRUB_HL_COLOR_CODE]}"
      color_select "Hintergrund der Auswahl ([0] black = transparent)"
      GRUB_BG_COLOR_CODE=$?
      GRUB_BG_COLOR_NAME="${ANSI_COLOR_NAMES[$GRUB_BG_COLOR_CODE]}"
      color_select "Informationen neben Menü"
      GRUB_OS_COLOR_CODE=$?
      GRUB_OS_COLOR_NAME="${ANSI_COLOR_NAMES[$GRUB_OS_COLOR_CODE]}"
      # ----------------
      # Zusammenfassung
      # ----------------
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " ${bold_white}Zusammenfassung ausgewählter Optionen${colors_off}"
      e_and_l "$HALF_MINUS_LINE"
      e_and_l -n " Zuletzt ausgewählten Eintrag merken: ${light_yellow}"
      if [ $(echo "$GRUB_DEFAULT_ENTRY" | grep -c -i -E "saved") -gt 0 ]; then e_and_l -n "Ja"; else e_and_l -n "Nein"; fi
      e_and_l "${colors_off}"
      e_and_l " Anzeigedauer des Startmenüs: ${light_yellow}$GRUB_TIMEOUT_DURATION${colors_off} Sekunden"
      e_and_l -n " Hintergrundbild: ${light_yellow}"
      if [ "$GRUB_BG_FILE" != "" ];
      then
        if [ "$GRUB_BG_FILE" == "reset" ];
        then
          e_and_l -n "wird auf Standard gesetzt"
        else
          e_and_l -n "$GRUB_BG_FILE"
        fi
      else
        e_and_l -n "keine Änderung"
      fi
      e_and_l "${colors_off}"
      fg_color_code="$(color_idx_code $GRUB_FG_COLOR_CODE)"
      e_and_l " Menü-Einträge und Rahmen: ${fg_color_code}$GRUB_FG_COLOR_NAME${colors_off}"
      hl_color_code="$(color_idx_code $GRUB_HL_COLOR_CODE)"
      e_and_l " Ausgewählter Menüeintrag: ${hl_color_code}$GRUB_HL_COLOR_NAME${colors_off}"
      bg_color_code="$(color_idx_code $GRUB_BG_COLOR_CODE)"
      e_and_l -n " Hintergrund der Auswahl : "
      if [ "$GRUB_BG_COLOR_NAME" != "black" ];
      then
        hl_bg_color="$(echo ${bg_color_code} | sed -E "s/\[0\;(3|9)/[4/gi")"
        e_and_l "$GRUB_BG_COLOR_NAME"
      else
        hl_bg_color=""
        e_and_l "transparent"
      fi
      os_color_code="$(color_idx_code $GRUB_OS_COLOR_CODE)"
      e_and_l " Informationen neben Menü: ${os_color_code}$GRUB_OS_COLOR_NAME${colors_off}"
      e_and_l " Vorschau (ohne Hintergrundbild):"
      e_and_l " ${os_color_code}      GRUB Version${colors_off}"
      e_and_l " ${fg_color_code}┏━━━━━━━━━━━━━━━━━━━━━━━${colors_off}"
      e_and_l " ${fg_color_code}┃ Eintrag im Startmenü ${colors_off}"
      e_and_l " ${fg_color_code}┃${colors_off}${hl_color_code}${hl_bg_color}*Ausgewählter Eintrag ${colors_off}"
      # ------------------------------------------------------------------------
      # 1. Sicherheitsabfrage
      # ------------------------------------------------------------------------
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " Soll der ${bold_yellow}GRUB-Bootloader${colors_off} mit diesen Einstellungen neu installiert werden?"
      e_and_l " [${bold_yellow}0${colors_off}] Abbrechen, GRUB nicht neu installieren"
      e_and_l " [${bold_yellow}1${colors_off}] Ja, neuen GRUB-Bootloader installieren"
      e_and_l " [${bold_yellow}2${colors_off}] Nein, Konfiguration wiederholen"
      user_choice_012
      GRUB_ACTION=$?
    done
    # --------------------------------------------------------------------------
    # 2. Sicherheitsabfrage
    # --------------------------------------------------------------------------
    if [ $GRUB_ACTION -eq 1 ];
    then
      e_and_l " $ACHTUNG_TAG: Die aktuelle Konfiguration des GRUB-Bootloaders wird vollständig"
      e_and_l " überschrieben, was dazu führen kann, dass eventuell individuell angepasste"
      e_and_l " Dateien nachträglich erneut manuell angepasst werden müssen!"
      ask_yes_or_no_plus "" " Jetzt wirklich den ${bold_yellow}GRUB-Bootloader${colors_off} auf ${bold_yellow}$boot_device${colors_off} erneuern" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l " $USER_CHOICE_YES"
        # ----------------------------------------------------------------------
        # Installation eines neuen GRUB-Loaders
        # ----------------------------------------------------------------------
        e_and_l -n " Installiere neuen ${light_yellow}GRUB-Bootloader${colors_off} auf dem Ziel, bitte warten   ... "
        if grub-install --version &>/dev/null;
        then
          # ---------------------------------
          # Bei EFI-Systemen Pfad hinzufügen
          # ---------------------------------
          if [ "$BOOT_MODE" == "EFI" ] &&
             [ "$uuid_efi_system" != "" ] &&
             [ -d /boot/efi ];
          then
            BOOT_EFI_OPTION="--efi-directory=/boot/efi"
          else
            BOOT_EFI_OPTION=""
          fi
          # ---------------------------------
          grub-install --boot-directory=/boot ${BOOT_EFI_OPTION} --force ${boot_device} &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
          add_full_log
        else
          e_and_l "$NA_TAG"
        fi
        # ----------------------------------------------------------------------
        # Standard-Konfiguration (Defaults) von GRUB ändern
        # ----------------------------------------------------------------------
        e_and_l -n " Aktualisiere ${light_yellow}Konfiguration${colors_off} des GRUB-Bootloaders, bitte warten  ... "
        if [ -s "$GRUB_DEFAULT_FILE" ];
        then
          create_backup_file "$GRUB_DEFAULT_FILE"
          # --------------------------------------------------------------------
          # 1. Einstellungen zur Vorauswahl des letzten ausgewählten Eintrags
          # --------------------------------------------------------------------
          # 1.1 GRUB_DEFAULT: Letzten ausgewählten Eintrag vorauswählen (saved)
          # --------------------------------------------------------------------
          # Wenn es den Eintrag schon gibt, diesen ändern ...
          # --------------------------------------------------
          if [ $(cat "$GRUB_DEFAULT_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*GRUB_DEFAULT\s*\=") -gt 0 ];
          then
            sed -i -E "s/^\s*\#*\s*GRUB_DEFAULT\s*\=.*/$GRUB_DEFAULT_ENTRY/gi" "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_1=$?
          # ----------------------
          # ... sonst neu anlegen
          # ----------------------
          else
            echo -e "" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
            echo -e "$GRUB_DEFAULT_ENTRY" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_1=$?
          fi
          # --------------------------------------------------
          # 1.2 GRUB_SAVEDEFAULT: Vorauswahl verwenden (true)
          # --------------------------------------------------
          # Wenn es den Eintrag schon gibt, diesen ändern ...
          # --------------------------------------------------
          if [ $(cat "$GRUB_DEFAULT_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*GRUB_SAVEDEFAULT\s*\=") -gt 0 ];
          then
            sed -i -E "s/^\s*\#*\s*GRUB_SAVEDEFAULT\s*\=.*/$GRUB_SAVEDEFAULT_ENTRY/gi" "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_2=$?
          # ----------------------
          # ... sonst neu anlegen
          # ----------------------
          else
            # ------------------------------------------------------
            # SED-Option /a fügt eine Zeile hinter dem Match ein ;)
            # ------------------------------------------------------
            sed -i -E "/$GRUB_DEFAULT_ENTRY/a$GRUB_SAVEDEFAULT_ENTRY" "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_2=$?
          fi
          # -----------------------------------------------------------------
          # 2. Einstellungen zur Menü-Anzeigedauer vor automatischer Auswahl
          # -----------------------------------------------------------------
          # 2.1 GRUB_TIMEOUT: Anzeigedauer in Sekunden
          # --------------------------------------------------
          # Wenn es den Eintrag schon gibt, diesen ändern ...
          # --------------------------------------------------
          if [ $(cat "$GRUB_DEFAULT_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*GRUB_TIMEOUT\s*\=") -gt 0 ];
          then
            sed -i -E "s/^\s*\#*\s*GRUB_TIMEOUT\s*\=.*/GRUB_TIMEOUT=$GRUB_TIMEOUT_DURATION/gi" "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_1=$?
          # ----------------------
          # ... sonst neu anlegen
          # ----------------------
          else
            echo -e "" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
            echo -e "GRUB_TIMEOUT=$GRUB_TIMEOUT_DURATION" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
            RESULT_ENTRY_1=$?
          fi
          # -------------------------------------------------------------------
          # 2.2 DURATION soll die Anzeigedauer, nicht die Vor-Verzögerung sein
          # -------------------------------------------------------------------
          # Wenn es den Eintrag schon gibt, diesen ändern ...
          # (wenn es ihn nicht gibt, auch nicht neu anlegen, da ohne diesen das
          # Verhalten von GRUB_TIMEOUT bereits die "Anzeigedauer" ist)
          # --------------------------------------------------
          if [ $(cat "$GRUB_DEFAULT_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*GRUB_TIMEOUT_STYLE\s*\=") -gt 0 ];
          then
            sed -i -E "s/^\s*\#*\s*GRUB_TIMEOUT_STYLE\s*\=.*/GRUB_TIMEOUT_STYLE=menu/gi" "$GRUB_DEFAULT_FILE" 2>/dev/null
          fi
          # --------------------------------------------------------------------
          remove_double_empty_lines "$GRUB_DEFAULT_FILE"
          # --------------------------------------------------------------------
          # 3. Zusätzlich individuelle Einstellungen zu Bild und Farben
          # --------------------------------------------------------------------
          # Individuelle Konfigurations-Datei anlegen
          # ------------------------------------------
          if [ -s "$GRUB_CUSTOM_FILE" ];
          then
            create_backup_file "$GRUB_CUSTOM_FILE"
          else
            echo -e -n > "$GRUB_CUSTOM_FILE" 2>/dev/null
          fi
          # --------------------
          # 3.1 Hintergrundbild
          # --------------------
          if [ "$GRUB_BG_FILE" != "" ];
          then
            # ---------------------------------------
            # Hintergrundbild zurücksetzen (löschen)
            # ---------------------------------------
            if [ "$GRUB_BG_FILE" == "reset" ];
            then
              sed -i -E "s/^\s*\#*\s*insmod\s.*//gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
              sed -i -E "s/^\s*\#*\s*background_image\s.*//gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
            # -----------------------
            # Hintergrundbild ändern
            # -----------------------
            else
              # --------------------------------------------------
              # Wenn es den Eintrag schon gibt, diesen ändern ...
              # --------------------------------------------------
              if [ $(cat "$GRUB_CUSTOM_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*background_image\s") -gt 0 ];
              then
                sed -i -E "s/^\s*\#*\s*insmod png/insmod png/gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
                sed -i -E "s/^\s*\#*\s*insmod jpeg/insmod jpeg/gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
                sed -i -E "s/^\s*\#*\s*background_image\s.*/background_image ${GRUB_BG_FILE//\//\\\/}/gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
              # --------------------------------------------------
              # ... sonst neu anlegen
              # --------------------------------------------------
              else
                echo -e "" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
                echo -e "insmod png" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
                echo -e "insmod jpeg" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
                echo -e "background_image $GRUB_BG_FILE" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
              fi
            fi
          fi
          # -----------
          # 3.2 Farben
          # -----------
          GRUB_COLOR_NAMES[0]="color_normal"
          GRUB_COLOR_VALUE[0]="$GRUB_OS_COLOR_NAME/black"
          GRUB_COLOR_NAMES[1]="menu_color_normal"
          GRUB_COLOR_VALUE[1]="$GRUB_FG_COLOR_NAME/black"
          GRUB_COLOR_NAMES[2]="menu_color_highlight"
          GRUB_COLOR_VALUE[2]="$GRUB_HL_COLOR_NAME/$GRUB_BG_COLOR_NAME"
          color_entries=${#GRUB_COLOR_NAMES[@]}
          col_nr=0
          while [ $col_nr -lt $color_entries ];
          do
            # --------------------------------------------------
            # Wenn es den Eintrag schon gibt, diesen ändern ...
            # --------------------------------------------------
            THE_NEW_COLOR_LINE="set ${GRUB_COLOR_NAMES[$col_nr]}=${GRUB_COLOR_VALUE[$col_nr]}"
            if [ $(cat "$GRUB_CUSTOM_FILE" 2>/dev/null | grep -c -i -E "^\s*\#*\s*set\s*${GRUB_COLOR_NAMES[$col_nr]}\s*\=") -gt 0 ];
            then
              THE_NEW_COLOR_LINE=$(echo -n "$THE_NEW_COLOR_LINE" | sed 's/\//\\\//g')
              sed -i -E "s/^\s*\#*\s*set\s*${GRUB_COLOR_NAMES[$col_nr]}\s*\=.*/$THE_NEW_COLOR_LINE/gi" "$GRUB_CUSTOM_FILE" 2>/dev/null
            # ----------------------
            # ... sonst neu anlegen
            # ----------------------
            else
              echo -e "" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
              echo -e "$THE_NEW_COLOR_LINE" >> "$GRUB_CUSTOM_FILE" 2>/dev/null
            fi
            # --------------------------------------------------
            ((col_nr+=1))
          done
          # --------------------------------------------------------------------
          remove_double_empty_lines "$GRUB_CUSTOM_FILE"
          # --------------------------------------------------------------------
          if [ $RESULT_ENTRY_1 -eq 0 ] &&
             [ $RESULT_ENTRY_2 -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG ($RESULT_ENTRY_1 $RESULT_ENTRY_2)"
            add_full_log
          fi
        else
          e_and_l "$NA_TAG"
        fi
        # ----------------------------------------------------------------------
        # Aktualisierung der GRUB-Konfiguration
        # ----------------------------------------------------------------------
        e_and_l -n " Aktualisiere ${light_yellow}Start-Einträge${colors_off} des GRUB-Bootloaders, bitte warten ... "
        # -----------------------------------
        # Wenn update-grub vorhanden ist ...
        # -----------------------------------
        if update-grub --version &>/dev/null;
        then
          # -------------------------------------------
          # Immer nach anderen Betriebssystemen suchen
          # -------------------------------------------
          if [ -s "$GRUB_DEFAULT_FILE" ];
          then
            if [ $(grep -i -c -E "^\s*\#*\s*GRUB_DISABLE_OS_PROBER" "$GRUB_DEFAULT_FILE") -gt 0 ];
            then
              sed -i 's/^\s*\#*\s*GRUB_DISABLE_OS_PROBER.*/GRUB_DISABLE_OS_PROBER=false/gi' "$GRUB_DEFAULT_FILE" 2>/dev/null
            else
              echo -e "" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
              echo -e "GRUB_DISABLE_OS_PROBER=false" >> "$GRUB_DEFAULT_FILE" 2>/dev/null
            fi
          fi
          # -------------------------------------------
          update-grub &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
          add_full_log
        else
          # --------------------------------------
          # ... sonst mit grub-mkconfig versuchen
          # --------------------------------------
          if grub-mkconfig --version &>/dev/null;
          then
            grub-mkconfig -o /boot/grub/grub.cfg &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
          else
            e_and_l "$NA_TAG"
          fi
        fi
        if [ -s "$GRUB_CUSTOM_FILE" ];
        then
          e_and_l " $HINWEIS_TAG: Die individuelle Konfiguration wurde ordnungsgemäß in den von GRUB"
          e_and_l " dafür vorgesehenen Dateien gespeichert. Die Änderung von GRUB-Einstellungen"
          e_and_l " in anderen Konfigurations-Dateien kann diese jedoch möglicherweise überlagern."
          e_and_l " Zudem können sich die Farben im GRUB-Startmenü aufgrund einer verschiedenen"
          e_and_l " RGB-Matrix eventuell leicht von den zuvor dargestellten Farben unterscheiden."
        fi
      else
        e_and_l " $USER_CHOICE_NO"
      fi
    fi
  fi

  # ============================================================================
  # Prüfung auf Verzögerungen im Boot-Vorgang
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Boot-Vorgang${colors_off}"
  e_and_l "$HALF_LINE"
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}Verzögerungen im Boot-Vorgang${colors_off}"
  if systemd-analyze --version &>/dev/null;
  then
    LANG=C systemd-analyze blame | grep -i -E "^\s*[0-9\s]*min" 1>"$BOOT_BLAME_LIST" 2>/dev/null
    if [ -s "$BOOT_BLAME_LIST" ];
    then
      BOOT_BLAME_ENTRIES=()
      while read blame_entry;
      do
        if [ "$blame_entry" != "" ];
        then
          BOOT_BLAME_ENTRIES+=("$blame_entry")
        fi
      done < "$BOOT_BLAME_LIST"
      anz_entries=${#BOOT_BLAME_ENTRIES[@]}
      if [ $anz_entries -gt 0 ];
      then
        e_and_l " $HINWEIS_TAG: Es wurden ${bold_yellow}$anz_entries${colors_off} Dienste gefunden, die zu einer ${light_cyan}erheblichen Verzögerung${colors_off}"
        e_and_l " des Bootvorgangs geführt haben (mit jeweils mehr als einer Minute)."
        e_and_l "$HALF_MINUS_LINE"
        i=0
        while [ $i -lt $anz_entries ];
        do
          e_and_l "$HALF_MINUS_LINE"
          BLAME_ENRTY_NAME=$(echo -n ${BOOT_BLAME_ENTRIES[$i]} | awk '{print $3}')
          BLAME_ENRTY_TIME=$(echo -n ${BOOT_BLAME_ENTRIES[$i]} | awk '{print $1 $2}')
          e_and_l "- ${bold_white}$BLAME_ENRTY_NAME${colors_off} (${bold_yellow}$BLAME_ENRTY_TIME${colors_off})"
          systemctl list-dependencies --reverse "$BLAME_ENRTY_NAME"
          ((i++))
        done
      fi
    else
      e_and_l "$ACTION_MESSAGE ,,, $OK_TAG ${dark_gray}(keine > 1 Minute)${colors_off}"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  # ============================================================================
  # Prüfung auf fehlerhafte System-Dienste
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}System-Dienste${colors_off}"
  e_and_l "$HALF_LINE"
  LANG=C systemctl 2>/dev/null | grep -E "\.service.*\bfailed\b" | awk '{print $2}' 1>"$FAILED_SERVICES_LIST" 2>/dev/null
  declare -A FAILED_SERVICE
  FAILED_SERVICE_IDX=0
  while read failed_service;
  do
    if [ "$failed_service" != "" ];
    then
      if [ $(LANG=C systemctl status $failed_service 2>/dev/null | grep -c -i -E "\bdisabled\b") -eq 0 ];
      then
        FAILED_SERVICE[$FAILED_SERVICE_IDX]="$failed_service"
        ((FAILED_SERVICE_IDX+=1))
      fi
    fi
  done < "$FAILED_SERVICES_LIST"
  if [ $FAILED_SERVICE_IDX -gt 0 ];
  then
    e_and_l " Es wurden ${bold_yellow}$FAILED_SERVICE_IDX${colors_off} fehlerhafte System-Dienste gefunden. Dies kann zu erheblichen"
    e_and_l " Verzögerungen beim System-Start und sogar zu dessen Abbruch führen."
    ask_yes_or_no_plus "disable_failed_services" " Sollen die ${light_cyan}fehlerhaften System-Dienste${colors_off} deaktiviert werden" "" "j"
    if [ $? -eq 1 ];
    then
      for failed_service in ${FAILED_SERVICE[@]};
      do
        e_and_l "$HALF_MINUS_LINE"
        ask_yes_or_no_plus "" " Dienst ${light_cyan}$failed_service${colors_off} deaktivieren" "" "n"
        if [ $? -eq 1 ];
        then
          e_and_l -n " - Deaktiviere ${light_yellow}$failed_service${colors_off} ... "
          systemctl disable "$failed_service" &>/dev/null
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
      done
    fi
    e_and_l "$HALF_MINUS_LINE"
    e_and_l " $HINWEIS_TAG: Die Liste der fehlerhaften System-Dienste ist gespeichert in:"
    e_and_l " ${light_yellow}$FAILED_SERVICES_LIST${colors_off}"
  else
    e_and_l " Prüfung auf ${light_cyan}fehlerhafte System-Dienste${colors_off} ... $NF_TAG"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Dateisysteme${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Prüfung der (Zugriffs-)Parameter von Netzwerk-Dateisystemen
  # ============================================================================
  ACTION_MESSAGE=" Prüfe Parameter von ${light_cyan}Netzwerk-Dateisystemen${colors_off}"
  if [ -s "$ETC_FSTAB" ];
  then
    if [ $(grep -c -i -E "^\/\/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\/" "$ETC_FSTAB") -gt 0 ];
    then
      grep -i -E "^\/\/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*\/" "$ETC_FSTAB" | grep -v -i -E "noserverino" | awk '{print $1";"$2}' > "$FSTAB_NETPATH_LIST"
      if [ -s "$FSTAB_NETPATH_LIST" ];
      then
        e_and_l " $ACHTUNG_TAG: In der Dateisystem-Tabelle wurden ${light_cyan}Netzwerk-Dateisysteme${colors_off} gefunden, die"
        e_and_l " automatisch ohne den Parameter ${light_yellow}noserverino${colors_off} eingebunden werden, was in einigen"
        e_and_l " Anwendungsfällen zu Zugriffs-Problemen führt. Da die Abwesenheit dieser Option"
        e_and_l " jedoch auch beabsichtigt sein kann, werden hier keine Korrekturen angeboten."
        e_and_l " Betroffen sind folgende Einträge:"
        while read fstab_line;
        do
          if [ "$fstab_line" != "" ];
          then
            e_and_l -n " - ${light_yellow}"
            e_and_l -n $(echo -e "$fstab_line" | cut -d';' -f 1)
            e_and_l -n "${colors_off} -> ${light_magenta}"
            e_and_l -n $(echo -e "$fstab_line" | cut -d';' -f 2)
            e_and_l "${colors_off}"
          fi
        done < "$FSTAB_NETPATH_LIST"
        e_and_l "$HALF_MINUS_LINE"
      else
        e_and_l "$ACTION_MESSAGE ... $NC_TAG"
        remove_file "$FSTAB_NETPATH_LIST"
      fi
    else
      e_and_l "$ACTION_MESSAGE ... $NF_TAG"
    fi
  else
    e_and_l "$(skip_text " $ACTION_MESSAGE" "keine fstab!")"
  fi

  # ============================================================================
  # Überprüfung der Zugriffsrechte des Wurzelverzeichnis
  # ============================================================================
  e_and_l -n " Prüfe ${light_cyan}Zugriffsrechte des Wurzelverzeichnis${colors_off} ... "
  ATTRIBS_ROOT="$(ls -la / | grep -E "\s\.$" | awk '{print $1}' | sed 's/d//')"
  if [ $( echo "$ATTRIBS_ROOT" | grep -i -c -E "rwxr-xr-x") -eq 0 ];
  then
    e_and_l "$ERROR_TAG"
    e_and_l " Die Zugriffsrechte des Wurzelverzeichnis sind nicht optimal [${light_yellow}$ATTRIBS_ROOT${colors_off}]."
    ask_yes_or_no_plus "root_dir_rights" " Sollen die Rechte auf ${bold_yellow}rwxr-xr-x${colors_off} korrigiert werden " "" "j"
    if [ $? -eq 1 ];
    then
      e_and_l -n " Korrigiere ${light_cyan}Rechte des Wurzelverzeichnis${colors_off}    ... "
      chmod -R 0755 / &>"$LOG_TEMP"
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
        add_full_log
      fi
    fi
  else
    e_and_l "$NC_TAG"
  fi

  # ============================================================================
  # Zustand der Benutzer-Ordner und deren Verknüpfungen (de <-> en) ermitteln
  # ============================================================================
  FOLDERS_EXISTS=0
  FOLDERS_LINKED=0
  FOLDERS_BROKEN=0
  anz=${#FOLDER_NAME_DE[@]}
  echo -e -n > "$BROKEN_LINKS_LIST"
  i=0
  while [ $i -lt $anz ];
  do
    FULL_PATH_DE="$USER_HOME_DIR/${FOLDER_NAME_DE[$i]}"
    FULL_PATH_EN="$USER_HOME_DIR/${FOLDER_NAME_EN[$i]}"
    # ------------------------
    # Ungültige Verknüpfungen
    # ------------------------
    if [ -L "$FULL_PATH_DE" ];
    then
      THE_TARGET_PATH=$(readlink "$FULL_PATH_DE")
      if [ ! -d $THE_TARGET_PATH ] &&
         [ ! -f $THE_TARGET_PATH ] &&
         [ ! -L $THE_TARGET_PATH ];
      then
        echo -e "$FULL_PATH_DE > $THE_TARGET_PATH" >> "$BROKEN_LINKS_LIST" 2>/dev/null
        ((FOLDERS_BROKEN+=1))
      fi
    fi
    if [ -L "$FULL_PATH_EN" ];
    then
      THE_TARGET_PATH=$(readlink "$FULL_PATH_EN")
      if [ ! -d $THE_TARGET_PATH ] &&
         [ ! -f $THE_TARGET_PATH ] &&
         [ ! -L $THE_TARGET_PATH ];
      then
        echo -e "$FULL_PATH_EN > $THE_TARGET_PATH" >> "$BROKEN_LINKS_LIST" 2>/dev/null
        ((FOLDERS_BROKEN+=1))
      fi
    fi
    # ----------------------------------
    # Fehlende Ordner und Verknüpfungen
    # ----------------------------------
    if [ -d "$FULL_PATH_DE" ] ||
       [ -d "$FULL_PATH_EN" ];
    then
      ((FOLDERS_EXISTS+=1))
      if [[ -d "$FULL_PATH_DE" && -L "$FULL_PATH_EN" ]] ||
         [[ -L "$FULL_PATH_DE" && -d "$FULL_PATH_EN" ]];
      then
        ((FOLDERS_LINKED+=1))
      fi
    fi
    ((i+=1))
  done

  # ============================================================================
  # Ungültige Links zwischen Benutzer-Ordnern (deutsch <-> english) löschen
  # oder entsprechende Ordner dazu erstellen
  # -----------------------------------------------------------------------
  # Je nach Sprachumgebung bzw. nach Wechsel dieser werden (bspw. bei Ubuntu)
  # auch die Ordnernamen des Benutzers geändert. Dadurch können dann je nach
  # Zustand ungültige Verknüpfungen oder fehlende Ordner zu diesen entstehen.
  # ============================================================================
  if [ -s "$BROKEN_LINKS_LIST" ];
  then
    # -------------------------------
    # Fehlerhafte Einträge auflisten
    # -------------------------------
    e_and_l "$HALF_MINUS_LINE"
    e_and_l " $WARN_TAG! Es wurden ungültige Verknüpfungen oder Benutzer-Ordner entdeckt:"
    while read broken_line;
    do
      if [ "$broken_line" != "" ];
      then
        e_and_l " - ${broken_line/ > / -> }"
      fi
    done < "$BROKEN_LINKS_LIST"
    # --------
    # Abfrage
    # --------
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Nichts, alles so lassen wie es ist"
    e_and_l " [${bold_yellow}1${colors_off}] Die ungültigen Verknüpfungen löschen"
    e_and_l " [${bold_yellow}2${colors_off}] Fehlende Ordner zu den Verknüpfungen anlegen (${bold_white}empfohlen${colors_off})"
    user_choice_012
    LINK_ACTION=$?
    # -------------
    # Durchführung
    # -------------
    if [ $LINK_ACTION -gt 0 ];
    then
      while read broken_line;
      do
        if [ "$broken_line" != "" ];
        then
          THE_LINK_PATH="$(echo -e -n ${broken_line} | cut -d'>' -f 1 | xargs)"
          THE_TARGET_PATH="$(echo -e -n ${broken_line} | cut -d'>' -f 2 | xargs)"
          if [ "$THE_LINK_PATH" != "" ] &&
             [ "$THE_TARGET_PATH" != "" ];
          then
            # --------------------------------
            # Ungültige Verknüpfungen löschen
            # --------------------------------
            if [ $LINK_ACTION -eq 1 ];
            then
              e_and_l -n " Lösche ${light_yellow}$THE_LINK_PATH${colors_off} ... "
              remove_file "$THE_LINK_PATH" &>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
            # -----------------------------------------
            # Zu Verknüpfungen fehlende Ordner anlegen
            # -----------------------------------------
            if [ $LINK_ACTION -eq 2 ];
            then
              e_and_l -n " Erstelle ${light_yellow}$THE_TARGET_PATH${colors_off} ... "
              mkdir -p "$THE_TARGET_PATH" &>/dev/null
              if [ $? -eq 0 ];
              then
                chown -R "$USER_USERNAME:$USER_USERNAME" "$THE_TARGET_PATH" &>/dev/null
                chmod -R 0755 "$THE_TARGET_PATH" &>/dev/null
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
          fi
        fi
      done < "$BROKEN_LINKS_LIST"
    fi
    e_and_l "$HALF_MINUS_LINE"
  else
    e_and_l " Reparatur ${light_cyan}ungültiger Benutzer-Ordner/Links${colors_off} ... $NF_TAG"
  fi
  remove_file "$BROKEN_LINKS_LIST"

  # ============================================================================
  # Existierende Benutzer-Ordner zwischen deren "deutschen" und "englischen"
  # Namen gegenseitig symbolisch verlinken
  # ============================================================================
  ACTION_MESSAGE=" Benutzer-Ordner ${light_cyan}deutsch<>english${colors_off} verlinken"
  if [ $FOLDERS_LINKED -ne $FOLDERS_EXISTS ];
  then
    if [ $FOLDERS_BROKEN -eq 0 ]; then e_and_l "$HALF_MINUS_LINE"; fi
    e_and_l " Zur Verbesserung der Kompatibilität können Benutzer-Ordner in deutscher und"
    e_and_l " englischer Sprache gegenseitig mit einem symbolischen Link verknüpft werden."
    ask_yes_or_no_plus "desktop_link" "$ACTION_MESSAGE" "" "n"
    if [ $? -eq 1 ];
    then
      i=0
      while [ $i -lt $anz ];
      do
        NAME_DE="${FOLDER_NAME_DE[$i]}"
        NAME_EN="${FOLDER_NAME_EN[$i]}"
        FULL_PATH_DE="$USER_HOME_DIR/$NAME_DE"
        FULL_PATH_EN="$USER_HOME_DIR/$NAME_EN"
        TARGET_NAME=""
        LINK_NAME=""
        if [ -d "$FULL_PATH_DE" ] &&
           [ ! -L "$FULL_PATH_DE" ];
        then
          TARGET_NAME="$NAME_DE"
          LINK_NAME="$NAME_EN"
        fi
        if [ -d "$FULL_PATH_EN" ] &&
           [ ! -L "$FULL_PATH_EN" ];
        then
          TARGET_NAME="$NAME_EN"
          LINK_NAME="$NAME_DE"
        fi
        TARGET_PATH="$USER_HOME_DIR/$TARGET_NAME"
        LINK_PATH="$USER_HOME_DIR/$LINK_NAME"
        if [ "$TARGET_NAME" != "" ] &&
           [ -d "$TARGET_PATH" ] &&
           [ "$LINK_NAME" != "" ] &&
           [ ! -d "$LINK_PATH" ] &&
           [ ! -f "$LINK_PATH" ] &&
           [ ! -L "$LINK_PATH" ];
        then
          e_and_l -n " Verknüpfe ${light_yellow}$LINK_PATH${colors_off} -> $TARGET_PATH ... "
          ln -s "$TARGET_PATH" "$LINK_PATH" &>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "$LINK_PATH" &>/dev/null
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
        ((i+=1))
      done
    fi
    e_and_l "$HALF_MINUS_LINE"
  else
    e_and_l "$ACTION_MESSAGE ... $NC_TAG"
  fi

  # ============================================================================
  # Alle eigenen Dateien auch zu eigen machen (all my files belong to me ;)
  # ============================================================================
  ACTION_MESSAGE=" Besitz-Zuordnungen ${light_cyan}eigener Dateien${colors_off} prüfen"
  if [ "$USER_USERNAME" != "root" ] &&
     [ $USER_UID -ge 1000 ];
  then
    e_and_l -n " Korrigiere ${light_cyan}Besitzzuordnung${colors_off} eigener Dateien ... "
    if [ $(find "$USER_HOME_DIR" ! -user "$USER_USERNAME" | wc -l) -gt 1 ];
    then
      chown -R "$USER_USERNAME:$USER_USERNAME" "$USER_HOME_DIR" &>"$LOG_TEMP"
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
        add_full_log
      fi
    else
      e_and_l "$NC_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE " "$NR_TXT")"
  fi

  # ============================================================================
  # Pakete
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Pakete${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Pakete mit fehlerhaften Abhängigkeiten
  # ============================================================================
  ACTION_MESSAGE=" Reparatur von ${light_cyan}fehlerhaften Abhängigkeiten${colors_off}  ... "
  apt list ?broken 2>/dev/null | grep -oP '^(.*)(?=/)' > "$PKG_BROKEN_LIST"
  if [ -s "$PKG_BROKEN_LIST" ];
  then
    PKG_BROKEN_ARRAY=()
    while read pkg;
    do
      if [ "$pkg" != "" ];
      then
        PKG_BROKEN_ARRAY+=("$pkg")
      fi
    done < "$PKG_BROKEN_LIST"
    e_and_l " Es wurden ${bold_yellow}${#PKG_BROKEN_ARRAY[@]}${colors_off} Pakete mit ${light_cyan}fehlerhaften Abhängigkeiten${colors_off} gefunden."
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts reparieren und Liste als Datei speichern"
    e_and_l " [${bold_yellow}1${colors_off}] Jedes Paket einzeln jeweils mit Abfrage reparieren"
    e_and_l " [${bold_yellow}2${colors_off}] Alle Pakete ohne einzelne Abfragen reparieren"
    user_choice_012
    REPAIR_MODE=$?
    if [ $REPAIR_MODE -gt 0 ];
    then
      # ----------------------------------------------------
      # Sicherheitsabfrage wenn alle gelöscht werden sollen
      # ----------------------------------------------------
      if [ $REPAIR_MODE -eq 2 ];
      then
        e_and_l " Folgende Pakete mit fehlerhaften Abhängigkeiten wurden gefunden:"
        for pkg in "${PKG_BROKEN_ARRAY[@]}";
        do
          e_and_l " - ${light_cyan}$pkg${colors_off}"
        done
        ask_yes_or_no_plus "" " Jetzt wirklich ${bold_cyan}alle${colors_off} vorstehenden Abhängigkeiten reparieren" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REPAIR_MODE=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------------
      if [ $REPAIR_MODE -gt 0 ];
      then
        e_and_l -n " Vorbereitung des Reparatur-Vorgangs, bitte warten ... "
        apt clean &>/dev/null
        apt autoclean &>/dev/null
        e_and_l "$OK_TAG"
        e_and_l "$HALF_MINUS_LINE"
        for pkg in "${PKG_BROKEN_ARRAY[@]}";
        do
          DO_REPAIR_THIS=1
          if [ $REPAIR_MODE -eq 1 ];
          then
            e_and_l " Paket ${light_cyan}$pkg${colors_off}"
            ask_yes_or_no_plus "" " Reparieren" "" "n"
            DO_REPAIR_THIS=$?
          fi
          if [ $DO_REPAIR_THIS -eq 1 ];
          then
            e_and_l -n " Repariere ${light_yellow}$pkg${colors_off} ... "
            apt --fix-broken install "$pkg" -y &>/dev/null
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        done
      fi
      remove_file "$PKG_BROKEN_LIST"
    else
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste der fehlerhaften Abhängigkeiten ist gespeichert in:"
      e_and_l " ${light_yellow}$PKG_BROKEN_LIST${colors_off}"
    fi
  else
    remove_file "$PKG_BROKEN_LIST"
    e_and_l "$ACTION_MESSAGE$NF_TAG"
  fi

  # ============================================================================
  # Paketquellen
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Paketquellen${colors_off}"
  e_and_l "$HALF_LINE"

  # Temporäre Dateien zum Bearbeiten der Quell-Listen
  ALL_SOURCE_FILES="$DOWNLOAD_DIR/all_source_files.tmp" # Liste aller Dateien mit Quellen
  ALL_SOURCES_LIST="$DOWNLOAD_DIR/all_sources_list.tmp" # Liste aller Quell-Angaben

  # ============================================================================
  # Letzte internen Arbeitslisten löschen
  # ============================================================================
  remove_file "$ALL_SOURCE_FILES"
  remove_file "$ALL_SOURCES_LIST"

  # ============================================================================
  # Prüfung auf abgelaufene APT-Key-Signaturen (Authentifizierungs-Schlüssel)
  # ============================================================================
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}abgelaufene APT-Key-Signaturen${colors_off} ... "
  apt-key list &>/dev/null
  if [ $? -eq 0 ];
  then
    e_and_l -n "$ACTION_MESSAGE"
    LANG=C apt-key list 2>/dev/null | grep -A 2 -i -E "(expired|verfallen):" | awk 'NR>1' | \
    sed 's/^[[:space:]]*/ /g' | sed 's/[[:space:]]*uid.*\][[:space:]]*/ /gi' > "$EXPIRED_APT_KEYS_LIST"
    if [ -s "$EXPIRED_APT_KEYS_LIST" ];
    then
      e_and_l "$WARN_TAG"
      e_and_l " Folgende APT-Signaturen sind ${bold_red}abgelaufen${colors_off} und damit ungültig:"
      declare -A APT_EXP_KEY
      declare -A APT_EXP_DSC
      APT_KEY_IDX=1
      while read expired_key;
      do
        read key_description
        APT_EXP_KEY["$APT_KEY_IDX"]="$expired_key"
        APT_EXP_DSC["$APT_KEY_IDX"]="$key_description"
        ((APT_KEY_IDX+=1))
      done < "$EXPIRED_APT_KEYS_LIST"
      knr=1
      e_and_l "$HALF_MINUS_LINE"
      while [ $knr -lt $APT_KEY_IDX ];
      do
        expired_key="${APT_EXP_KEY[$knr]}"
        key_description="${APT_EXP_DSC[$knr]}"
        e_and_l " - $key_description"
        e_and_l "   Schlüssel ${bold_white}$expired_key${colors_off}"
        RAW_APT_KEY="${expired_key// /}"
        ask_yes_or_no_plus "" "   Soll der Schlüssel ${light_yellow}erneuert${colors_off} werden" "" "j"
        KEY_RENEW=$?
        if [ $KEY_RENEW -eq 1 ];
        then
          e_and_l -n "   Versuche den alten Schlüssel zu erneuern ... "
          apt-key adv --recv-keys --keyserver keys.gnupg.net "$RAW_APT_KEY" &>"$LOG_TEMP"
          if [ $? -eq 0 ];
          then
            e_and_l "$OK_TAG"
          else
            apt-key adv --recv-keys --keyserver keyserver.ubuntu.com "$RAW_APT_KEY" &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              KEY_RENEW=0
              add_full_log
            fi
          fi
          # Wenn ein neuer Schlüssel hinzugefügt wurde, dann den verfallenen automatisch löschen,
          # sonst, wenn der Schlüssel nicht erneuert werden kann, anbieten ihn selbst zu löschen
          if [ $KEY_RENEW -eq 1 ];
          then
            apt-key del "$RAW_APT_KEY" &>/dev/null
          fi
        fi
        if [ $KEY_RENEW -eq 0 ];
        then
          ask_yes_or_no_plus "" "   Soll der Schlüssel ${light_yellow}gelöscht${colors_off} werden" "" ""
          if [ $? -eq 1 ];
          then
            e_and_l -n "   Versuche den alten Schlüssel zu löschen  ... "
            apt-key del "$RAW_APT_KEY" &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
        fi
        ((knr+=1))
        e_and_l "$HALF_MINUS_LINE"
      done
      e_and_l " $HINWEIS_TAG: Die Liste der abgelaufenen APT-Key-Signaturen ist gespeichert in:"
      e_and_l " ${light_yellow}$EXPIRED_APT_KEYS_LIST${colors_off}"
      e_and_l "$HALF_LINE"
    else
      remove_file "$EXPIRED_APT_KEYS_LIST"
      e_and_l "$NF_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  # ============================================================================
  # Prüfung auf veraltete APT-Key-Eintragungen
  # ============================================================================
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}veraltete APT-Key-Eintragungen${colors_off} ... "
  apt-key list &>/dev/null
  if [ $? -eq 0 ];
  then
    e_and_l -n "$ACTION_MESSAGE"
    OLD_APT_KEY_FILE="$APT_SOURCES_MAIN_DIR/trusted.gpg"
    NEW_APT_KEY_DIR="$APT_SOURCES_MAIN_DIR/trusted.gpg.d"
    if [ -s "$OLD_APT_KEY_FILE" ] &&
      [ -d "$NEW_APT_KEY_DIR" ];
    then
      create_backup_file "$OLD_APT_KEY_FILE"
      TMP_APT_KEY_FILE="old-apt-keys.txt"
      TMP_APT_KEY_LIST="$DOWNLOAD_DIR/$TMP_APT_KEY_FILE"
      LANG=C apt-key --keyring "$OLD_APT_KEY_FILE" list 2>/dev/null | grep -A 2 -i -E "^pub" | grep -v -i -E "^pub" | grep -v -i -E "^\s*-" | \
      sed 's/^[[:space:]]*/ /g' | sed 's/[[:space:]]*uid.*\][[:space:]]*/ /gi' > "$TMP_APT_KEY_LIST"
      if [ -s "$TMP_APT_KEY_LIST" ];
      then
        declare -A APT_TMP_KEY
        declare -A APT_TMP_DSC
        APT_KEY_IDX=1
        while read old_key;
        do
          THE_OLD_KEY=$(echo $old_key | sed 's/ //g')
          read THE_KEY_DESC
          THE_KEY_DESC="${THE_KEY_DESC%%\<*}"
          THE_KEY_DESC=$(echo "$THE_KEY_DESC" | xargs)
          if [ "$THE_OLD_KEY" != "" ] &&
             [ "$THE_KEY_DESC" != "" ];
          then
            APT_TMP_KEY["$APT_KEY_IDX"]="$THE_OLD_KEY"
            APT_TMP_DSC["$APT_KEY_IDX"]="$THE_KEY_DESC"
            ((APT_KEY_IDX+=1))
          fi
        done < "$TMP_APT_KEY_LIST"
        if [ $APT_KEY_IDX -gt 1 ];
        then
          e_and_l "$WARN_TAG"
          e_and_l " Es wurden veraltete Einträge gefunden. Es wird empfohlen, die folgenden"
          e_and_l " Einträge in ein neues Format umzuwandeln (bitte jeweils auswählen):"
          knr=1
          e_and_l "$HALF_MINUS_LINE"
          while [ $knr -lt $APT_KEY_IDX ];
          do
            THE_OLD_KEY="${APT_TMP_KEY[$knr]}"
            THE_KEY_DESC="${APT_TMP_DSC[$knr]}"
            ask_yes_or_no_plus "" " - $THE_KEY_DESC" "" "j"
            if [ $? -eq 1 ];
            then
              NEW_APT_FILE_NAME=$(echo "$THE_KEY_DESC" | tr A-Z a-z | sed 's/(//g' | sed 's/)//g' | xargs | sed 's/ /-/g')
              if [ "$NEW_APT_FILE_NAME" != "" ];
              then
                NEW_APT_FILE_NAME+=".asc"
                if [ ! -s "$NEW_APT_KEY_DIR/$NEW_APT_FILE_NAME" ];
                then
                  e_and_l -n " Neuer Schlüssel: ${bold_white}$NEW_APT_FILE_NAME${colors_off} ... "
                  apt-key export "$THE_OLD_KEY" > "$NEW_APT_KEY_DIR/$NEW_APT_FILE_NAME" 2>"$LOG_TEMP"
                  if [ $? -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                    e_and_l -n " Lösche veralteten Schlüssel ... "
                    apt-key --keyring "$OLD_APT_KEY_FILE" del "$THE_OLD_KEY" &>"$LOG_TEMP"
                    if [ $? -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                  else
                    e_and_l "$ERROR_TAG"
                  fi
                else
                  e_and_l " $ERROR_TAG: Die neue Schlüssel-Datei $NEW_APT_KEY_DIR/$NEW_APT_FILE_NAME existiert schon."
                  ask_yes_or_no_plus "" " Den veralteten Schlüssel löschen" "" "n"
                  if [ $? -eq 1 ];
                  then
                    e_and_l -n " Lösche veralteten Schlüssel ... "
                    apt-key --keyring "$OLD_APT_KEY_FILE" del "$THE_OLD_KEY" &>"$LOG_TEMP"
                    if [ $? -eq 0 ];
                    then
                      e_and_l "$OK_TAG"
                    else
                      e_and_l "$ERROR_TAG"
                    fi
                  fi
                fi
              else
                e_and_l " $ERROR_TAG $LINENO"
              fi
            fi
            e_and_l "$HALF_MINUS_LINE"
            ((knr+=1))
          done
          add_full_log
        else
          remove_file "$TMP_APT_KEY_LIST"
          e_and_l "$NF_TAG"
        fi
      else
        remove_file "$TMP_APT_KEY_LIST"
        e_and_l "$NF_TAG"
      fi
    else
      e_and_l "$NF_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi

  # ============================================================================
  # Liste aller Dateien mit Quell-Angaben erstellen
  # ============================================================================
  if [ -s "$APT_SOURCES_LIST_FILE" ];
  then
    echo "$APT_SOURCES_LIST_FILE" > "$ALL_SOURCE_FILES"
  fi
  if [ -d "$APT_SOURCES_LIST_DIR" ];
  then
    find "$APT_SOURCES_LIST_DIR" -type f -not -iname '*.bak' -and -not -iname '*.dpkg-old' -and -not -iname '*.orig' -and -not -iname '*.save' >> "$ALL_SOURCE_FILES" 2>/dev/null
  fi

  # ============================================================================
  # Liste aller Quell-Angaben aus den Quell-Dateien erstellen und diese dabei
  # um überflüssige Leerstellen bereinigen, damit auch redundante Einträge
  # sicher gefunden werden, die sich ev. nur durch Leerzeichen unterscheiden
  # ============================================================================
  if [ -s "$ALL_SOURCE_FILES" ];
  then
    while read file_path;
    do
      # Wichtig: \- ans Ende des regulären Ausdrucks ;)
      SRC_ENTRY=$(grep -i -E "^[^ *#].*http[a-z0-9 \/\.\:\_\-]*" ${file_path} | sed -E "s/.*(http[^\#]*).*/\1/gi" | sed -E "s/[[:space:]]*[[:space:]]/ /g")
      if [ "$SRC_ENTRY" != "" ];
      then
        echo "$SRC_ENTRY" >> "$ALL_SOURCES_LIST" 2>/dev/null
      fi
    done < "$ALL_SOURCE_FILES"
  fi

  # ============================================================================
  # Redundante Einträge aus der Gesamtliste (NICHT den Quelldateien) entfernen
  # Hinweis: NICHT sort -u verwenden, da "sort" die Reihenfolge der Zeilen
  # ändert und auch nicht "uniq", da dies nur direkte Nachbarn entfernt ;)
  # ============================================================================
  THE_TEMP_FILE="$DOWNLOAD_DIR/tmp_sources_list.tmp"
  if [ -s "$ALL_SOURCES_LIST" ];
  then
    awk '!seen[$0]++' "$ALL_SOURCES_LIST" > "$THE_TEMP_FILE" 2>/dev/null
    remove_file "$ALL_SOURCES_LIST"
    mv -f "$THE_TEMP_FILE" "$ALL_SOURCES_LIST" &>/dev/null
  fi

  # ============================================================================
  # Verbliebene Quell-Angaben verarbeiten
  # ============================================================================
  ACTION_MESSAGE=" Prüfung auf ${light_cyan}redundante Paket-Quell-Angaben${colors_off} ... "
  if [ -s "$ALL_SOURCES_LIST" ];
  then
    # SOURCES_URI_LIST="$DOWNLOAD_DIR/sources_uri_list.tmp"
    # remove_file "$SOURCES_URI_LIST"
    # --------------------------------------------------------------------------
    # Äußere Schleife durch alle Quell-Angaben
    # --------------------------------------------------------------------------
    e_and_l -n "$ACTION_MESSAGE"
    REDUNDANT_FOUND=0
    while read source_entry;
    do
      # ------------------------------------------------------------------------
      # Innere Schleife durch alle Dateien
      # ------------------------------------------------------------------------
      # 1. Prüfen ob Redundanzen vorhanden sind
      # ----------------------------------------
      REG_EXP="^[^\s*#].*${source_entry}"
      ENTRIES_FOUND=0
      while read source_file;
      do
        if [ $(grep -i -c -E "$REG_EXP" "$source_file" 2>/dev/null) -gt 0 ];
        then
          ((ENTRIES_FOUND+=1))
        fi
      done < "$ALL_SOURCE_FILES"
      # ----------------------------------------------------------------------
      # 2. Wenn Redundanzen gefunden wurden, dann betroffene Dateien anzeigen
      # ----------------------------------------------------------------------
      if [ $ENTRIES_FOUND -gt 1 ];
      then
        if [ $REDUNDANT_FOUND -eq 0 ];
        then
          e_and_l "$WARN_TAG"
          e_and_l " Es wurden Redundanzen oder Unstimmigkeiten gefunden, die nicht eindeutig"
          e_and_l " automatisiert bereinigt werden können - daher ggf. bitte manuell ändern."
          REDUNDANT_FOUND=1
        fi
        e_and_l " Eintrag ${bold_yellow}$source_entry${colors_off}"
        e_and_l " ist enthalten in den Dateien:"
        while read source_file;
        do
          if [ $(grep -i -c -E "$REG_EXP" "$source_file" 2>/dev/null) -gt 0 ];
          then
            e_and_l " - $source_file"
          fi
        done < "$ALL_SOURCE_FILES"
        e_and_l "$HALF_LINE"
      fi
      # ------------------------------------------------------------------------
    done < "$ALL_SOURCES_LIST" # Ende äußere Schleife durch alle Quell-Angaben
    if [ $REDUNDANT_FOUND -eq 0 ];
    then
      e_and_l "$NF_TAG"
    fi

    # ==========================================================================
    # Prüfung der Erreichbarkeit der Server
    # ==========================================================================
    if [ -s "$ALL_SOURCES_LIST" ];
    then
      e_and_l "$HALF_LINE"
      ask_yes_or_no_plus "chkpkgsrv" " Prüfung der ${light_cyan}Erreichbarkeit der Paketserver${colors_off}" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l " Prüfe die ${light_yellow}Erreichbarkeit der Paketserver${colors_off}:"
        # ----------------------------------------------------------------------
        # Ermittlung des längsten Namens
        # ----------------------------------------------------------------------
        MAX_NAME_LENGTH=0
        MAX_STRING_LENGTH=57
        while read src_uri;
        do
          FULL_URI_LENGTH=${#src_uri}
          FULL_DOMAIN=$(echo "$src_uri" | sed -E "s/^\s*(http[a-z0-9\/\.\:\_\-]*)\s*.*/\1/gi")
          FULL_DOMAIN_LENGTH=${#FULL_DOMAIN}
          DOMAIN_PART=$(echo "$FULL_DOMAIN" | sed -E "s/.*http[s]*\:\/\///gi" | sed -E "s/[\/]*$//g" | awk -F/ '{print $1}' | xargs 2>/dev/null)
          DOMAIN_PART_LENGTH=${#DOMAIN_PART}
          OPTION_PART_LENGTH=$((FULL_URI_LENGTH - FULL_DOMAIN_LENGTH))
          OPTION_PART=$(echo ${src_uri:$FULL_DOMAIN_LENGTH:$OPTION_PART_LENGTH} | xargs 2>/dev/null)
          if [ $((DOMAIN_PART_LENGTH+OPTION_PART_LENGTH)) -gt $MAX_STRING_LENGTH ];
          then
            OPTION_PART_LENGTH=$((MAX_STRING_LENGTH-DOMAIN_PART_LENGTH))
          fi
          ((FULL_NAME_LENGTH=DOMAIN_PART_LENGTH+OPTION_PART_LENGTH))
          if [ $FULL_NAME_LENGTH -gt $MAX_NAME_LENGTH ];
          then
            MAX_NAME_LENGTH=$FULL_NAME_LENGTH
          fi
        done < "$ALL_SOURCES_LIST"
        ((MAX_NAME_LENGTH+=2))
        # ----------------------------------------------------------------------
        # Testen der Erreichbarkeit
        # ----------------------------------------------------------------------
        while read src_uri;
        do
          if [ "$src_uri" != "" ];
          then
            FULL_URI_LENGTH=${#src_uri}
            FULL_DOMAIN=$(echo "$src_uri" | sed -E "s/^\s*(http[a-z0-9\/\.\:\_\-]*)\s*.*/\1/gi")
            FULL_DOMAIN_LENGTH=${#FULL_DOMAIN}
            DOMAIN_PART=$(echo "$FULL_DOMAIN" | sed -E "s/.*http[s]*\:\/\///gi" | sed -E "s/[\/]*$//g" | awk -F/ '{print $1}' | xargs 2>/dev/null)
            DOMAIN_PART_LENGTH=${#DOMAIN_PART}
            OPTION_PART_LENGTH=$((FULL_URI_LENGTH - FULL_DOMAIN_LENGTH))
            OPTION_PART=$(echo ${src_uri:$FULL_DOMAIN_LENGTH:$OPTION_PART_LENGTH} | xargs 2>/dev/null)
            if [ $((DOMAIN_PART_LENGTH+OPTION_PART_LENGTH)) -gt $MAX_STRING_LENGTH ];
            then
              SUB_MAX_LENGTH=$((MAX_STRING_LENGTH-DOMAIN_PART_LENGTH))
              if [ $SUB_MAX_LENGTH -le 0 ];
              then
                OPTION_PART=""
              else
                OPTION_PART=${OPTION_PART:0:$SUB_MAX_LENGTH}
              fi
            fi
            e_and_l -n " - ${bold_white}$DOMAIN_PART${colors_off} "
            if [ "$OPTION_PART" != "" ];
            then
              e_and_l -n "($OPTION_PART)"
            else
              e_and_l -n " "
            fi
            ((ANZ_SPACES=MAX_NAME_LENGTH-DOMAIN_PART_LENGTH-OPTION_PART_LENGTH-1))
            insert_spaces $ANZ_SPACES
            e_and_l -n " ... "
            TEST_FILE="$DOWNLOAD_DIR/download_test.tmp"
            remove_file "$TEST_FILE"
            TARGET_REACHED=0
            # Test 1 mit Download von vollem Pfad
            wget -nv -O "$TEST_FILE" "$FULL_DOMAIN" &>/dev/null
            if [ -s "$TEST_FILE" ];
            then
              TARGET_REACHED=1
            else
              # Test 2 nur auf die Domain (falls wget abgewiesen wird)
              ping -c 1 "$DOMAIN_PART" &>/dev/null
              if [ $? -eq 0 ];
              then
                TARGET_REACHED=2
              fi
            fi
            if [ $TARGET_REACHED -gt 0 ];
            then
              e_and_l -n "$OK_TAG"
              if [ $TARGET_REACHED -eq 2 ];
              then
                e_and_l " ${dark_gray}(Domain)${colors_off}"
              else
                e_and_l ""
              fi
            else
              e_and_l "$ERROR_TAG"
              e_and_l "   Enthalten in Datei(en):"
              while read source_file;
              do
                if [ $(grep -i -c -E "$src_uri" "$source_file" 2>/dev/null) -gt 0 ];
                then
                  e_and_l "   $source_file"
                fi
              done < "$ALL_SOURCE_FILES"
            fi
            remove_file "$TEST_FILE"
          fi
        done < "$ALL_SOURCES_LIST"
      fi
    fi
  else # Keine Paketquellen gefunden
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NA_TXT")"
  fi
  # ============================================================================
  # Temporäre Dateien löschen
  # ============================================================================
  remove_file "$THE_TEMP_FILE"
  remove_file "$ALL_SOURCES_LIST"
  remove_file "$ALL_SOURCE_FILES"
  # remove_file "$SOURCES_URI_LIST"

  # ============================================================================
  # Aktualisierung des Linux Mint Update Management
  # ============================================================================
  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Linux Mint Update Management${colors_off}"
  e_and_l "$HALF_LINE"
  ACTION_MESSAGE=" Aktualisierung des Mint Update Managements"
  if [ $(echo "$OPERATION_SYSTEM" | grep -i -c -E " mint ") -gt 0 ];
  then
    CHANGES_MADE=0
    declare -A MINT_UPDATE_PKG_LIST
    declare -A MINT_UPDPKG_NAM_LIST
    MINT_UPDATE_PKG_LIST[0]="mintupdate"
    MINT_UPDPKG_NAM_LIST[0]="Linux Mint Update Manager"
    MINT_UPDATE_PKG_LIST[1]="mint-upgrade-info"
    MINT_UPDPKG_NAM_LIST[1]="Linux Mint Upgrade Inform"
    i=0
    while [ $i -lt ${#MINT_UPDATE_PKG_LIST[@]} ];
    do
      MINT_UPDATE_PKG="${MINT_UPDATE_PKG_LIST[$i]}"
      MINT_UPDPKG_NAM="${MINT_UPDPKG_NAM_LIST[$i]}"
      if [ $(LANG=C dpkg-query -W -f='${Status}' "$MINT_UPDATE_PKG" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
      then
        if [ $(LANG=C apt list "$MINT_UPDATE_PKG" 2>/dev/null | grep -i -c -E "upgradable") -gt 0 ];
        then
          e_and_l " Es ist eine neuere Version von ${bold_white}$MINT_UPDPKG_NAM${colors_off} verfügbar."
          ask_yes_or_no_plus "mint_update" " Jetzt ${light_cyan}$MINT_UPDPKG_NAM${colors_off} aktualisieren" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Aktualisiere ${light_yellow}$MINT_UPDPKG_NAM${colors_off} ... "
            apt install "$MINT_UPDATE_PKG" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
          fi
        else # Paket ist aktuell
          e_and_l " ${light_cyan}$MINT_UPDPKG_NAM${colors_off} ist aktuell ... $NC_TAG"
        fi
      else # Paket ist nicht installiert
        if [ $(apt list "$MINT_UPDATE_PKG" 2>/dev/null | grep -i -c -E "$MINT_UPDATE_PKG") -gt 0 ];
        then
          e_and_l " $HINWEIS_TAG: ${bold_white}$MINT_UPDPKG_NAM${colors_off} ist nicht installiert."
          ask_yes_or_no_plus "" " Jetzt ${light_cyan}$MINT_UPDPKG_NAM${colors_off} installieren" "" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Installiere ${light_yellow}$MINT_UPDPKG_NAM${colors_off} ... "
            apt install "$MINT_UPDATE_PKG" -y &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              e_and_l "$OK_TAG"
              CHANGES_MADE=1
            else
              e_and_l "$ERROR_TAG"
            fi
            add_full_log
          fi
        else # Paket ist nicht verfügbar
          e_and_l "$(skip_text " $MINT_UPDPKG_NAM" "$NA_TXT")"
        fi
      fi
      ((i+=1))
    done
    if [ $CHANGES_MADE -gt 0 ];
    then
      repo_update " Aktualisiere das Repository, bitte warten ... "
    fi
  else # Kein Linux Mint
    e_and_l "$(skip_text "$ACTION_MESSAGE" "kein Linux Mint")"
  fi

  # ============================================================================
  # Löschen veralteter APT-Paket-Listen und APT-Cache-Dateien
  # ============================================================================
  e_and_l "$HALF_LINE"
  ask_yes_or_no_plus "apt_clear_all" " Den ${light_cyan}APT-Zwischenspeicher${colors_off} und ${light_cyan}Paket-Listen${colors_off} erneuern" "" "n"
  if [ $? -eq 1 ];
  then
    # Nur weitermachen, wenn nicht gerade eine andere dpkg-Aktion läuft
    if [ ! -s "/var/lib/dpkg/lock" ] &&
       [ ! -s "/var/lib/dpkg/lock-frontend" ];
    then
      # Löschen der APT-Paket-Listen
      if [ -d "/var/lib/apt/lists" ];
      then
        e_and_l -n " - Löschen der veralteten ${light_yellow}APT-Paket-Listen${colors_off}  ... "
        rm -f /var/lib/apt/lists/* &>"$LOG_TEMP"
        e_and_l "$OK_TAG"
        add_full_log
      fi
      # Löschen veralteter APT-Cache-Dateien
      e_and_l -n " - Löschen der veralteten ${light_yellow}APT-Cache-Dateien${colors_off} ... "
      apt-get clean &>"$LOG_TEMP"
      if [ $? -eq 0 ];
      then
        apt-get autoclean &>>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG $LINENO"
        fi
      else
        e_and_l "$ERROR_TAG $LINENO"
      fi
      add_full_log
      # Repository aktualisieren und Paketlisten neu erstellen
      repo_update " - Erneuerung des ${light_yellow}Repository${colors_off}, bitte warten  ... "
    else
      e_and_l " $ERROR_TAG: ${bold_white}apt${colors_off} ist gerade durch einen anderen Prozess geblockt (Update?), eine"
      e_and_l " Bereinigung daher derzeit ${bold_red}nicht${colors_off} möglich - bitte später nochmals versuchen."
    fi
  fi

fi # Ende [repair]

# ==============================================================================
# Bereinigung des Systems
# ==============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[cleansys]} -eq 1 ];
then

  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Bereinigung des Systems${colors_off} ${dark_gray}[cleansys]${colors_off}"
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Kernel${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Löschen nicht verwendeter Kernel-Versionen
  # ============================================================================
  # ----------------------------------------------------------------------------
  # Nicht verwendete Kernel-Versionen ermitteln
  # ----------------------------------------------------------------------------
  echo $(dpkg -l linux-{image,headers}-"[0-9]*" 2>/dev/null | awk '/ii/{print $2}' | grep -v "$CURRENT_KERNEL_VERSION") > "$OLD_KERNEL_LIST"
  declare -A REMOVE_KERNEL_TABLE
  REMOVE_KERNEL_IDX=0
  while read old_kernel;
  do
    kernel_base_name="$(echo ${old_kernel} | sed 's/linux-image-//i' | sed 's/linux-headers-//i' | sed 's/-generic//i' | sed 's/-common//i' | sed 's/-amd64//i' | sed 's/-i386//i')"
    if [ "$kernel_base_name" != "" ] &&
       [ "$kernel_base_name" != "$CURRENT_KERNEL_VERSION" ];
    then
      if [ $(LANG=C dpkg-query -W -f='${Status}' "$old_kernel" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ] ||
         [ $(grep -i -r -l -E "$kernel_base_name" /boot/efi 2>/dev/null | wc -l) -ne 0 ] ||
         [ $(grep -i -r -l -E "$kernel_base_name" /boot/grub 2>/dev/null | wc -l) -ne 0 ] ||
         [ $(ls -la /boot/initrd.img 2>/dev/null | grep -c -E "$kernel_base_name") -ne 0 ] ||
         [ $(ls -la /boot/vmlinuz 2>/dev/null | grep -c -E "$kernel_base_name") -ne 0 ];
      then
        REMOVE_KERNEL_TABLE[$REMOVE_KERNEL_IDX]="$old_kernel"
        ((REMOVE_KERNEL_IDX+=1))
      fi
    fi
  done < "$OLD_KERNEL_LIST"
  # ----------------------------------------------------------------------------
  # Wenn Einträge gefunden wurden, dann diese einzeln mit Abfrage löschen
  # ----------------------------------------------------------------------------
  if [ -s "$OLD_KERNEL_LIST" ] &&
     [ $REMOVE_KERNEL_IDX -gt 0 ];
  then
    e_and_l " Es wurden ${bold_yellow}$REMOVE_KERNEL_IDX${colors_off} Einträge von ${light_cyan}nicht verwendeten Kernel-Versionen${colors_off} gefunden."
    e_and_l " Die aktuell verwendete Version ist: ${bold_white}$CURRENT_KERNEL_VERSION${colors_off}"
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen und Liste als Datei speichern"
    e_and_l " [${bold_yellow}1${colors_off}] Jede Komponente einzeln jeweils mit Abfrage löschen"
    e_and_l " [${bold_yellow}2${colors_off}] Alle Komponenten ohne einzelne Abfragen löschen"
    user_choice_012
    REMOVE_MODE=$?
    if [ $REMOVE_MODE -gt 0 ];
    then
      # ----------------------------------------------------
      # Sicherheitsabfrage wenn alle gelöscht werden sollen
      # ----------------------------------------------------
      if [ $REMOVE_MODE -eq 2 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        e_and_l " Folgende nicht verwendete Kernel-Komponenten wurden gefunden:"
        for old_kernel in ${REMOVE_KERNEL_TABLE[@]};
        do
          e_and_l " - ${light_cyan}$old_kernel${colors_off}"
        done
        e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Jetzt wirklich ${bold_red}alle${colors_off} vorstehenden Komponenten löschen" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REMOVE_MODE=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------------
      if [ $REMOVE_MODE -gt 0 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        kernel_changed=0
        for old_kernel in ${REMOVE_KERNEL_TABLE[@]};
        do
          DO_REMOVE_THIS=1
          if [ $REMOVE_MODE -eq 1 ];
          then
            e_and_l -n " Komponente ${light_cyan}$old_kernel${colors_off}"
            ask_yes_or_no_plus "" " löschen" "" "n"
            DO_REMOVE_THIS=$?
          fi
          if [ $DO_REMOVE_THIS -eq 1 ];
          then
            # ----------------------
            # Kernel selbst löschen
            # ----------------------
            e_and_l -n " Lösche ${light_yellow}$old_kernel${colors_off} ... "
            apt-get purge -y "$old_kernel" &>"$LOG_TEMP"
            if [ $? -eq 0 ];
            then
              # ----------------------------------------
              # Verbliebene Komponenten löschen, sofern
              # diese nicht mehr gebraucht werden
              # ----------------------------------------
              kernel_base_name="$(echo ${old_kernel} | sed 's/linux-image-//i' | sed 's/linux-headers-//i')"
              kernel_config_file="/boot/config-$kernel_base_name"
              if [ -f "$kernel_config_file" ];
              then
                # e_and_l " Removing $kernel_config_file"
                remove_file "$kernel_config_file"
              fi
              kernel_initrd_file="/boot/initrd.img-$kernel_base_name"
              if [ -f "$kernel_initrd_file" ];
              then
                # e_and_l " Removing $kernel_initrd_file"
                remove_file "$kernel_initrd_file"
              fi
              kernel_sysmap_file="/boot/System.map-$kernel_base_name"
              if [ -f "$kernel_sysmap_file" ];
              then
                # e_and_l " Removing $kernel_sysmap_file"
                remove_file "$kernel_sysmap_file"
              fi
              kernel_vmlinuz_file="/boot/vmlinuz-$kernel_base_name"
              if [ -f "$kernel_vmlinuz_file" ];
              then
                # e_and_l " Removing $kernel_vmlinuz_file"
                remove_file "$kernel_vmlinuz_file"
              fi
              e_and_l "$OK_TAG"
              ((kernel_changed+=1))
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        done
        # ------------------------------------------------------------------------
        # Wenn Einträge gelöscht wurden, initramfs und Boot-Loader aktualisieren
        # ------------------------------------------------------------------------
        if [ $kernel_changed -gt 0 ];
        then
          e_and_l " Es wurden ${light_yellow}$kernel_changed${colors_off} Einträge gelöscht."
          if update-grub --help &>/dev/null;
          then
            INIT_GRUB_QUESTION_1="Sollen ${light_cyan}initramfs${colors_off} und ${light_cyan}GRUB-Loader${colors_off}"
            INIT_GRUB_QUESTION_2=" und ${bold_white}GRUB-Loader${colors_off}"
          else
            INIT_GRUB_QUESTION_1="Soll das ${light_cyan}initramfs${colors_off}"
            INIT_GRUB_QUESTION_2=""
          fi
          ask_yes_or_no_plus "" " $INIT_GRUB_QUESTION_1 erneuert werden" "" "j"
          if [ $? -eq 1 ];
          then
            e_and_l " $ACHTUNG_TAG: Dadurch werden Dateien im Boot-Bereich des Systems verändert, was"
            e_and_l " dazu führen kann, dass sich das System nicht mehr starten lässt, bzw. einzelne"
            e_and_l " Dateien nachträglch manuell angepasst werden müssen. Mache daher nur weiter,"
            e_and_l " wenn Du Dich gut auskennst und diese Anpassungen durchführen kannst!"
            ask_yes_or_no_plus "" " Jetzt wirklich ${bold_white}initramfs${colors_off}$INIT_GRUB_QUESTION_2 erneuern" "" ""
            if [ $? -eq 1 ];
            then
              # ---------------------------------------------------------------
              # Resume-Eintrag zurücksetzen
              # (Kann helfen Time-Outs oder Panics beim Booten durch die Suche
              #  nach nicht mehr vorhandenen Partitionen zu eliminieren ;)
              # ---------------------------------------------------------------
              RESUME_FILE="/etc/initramfs-tools/conf.d/resume"
              if [ -s "$RESUME_FILE" ];
              then
                mv -f "$RESUME_FILE" "$RESUME_FILE.org" &>/dev/null
                echo -e "RESUME=none" > "$RESUME_FILE" 2>/dev/null
              fi
              # --------------------------------
              # Initial RAM FileSystem erneuern
              # --------------------------------
              e_and_l -n " Aktualisiere das ${light_yellow}Initial RAM FileSystem${colors_off}  ... "
              update-initramfs -u &>"$LOG_TEMP"
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
              add_full_log
              if update-grub --help &>/dev/null;
              then
                e_and_l -n " Aktualisiere die Einträge im ${light_yellow}GRUB-Loader${colors_off} ... "
                update-grub &>"$LOG_TEMP"
                if [ $? -eq 0 ];
                then
                  e_and_l "$OK_TAG"
                else
                  e_and_l "$ERROR_TAG"
                fi
                add_full_log
              fi
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        fi
      fi
      remove_file "$OLD_KERNEL_LIST"
    else
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste nicht mehr benötigter Kernel-Komponenten ist gespeichert in:"
      e_and_l " ${light_yellow}$OLD_KERNEL_LIST${colors_off}"
    fi
    e_and_l "$HALF_LINE"
  else
    remove_file "$OLD_KERNEL_LIST"
    e_and_l " Löschen nicht verwendeter ${light_cyan}Kernel-Versionen${colors_off} ... $NF_TAG"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Veraltete und verwaiste Pakete und Links${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Löschen verwaister Pakete und Komponenten
  # ============================================================================
  ACTION_MESSAGE=" Löschen ${light_cyan}nicht mehr benötigter Komponenten${colors_off}  ... "
  apt list ?garbage 2>/dev/null | grep -oP '^(.*)(?=/)' > "$PKG_GARBAGE_LIST"
  if [ -s "$PKG_GARBAGE_LIST" ];
  then
    PKG_GARBAGE_ARRAY=()
    while read pkg;
    do
      if [ "$pkg" != "" ];
      then
        PKG_GARBAGE_ARRAY+=("$pkg")
      fi
    done < "$PKG_GARBAGE_LIST"
    e_and_l " Es wurden ${bold_yellow}${#PKG_GARBAGE_ARRAY[@]}${colors_off} ${light_cyan}nicht mehr benötigte Pakete und System-Komponenten${colors_off} gefunden."
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen und Liste als Datei speichern"
    e_and_l " [${bold_yellow}1${colors_off}] Jede Komponente einzeln jeweils mit Abfrage löschen"
    e_and_l " [${bold_yellow}2${colors_off}] Alle Komponenten ohne einzelne Abfragen löschen"
    user_choice_012
    REMOVE_MODE=$?
    if [ $REMOVE_MODE -gt 0 ];
    then
      # ----------------------------------------------------
      # Sicherheitsabfrage wenn alle gelöscht werden sollen
      # ----------------------------------------------------
      if [ $REMOVE_MODE -eq 2 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        e_and_l " Folgende nicht mehr benötigte Pakete und Komponenten wurden gefunden:"
        for pkg in "${PKG_GARBAGE_ARRAY[@]}";
        do
          e_and_l " - ${light_cyan}$pkg${colors_off}"
        done
        e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Jetzt wirklich ${bold_red}alle${colors_off} vorstehenden Komponenten löschen" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REMOVE_MODE=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------------
      if [ $REMOVE_MODE -gt 0 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        for pkg in "${PKG_GARBAGE_ARRAY[@]}";
        do
          DO_REMOVE_THIS=1
          if [ $REMOVE_MODE -eq 1 ];
          then
            e_and_l " Komponente ${light_cyan}$pkg${colors_off}"
            ask_yes_or_no_plus "" " Löschen" "" "n"
            DO_REMOVE_THIS=$?
          fi
          if [ $DO_REMOVE_THIS -eq 1 ];
          then
            e_and_l -n " Lösche ${light_yellow}$pkg${colors_off} ... "
            # { apt purge "$pkg" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
            # PURGE_PKG_RESULT=$(cat "$LAST_EXIT_CODE")
            # add_full_log
            # remove_file "$LAST_EXIT_CODE"
            apt-get purge "$pkg" -y &>"$LOG_TEMP"
            PURGE_PKG_RESULT=$?
            if [ $PURGE_PKG_RESULT -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        done
      fi
      remove_file "$PKG_GARBAGE_LIST"
    else
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste der nicht mehr benötigten Komponenten ist gespeichert in:"
      e_and_l " ${light_yellow}$PKG_GARBAGE_LIST${colors_off}"
    fi
    e_and_l "$HALF_LINE"
  else
    remove_file "$PKG_GARBAGE_LIST"
    e_and_l "$ACTION_MESSAGE$NF_TAG"
  fi

  # ============================================================================
  # Löschen Paket-Konfigurationen
  # ============================================================================
  ACTION_MESSAGE=" Löschen ${light_cyan}verwaister Paket-Konfigurationen${colors_off}   ... "
  apt list ?config-files 2>/dev/null | grep -oP '^(.*)(?=/)' > "$CONFIG_REST_LIST"
  if [ -s "$CONFIG_REST_LIST" ];
  then
    CONFIG_REST_ARRAY=()
    while read pkg;
    do
      if [ "$pkg" != "" ];
      then
        CONFIG_REST_ARRAY+=("$pkg")
      fi
    done < "$CONFIG_REST_LIST"
    e_and_l " Es wurden ${bold_yellow}${#CONFIG_REST_ARRAY[@]}${colors_off} ${light_cyan}verwaiste Konfigurationen${colors_off} von gelöschten Paketen gefunden."
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen und Liste als Datei speichern"
    e_and_l " [${bold_yellow}1${colors_off}] Jede verwaiste Konfiguration einzeln jeweils mit Abfrage löschen"
    e_and_l " [${bold_yellow}2${colors_off}] Alle verwaisten Konfigurationen ohne einzelne Abfragen löschen"
    user_choice_012
    REMOVE_MODE=$?
    if [ $REMOVE_MODE -gt 0 ];
    then
      # ----------------------------------------------------
      # Sicherheitsabfrage wenn alle gelöscht werden sollen
      # ----------------------------------------------------
      if [ $REMOVE_MODE -eq 2 ];
      then
        e_and_l " Zu folgenden Paketen wurden verwaiste Konfigurationen gefunden:"
        for pkg in "${CONFIG_REST_ARRAY[@]}";
        do
          e_and_l " - ${light_cyan}$pkg${colors_off}"
        done
        e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Jetzt wirklich ${bold_red}alle${colors_off} vorstehenden Konfigurationen löschen" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          REMOVE_MODE=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------------
      if [ $REMOVE_MODE -gt 0 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        for pkg in "${CONFIG_REST_ARRAY[@]}";
        do
          DO_REMOVE_THIS=1
          if [ $REMOVE_MODE -eq 1 ];
          then
            e_and_l " Konfiguration von ${light_cyan}$pkg${colors_off}"
            ask_yes_or_no_plus "" " Löschen" "" "n"
            DO_REMOVE_THIS=$?
          fi
          if [ $DO_REMOVE_THIS -eq 1 ];
          then
            e_and_l -n " Lösche Konfiguration von ${light_yellow}$pkg${colors_off} ... "
            # { apt purge "$pkg" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
            # PURGE_PKG_RESULT=$(cat "$LAST_EXIT_CODE")
            # remove_file "$LAST_EXIT_CODE"
            apt-get purge "$pkg" -y &>"$LOG_TEMP"
            PURGE_PKG_RESULT=$?
            if [ $PURGE_PKG_RESULT -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
          e_and_l "$HALF_MINUS_LINE"
        done
      fi
      remove_file "$CONFIG_REST_LIST"
    else
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste der verwaisten Konfigurationen ist gespeichert in:"
      e_and_l " ${light_yellow}$CONFIG_REST_LIST${colors_off}"
    fi
    e_and_l "$HALF_LINE"
  else
    remove_file "$CONFIG_REST_LIST"
    e_and_l "$ACTION_MESSAGE$NF_TAG"
  fi

  # ============================================================================
  # Löschen verwaister Flatpak-Pakete (System-Komponenten)
  # -------------------------------------------------------
  # Hinweis: Aktuell werden nur verbliebene System-Komponenten gefunden, wenn
  # KEINE Anwendungen mehr installiert sind, und es wird auch nichts gelöscht.
  # -------------------------------------------------------
  # TODO: Tatsächlich verwaiste System-Komponenten von einzelnen nicht mehr
  #       installierten Anwendungen finden und diese löschen.
  # ============================================================================
  ACTION_MESSAGE=" Löschen von ${light_cyan}verwaisten Flatpak-Komponenten${colors_off} ... "
  if [ $FLATPAK_ACTIVE -eq 1 ];
  then
    THE_FLATPAK_INST_ALL_LIST="$DOWNLOAD_DIR/the_flatpak_inst_all_list"
    # --------------------------------------------------------------------------
    # Liste ALLER installierten Flatpaks (Apps und Treiber etc.) erstellen
    # --------------------------------------------------------------------------
    flatpak list --columns=name,version,ref > "$THE_FLATPAK_INST_ALL_LIST" 2>/dev/null
    # --------------------------------------------------------------------------
    # Wenn die App-Liste leer ist (keine Apps installiert), die komplette Liste
    # aber Einträge enthält, werden Letztere vermutlich nicht mehr benötigt
    # --------------------------------------------------------------------------
    if [ ! -s $FLATPAK_INSTALLED_PKG_LIST ] &&
       [ -s $THE_FLATPAK_INST_ALL_LIST ];
    then
      e_and_l " Es wurden ${light_cyan}verwaiste Flatpak-Komponenten${colors_off} gefunden."
      e_and_l " Folgende Pakete werden vermutlich nicht mehr benötigt:"
      while read flatpak_name;
      do
        if [ "$flatpak_name" != "" ];
        then
          e_and_l -n " - $(echo "$flatpak_name" | cut -f 1 | xargs 2>/dev/null) "
          e_and_l "$(echo "$flatpak_name" | cut -f 2 | xargs 2>/dev/null)"
        fi
      done < "$THE_FLATPAK_INST_ALL_LIST"
    else
      e_and_l "$ACTION_MESSAGE$NF_TAG"
    fi
    remove_file "$THE_FLATPAK_INST_ALL_LIST"
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "kein Flatpak")"
  fi

  # ============================================================================
  # Löschen veralteter Snap-Snapschüsse
  # ============================================================================
  ACTION_MESSAGE=" Löschen von ${light_cyan}veralteten Snap-Snapschüssen${colors_off}   ... "
  if [ $SNAP_ACTIVE -gt 0 ];
  then
    remove_file "$SNAP_SNAPSHOT_LIST"
    LANG=en_US.UTF-8 snap saved 2>/dev/null | tail --lines=+2 | awk '{print $1, $2, "(A"$3")", "(V"$4")", "(R"$5")", "(S"$6")"}' > "$SNAP_SNAPSHOT_LIST"
    if [ -s "$SNAP_SNAPSHOT_LIST" ];
    then
      remove_snapshots "" 0
    else
      e_and_l "$ACTION_MESSAGE$NF_TAG"
      remove_file "$SNAP_SNAPSHOT_LIST"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "kein SNAP")"
  fi

  # ============================================================================
  # Löschen sonstiger ungültiger Verknüpfungen im Benutzer-Ordner
  # --------------------------------------------------------------
  # Achtung: HINTER den [repair]-Aktionen zu:
  # - "Reparatur ungültiger Benutzer-Ordner/Links" und
  # - "Benutzer-Ordner deutsch<>english verlinken" !!!
  # ============================================================================
  BROKEN_LINKS=0
  BROKEN_LINK_TABLE=()
  echo -e -n > "$BROKEN_LINKS_LIST"
  while read the_link;
  do
    if [ "$the_link" != "" ];
    then
      THE_LINK_TARGET="$(readlink "$the_link")"
      if [ "$THE_LINK_TARGET" != "" ];
      then
        # ---------------------------------
        # Relative Zielangaben korrigieren
        # ---------------------------------
        if [ "${THE_LINK_TARGET:0:1}" != "/" ];
        then
          LINK_BASE_PATH="${the_link%/*}"
          THE_LINK_TARGET="$LINK_BASE_PATH/$THE_LINK_TARGET"
        fi
        # -----------------------------------------------
        # Verknüpfungen zu nicht existierenden Zielen in
        # Liste (Datei) und interne Tabelle speichern
        # -----------------------------------------------
        if [ ! -e "$THE_LINK_TARGET" ];
        then
          THE_BROKEN_LINE="$the_link > $THE_LINK_TARGET"
          echo -e "$THE_BROKEN_LINE" >> "$BROKEN_LINKS_LIST"
          BROKEN_LINK_TABLE+=("$THE_BROKEN_LINE")
          ((BROKEN_LINKS+=1))
        fi
      fi
    fi
  done <<< $(find "$USER_HOME_DIR" -type l -print)
  if [ $BROKEN_LINKS -gt 0 ];
  then
    e_and_l "$HALF_LINE"
    e_and_l " Es wurden ${bold_yellow}$BROKEN_LINKS${colors_off} ${light_cyan}ungültige Verknüpfungen${colors_off} gefunden."
    # --------
    # Abfrage
    # --------
    e_and_l " Was soll ich tun?"
    e_and_l " [${bold_yellow}0${colors_off}] Schritt überspringen, nichts löschen und Liste als Datei speichern"
    e_and_l " [${bold_yellow}1${colors_off}] Jede ungültige Verknüpfung einzeln jeweils mit Abfrage löschen"
    e_and_l " [${bold_yellow}2${colors_off}] Alle ungültigen Verknüpfungen ohne einzelne Abfragen löschen"
    user_choice_012
    LINK_ACTION=$?
    if [ $LINK_ACTION -gt 0 ];
    then
      # ----------------------------------------------------
      # Sicherheitsabfrage wenn alle gelöscht werden sollen
      # ----------------------------------------------------
      if [ $LINK_ACTION -eq 2 ];
      then
        e_and_l " Folgende ungültigen Verknüpfungen wurden gefunden:"
        i=1
        e_and_l "$HALF_MINUS_LINE"
        for broken_line in "${BROKEN_LINK_TABLE[@]}";
        do
          if [ "$broken_line" != "" ];
          then
            THE_LINK_PATH="$(echo -e -n "$broken_line" | sed -E "s/'/\\\'/g" | cut -d'>' -f 1 | xargs 2>/dev/null)"
            THE_TARGET_PATH="$(echo -e -n "$broken_line" | sed -E "s/'/\\\'/g" | cut -d'>' -f 2 | xargs 2>/dev/null)"
            e_and_l " $i. ${light_red}$THE_LINK_PATH${colors_off} -> ${light_magenta}$THE_TARGET_PATH${colors_off}"
            e_and_l "$HALF_MINUS_LINE"
          fi
          ((i+=1))
        done
        e_and_l " Hast Du die Liste genau geprüft, so dass nichts ungewollt gelöscht wird?"
        ask_yes_or_no_plus "" " Jetzt wirklich ${bold_red}alle${colors_off} vorstehenden Verknüpfungen löschen" "" "n"
        if [ $? -eq 0 ];
        then
          e_and_l " $USER_CHOICE_NO"
          LINK_ACTION=0
        else
          e_and_l " $USER_CHOICE_YES"
        fi
      fi
      # ----------------------------------------------------
      if [ $LINK_ACTION -gt 0 ];
      then
        e_and_l "$HALF_MINUS_LINE"
        for broken_line in "${BROKEN_LINK_TABLE[@]}";
        do
          if [ "$broken_line" != "" ];
          then
            DO_REMOVE_LINK=1
            # --------------
            # Einzelabfrage
            # --------------
            THE_LINK_PATH="$(echo -e -n "$broken_line" | sed -E "s/'/\\\'/g" | cut -d'>' -f 1 | xargs 2>/dev/null)"
            THE_TARGET_PATH="$(echo -e -n "$broken_line" | sed -E "s/'/\\\'/g" | cut -d'>' -f 2 | xargs 2>/dev/null)"
            if [ $LINK_ACTION -eq 1 ];
            then
              e_and_l " ${light_cyan}$THE_LINK_PATH${colors_off} -> ${dark_gray}$THE_TARGET_PATH${colors_off}"
              ask_yes_or_no_plus "" " Ungültige Verknüpfung löschen" "" "n"
              DO_REMOVE_LINK=$?
            fi
            # --------------
            if [ $DO_REMOVE_LINK -eq 1 ];
            then
              e_and_l -n " Lösche ${light_yellow}$THE_LINK_PATH${colors_off} ... "
              rm -f "$THE_LINK_PATH" &>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            fi
            e_and_l "$HALF_MINUS_LINE"
          fi
        done
      fi
      remove_file "$BROKEN_LINKS_LIST"
    else
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Liste der ungültigen Verknüpfungen ist gespeichert in:"
      e_and_l " ${light_yellow}$BROKEN_LINKS_LIST${colors_off}"
    fi
  else
    e_and_l " Löschen ${light_cyan}ungültiger Verknüpfungen${colors_off} (Symlink) ... $NF_TAG"
    remove_file "$BROKEN_LINKS_LIST"
  fi

  e_and_l "$HALF_LINE"
  e_and_l " ${bold_blue}Veraltete und temporäre Benutzer-Daten${colors_off}"
  e_and_l "$HALF_LINE"

  # ============================================================================
  # Löschen der User-System-Benachrichtigungen (Mails)
  # ============================================================================
  ACTION_MESSAGE=" Löschen der ${light_cyan}User-System-Benachrichtigungen${colors_off} ... "
  USER_MAIL_FILE="/var/spool/mail/$USER_USERNAME"
  if [ -s "$USER_MAIL_FILE" ];
  then
    MAILS_ENTRIES=$(grep -c -i -E "from:" "$USER_MAIL_FILE")
    MAILS_TOTAL_BYTES=$(du -b -c -s ${USER_MAIL_FILE} 2>/dev/null | tail -1 | awk '{print $1}')
    QUESTION_TEXT=" ${light_cyan}System-Benachrichtigungen${colors_off} löschen (${light_magenta}$MAILS_ENTRIES Mails, "
    QUESTION_TEXT+=$(show_human_bytes "$MAILS_TOTAL_BYTES")
    QUESTION_TEXT+="${colors_off})"
    ask_yes_or_no_plus "delete_user_mails" "$QUESTION_TEXT" "" "n"
    if [ $? -eq 1 ];
    then
      e_and_l -n " Lösche die ${light_yellow}User-System-Benachrichtigungen${colors_off}  ... "
      remove_file "$USER_MAIL_FILE"
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
      fi
      e_and_l "$HALF_MINUS_LINE"
    fi
  else
    e_and_l "$ACTION_MESSAGE$NF_TAG"
  fi

  # ============================================================================
  # Löschen der veralteten System-Log-Dateien
  # ------------------------------------------
  # ACHTUNG: Die Anzahl Tage werden weiter oben mit ANZ_LOG_DAYS festgelegt
  # ============================================================================
  ACTION_MESSAGE=" Löschen der veralteten ${light_cyan}System-Log-Dateien${colors_off}  ... "
  VAR_LOG_DIR="/var/log"
  if [ -d "$VAR_LOG_DIR" ];
  then
    # ------------------------------------
    # Anzahl veralteter Dateien ermitteln
    # ------------------------------------
    OLD_LOGS_FILES=$(find "$VAR_LOG_DIR" -depth -type f -mtime +${ANZ_LOG_DAYS} 2>/dev/null | wc -l)
    EMPTY_LOG_DIRS=$(find "$VAR_LOG_DIR/journal" -depth -type d -empty 2>/dev/null | wc -l)
    if [ $OLD_LOGS_FILES -gt 0 ] ||
       [ $EMPTY_LOG_DIRS -gt 0 ];
    then
      # --------------------------------------------------------------------
      # Belegten Speicherplatz der Dateien ermitteln (nur wenn es auch
       # Dateien gibt, da "du" sonst nicht das gewünschte Ergebnis liefert)
      # --------------------------------------------------------------------
      if [ $OLD_LOGS_FILES -gt 0 ];
      then
        OLD_LOGS_BYTES=$(find "$VAR_LOG_DIR" -depth -type f -mtime +${ANZ_LOG_DAYS} 2>/dev/null | xargs du -b -c -s 2>/dev/null | tail -1 | awk '{print $1}')
      else
        OLD_LOGS_BYTES=0
      fi
      ((OLD_LOGS_FILES+=EMPTY_LOG_DIRS))
      QUESTION_TEXT=" Veraltete ${light_cyan}System-Logs${colors_off} löschen (${light_magenta}$OLD_LOGS_FILES Dateien, "
      QUESTION_TEXT+=$(show_human_bytes "$OLD_LOGS_BYTES")
      QUESTION_TEXT+="${colors_off})"
      ask_yes_or_no_plus "delete_old_syslogs" "$QUESTION_TEXT" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Lösche die veralteten ${light_yellow}System-Log-Dateien${colors_off}   ... "
        # --------------------------
        # Veraltete Dateien löschen
        # --------------------------
        find "$VAR_LOG_DIR" -depth -type f -mtime +${ANZ_LOG_DAYS} -delete &>"$LOG_TEMP"
        # -----------------------------------------
        # Leere Ordner löschen (nur unter journal)
        # -----------------------------------------
        if [ -d "$VAR_LOG_DIR/journal" ];
        then
          find "$VAR_LOG_DIR/journal" -depth -type d -empty -delete &>>"$LOG_TEMP"
        fi
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
        add_full_log
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE$ND_TAG"
    fi
  else
    e_and_l "$(skip_text "$ACTION_MESSAGE" "$NF_TXT")"
  fi

  # ============================================================================
  # Löschen der gespeicherten Vorschaubilder (Thumbnail-Cache)
  # ============================================================================
  ACTION_MESSAGE=" Löschen des gespeicherten ${light_cyan}Thumbnail-Cache${colors_off}  ... "
  THUMBS_DIR="$USER_HOME_DIR/.cache/thumbnails"
  if [ -d "$THUMBS_DIR" ];
  then
    THUMBS_TOTAL_BYTES=$(du -b -c -s ${THUMBS_DIR} 2>/dev/null | tail -1 | awk '{print $1}')
    THUMBS_TOTAL_FILES=$(find ${THUMBS_DIR} -type f 2>/dev/null | wc -l)
    if [ $THUMBS_TOTAL_FILES -gt 0 ];
    then
      QUESTION_TEXT=" ${light_cyan}Thumbnail-Cache${colors_off} löschen (${light_magenta}$THUMBS_TOTAL_FILES Dateien, "
      QUESTION_TEXT+=$(show_human_bytes "$THUMBS_TOTAL_BYTES")
      QUESTION_TEXT+="${colors_off})"
      ask_yes_or_no_plus "delete_thumb_cache" "$QUESTION_TEXT" "" "n"
      if [ $? -eq 1 ];
      then
        e_and_l -n " Lösche die gespeicherten ${light_yellow}Vorschau-Bilder${colors_off}   ... "
        rm -f -r ${THUMBS_DIR} &>"$LOG_TEMP"
        if [ $? -eq 0 ];
        then
          e_and_l "$OK_TAG"
        else
          e_and_l "$ERROR_TAG"
        fi
        add_full_log
        e_and_l "$HALF_MINUS_LINE"
      fi
    else
      e_and_l "$ACTION_MESSAGE$ND_TAG"
    fi
  else
    e_and_l "$ACTION_MESSAGE$ND_TAG"
  fi

  # ============================================================================
  # Löschen der veralteten Datei-Nutzungsdaten
  # ============================================================================
  ACTION_MESSAGE=" Löschen gespeicherter ${light_cyan}Datei-Nutzungsdaten${colors_off}  ... "
  # ----------------------------------------------------------------------------
  # ACHTUNG: Alle Pfadangaben in SEARCH_FILE_LIST sind relativ zum
  #          $USER_HOME_DIR und dürfen KEINE Leerzeichen enthalten!
  # ----------------------------------------------------------------------------
  SEARCH_FILE_LIST=('.recently-used'
                    '.local/share/recently-used.xbel*'
                    '.local/share/user-places.xbel*'
                    '.local/share/RecentDocuments/*'
                   )
  FILES_FOUND_TOTAL_BYTES=0
  FILES_FOUND_TOTAL_FILES=0
  for search_mask in ${SEARCH_FILE_LIST[@]};
  do
    SEARCH_FILE_MASK="$USER_HOME_DIR/$search_mask"
    FILES_FOUND_BYTES=$(du -b -c -s ${SEARCH_FILE_MASK} 2>/dev/null | tail -1 | awk '{print $1}')
    FILES_FOUND_FILES=$(find ${SEARCH_FILE_MASK} -type f 2>/dev/null | wc -l)
    ((FILES_FOUND_TOTAL_BYTES+=FILES_FOUND_BYTES))
    ((FILES_FOUND_TOTAL_FILES+=FILES_FOUND_FILES))
  done
  if [ $FILES_FOUND_TOTAL_FILES -gt 0 ];
  then
    QUESTION_TEXT=" ${light_cyan}Nutzungsdaten von Dateien${colors_off} löschen (${light_magenta}$FILES_FOUND_TOTAL_FILES Dateien, "
    QUESTION_TEXT+=$(show_human_bytes "$FILES_FOUND_TOTAL_BYTES")
    QUESTION_TEXT+="${colors_off})"
    ask_yes_or_no_plus "delete_user_temp" "$QUESTION_TEXT" "" "n"
    if [ $? -eq 1 ];
    then
      e_and_l -n " Lösche gespeicherte ${light_yellow}Datei-Nutzungsdaten${colors_off}    ... "
      for search_mask in ${SEARCH_FILE_LIST[@]};
      do
        # --------------------------------------------------------------
        # Zur Sicherheit nur löschen, wenn der Pfad nicht versehentlich
        # leer ist und dadurch der gesamte Home-Ordner gelöscht würde
        # --------------------------------------------------------------
        if [ "$search_mask" != "" ];
        then
          SEARCH_FILE_MASK="$USER_HOME_DIR/$search_mask"
          rm -f ${SEARCH_FILE_MASK} &>"$LOG_TEMP"
        fi
      done
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
        add_full_log
      fi
      # e_and_l "$HALF_MINUS_LINE"
    fi
  else
    e_and_l "$ACTION_MESSAGE$ND_TAG"
  fi

fi # Ende [cleansys]

#===============================================================================
# Einrichtung persönlicher System-Einstellungen (Personalisierung)
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[personal]} -eq 1 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Einrichtung persönlicher System-Einstellungen${colors_off} ${dark_gray}[personal]${colors_off}"
  e_and_l "$FULL_LINE"
  # -----------------------------------------------------------------------
  # Eingabe der Zugangsdaten zur Verifizierung auf dem Server
  # -----------------------------------------------------------------------
  e_and_l -n " Bitte Benutzernamen eingeben: "
  read -i "$USER_USERNAME" -r TMP_USER_NAME
  TMP_USER_NAME="${TMP_USER_NAME:-$USER_USERNAME}"
  TMP_USER_NAME=$(echo "$TMP_USER_NAME" | tr -d -c '[:alnum:]_' | tr '[:upper:]' '[:lower:]')
  stty -echo &>/dev/null
  e_and_l -n " Bitte Passwort für ${bold_yellow}${TMP_USER_NAME}${colors_off} eingeben: "
  read -r -s USER_PASSWORD
  stty echo &>/dev/null
  DOWNLOAD_FILE_URL="$RESSOURCE_DOWNLOADER"
  THE_TEMP_FILE="$DOWNLOAD_DIR/individual"
  DECODED_PASS=$(echo -n ${USER_PASSWORD} | md5sum | awk '{print $1}')
  CHECK_PASS=$(wget -nv --post-data="&c=1&u=$TMP_USER_NAME&p=$DECODED_PASS" -O "$THE_TEMP_FILE" "$DOWNLOAD_FILE_URL" &>/dev/null && cat "$THE_TEMP_FILE" 2>/dev/null)
  if [ "$CHECK_PASS" == "SUCCESS" ];
  then
    # ---------------------------------------------------------------------
    # Liste der Einstellungen und Aktionen definieren
    # ---------------------------------------------------------------------
    declare -A USER_CONF_NAM # Angezeigte Bezeichnungen
    declare -A USER_CONF_SRC # Quelldateien (OHNE Pfad, der wird über RESSOURCE_DOWNLOADER festgelegt)
    declare -A USER_CONF_DST # Zieldateien (MIT Pfad)
    declare -A USER_CONF_COM # Befehl, der nach dem Download der jeweiligen Quelldatei durchgeführt wird
    declare -A USER_CONF_MAO # Wenn "true", dann wird diese Aktion nur auf MATE ausgeführt
    declare -A USER_CONF_MSG # Meldung, die nach der Aktion angezeigt wird
    # -------------------------------------------------------
    # Interne Index-Liste der durchzuführenden Einstellungen
    # (NICHT identisch mit Paketnamen!)
    # -------------------------------------------------------
    # USER_CONF_LIST=('backpics' 'desktopu' 'firewall' 'matemenu' 'bookmark' 'mimeapps' 'doublcmd' 'kateconf' 'geanycfg' 'smplayer' 'redshift' 'teamview')
    USER_CONF_LIST=('backpics' 'firewall' 'matemenu' 'bookmark' 'mimeapps' 'doublcmd' 'smplayer' 'redshift' 'teamview')
    # Download der Hintergrundbilder
    USER_CONF_NAM[backpics]="Download der [cs]Dual-Monitor-Hintergrundbilder[ce]"
    USER_CONF_SRC[backpics]=""
    USER_CONF_DST[backpics]=""
    USER_CONF_COM[backpics]="wget_dir \"https://migano.de/download/lissy/res/wallpapers/\" \"/usr/share/backgrounds/wallpapers\" && chmod -R 0644 /usr/share/backgrounds/wallpapers/* &>/dev/null"
    USER_CONF_MAO[backpics]=""
    USER_CONF_MSG[backpics]=""
    # Einstellungen des Desktops und diverser Tools (vollständiger dconf-Baum!)
    # USER_CONF_NAM[desktopu]="Konfiguration von [cs]Desktop & diversen Tools[ce]"
    # USER_CONF_SRC[desktopu]="$DCONF_BASE_NAME.conf"
    # USER_CONF_DST[desktopu]=""
    # USER_CONF_COM[desktopu]="sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS=\"unix:path=/run/user/${USER_UID}/bus\" dconf load / < \"$DOWNLOAD_DIR/${USER_CONF_SRC[desktopu]}\" &>/dev/null"
    # USER_CONF_MAO[desktopu]="true"
    # USER_CONF_MSG[desktopu]=""
    # Firewall-Regeln
    USER_CONF_NAM[firewall]="Eintragen der eingehenden [cs]Firewall-Regeln[ce]"
    USER_CONF_SRC[firewall]="ufw-config"
    USER_CONF_DST[firewall]=""
    USER_CONF_COM[firewall]="chmod -R 0755 $DOWNLOAD_DIR/${USER_CONF_SRC[firewall]} && $DOWNLOAD_DIR/${USER_CONF_SRC[firewall]} &>/dev/null"
    USER_CONF_MAO[firewall]=""
    USER_CONF_MSG[firewall]=""
    # Favoriten Advanced MATE Menü
    USER_CONF_NAM[matemenu]="Favoriten für das [cs]Advanced MATE Menü[ce] setzen"
    USER_CONF_SRC[matemenu]="applications.list"
    USER_CONF_DST[matemenu]="${USER_CONFIG_DIR}/mate-menu/applications.list"
    USER_CONF_COM[matemenu]="cp -f $DOWNLOAD_DIR/${USER_CONF_SRC[matemenu]} ${USER_CONF_DST[matemenu]} &>/dev/null"
    USER_CONF_MAO[matemenu]="true"
    USER_CONF_MSG[matemenu]=""
    # Dateimanager Lesezeichen
    USER_CONF_NAM[bookmark]="Einrichten der [cs]Lesezeichen für Dateimanager[ce]"
    USER_CONF_SRC[bookmark]="bookmarks"
    USER_CONF_DST[bookmark]="${USER_CONFIG_DIR}/gtk-3.0/bookmarks"
    USER_CONF_COM[bookmark]="cp -f $DOWNLOAD_DIR/${USER_CONF_SRC[bookmark]} ${USER_CONF_DST[bookmark]} &>/dev/null"
    USER_CONF_MAO[bookmark]=""
    USER_CONF_MSG[bookmark]=""
    # Bevorzugte Anwendungen
    USER_CONF_NAM[mimeapps]="Festlegung der [cs]bevorzugten Anwendungen[ce]"
    USER_CONF_SRC[mimeapps]="mimeapps.list"
    USER_CONF_DST[mimeapps]="${USER_CONFIG_DIR}/mimeapps.list"
    USER_CONF_COM[mimeapps]="cp -f $DOWNLOAD_DIR/${USER_CONF_SRC[mimeapps]} ${USER_CONF_DST[mimeapps]} &>/dev/null"
    USER_CONF_MAO[mimeapps]=""
    USER_CONF_MSG[mimeapps]=""
    # Double-Commander
    USER_CONF_NAM[doublcmd]="Konfiguration des Programms [cs]DoubleCommander[ce]"
    USER_CONF_SRC[doublcmd]="doublecmd.7z"
    USER_CONF_DST[doublcmd]="${USER_CONFIG_DIR}"
    USER_CONF_COM[doublcmd]="7z x \"$DOWNLOAD_DIR/${USER_CONF_SRC[doublcmd]}\" -o\"${USER_CONF_DST[doublcmd]}\" -y &>/dev/null && chown -R \"$USER_USERNAME\":\"$USER_USERNAME\" $USER_CONFIG_DIR/doublecmd &>/dev/null"
    USER_CONF_MAO[doublcmd]=""
    USER_CONF_MSG[doublcmd]=""
    # Kate
#       THE_KATE_VERSION=$(get_pkg_apt_version "kate" 1)
#       if [ "$THE_KATE_VERSION" == "" ];
#       then
#         THE_KATE_VERSION=$(get_pkg_snap_version "kate" 1)
#       fi
#       THE_KATE_VERSION=$(echo -n "${THE_KATE_VERSION:0:2}" | xargs)
#       if [ "$THE_KATE_VERSION" == "" ]; then THE_KATE_VERSION=0; fi
#       USER_CONF_NAM[kateconf]="Konfiguration des Programms [cs]Kate$THE_KATE_VERSION (Editor)[ce]"
#       if [ $THE_KATE_VERSION -lt 20 ];
#       then
#         # Kate bis Version 19 (einschließlich)
#         # Alle Konfigurations-Dateien zum Überschreiben
#         USER_CONF_SRC[kateconf]="kate-settings.7z"
#         USER_CONF_DST[kateconf]="${USER_CONFIG_DIR}"
#         USER_CONF_COM[kateconf]="7z x \"$DOWNLOAD_DIR/${USER_CONF_SRC[kateconf]}\" -o\"${USER_CONF_DST[kateconf]}\" -y &>/dev/null && chown \"$USER_USERNAME\":\"$USER_USERNAME\" $USER_CONFIG_DIR/kate* &>/dev/null"
#         USER_CONF_MAO[kateconf]=""
#         USER_CONF_MSG[kateconf]=""
#       else
#         # Kate ab Version 20 (Nur Farb-Codes zum manuellen Import)
#         USER_CONF_SRC[kateconf]="kate_colors.theme"
#         USER_CONF_DST[kateconf]=""
#         USER_CONF_COM[kateconf]="mv -f \"${DOWNLOAD_DIR}/${USER_CONF_SRC[kateconf]}\" \"${DOWNLOAD_DIR}/kate_color_set.theme\" &>/dev/null"
#         USER_CONF_MAO[kateconf]=""
#         USER_CONF_MSG[kateconf]="Bitte die Datei ${light_yellow}kate_color_set.theme${colors_off} noch manuell importieren."
#       fi
    # Geany
#       USER_CONF_NAM[geanycfg]="Konfiguration des Programms [cs]Geany (Editor)[ce]"
#       USER_CONF_SRC[geanycfg]="geany.7z"
#       USER_CONF_DST[geanycfg]="${USER_CONFIG_DIR}"
#       USER_CONF_COM[geanycfg]="7z x \"$DOWNLOAD_DIR/${USER_CONF_SRC[geanycfg]}\" -o\"${USER_CONF_DST[geanycfg]}\" -y &>/dev/null && chown -R \"$USER_USERNAME\":\"$USER_USERNAME\" $USER_CONFIG_DIR/geany &>/dev/null"
#       USER_CONF_MAO[geanycfg]=""
#       USER_CONF_MSG[geanycfg]=""
    # SMPlayer
    USER_CONF_NAM[smplayer]="Konfiguration des Programms [cs]SMPlayer[ce]"
    USER_CONF_SRC[smplayer]="smplayer.ini"
    USER_CONF_DST[smplayer]="${USER_CONFIG_DIR}/smplayer/smplayer.ini"
    USER_CONF_COM[smplayer]="cp -f $DOWNLOAD_DIR/${USER_CONF_SRC[smplayer]} ${USER_CONF_DST[smplayer]} &>/dev/null"
    USER_CONF_MAO[smplayer]=""
    USER_CONF_MSG[smplayer]=""
    # Redshift
    USER_CONF_NAM[redshift]="Konfiguration der [cs]Farbtemperaturanpassung[ce]"
    USER_CONF_SRC[redshift]="redshift.conf"
    USER_CONF_DST[redshift]="${USER_CONFIG_DIR}/redshift.conf"
    USER_CONF_COM[redshift]="cp -f $DOWNLOAD_DIR/${USER_CONF_SRC[redshift]} ${USER_CONF_DST[redshift]} &>/dev/null"
    USER_CONF_MAO[redshift]=""
    USER_CONF_MSG[redshift]=""
    # Teamviewer-Hintergrunddienst deaktivieren
    USER_CONF_NAM[teamview]="Deaktivierung [cs]Teamviewer[ce] Hintergrunddienst"
    USER_CONF_SRC[teamview]=""
    USER_CONF_DST[teamview]=""
    USER_CONF_COM[teamview]="teamviewer daemon disable &>/dev/null"
    USER_CONF_MAO[teamview]=""
    USER_CONF_MSG[teamview]=""
    # ---------------------------------------------------------------------
    # Einstellungen durchführen
    # (Datei downloaden und zugehörigen Befehl ausführen)
    # ---------------------------------------------------------------------
    e_and_l "$OK_TAG"
    e_and_l "$HALF_LINE"
    for conf_name in ${USER_CONF_LIST[@]};
    do
      IDX_NAME="$conf_name"
      SHOW_NAME=${USER_CONF_NAM[$IDX_NAME]}
      SHOW_NAME=${SHOW_NAME//\[cs\]/${light_cyan}}
      SHOW_NAME=${SHOW_NAME//\[ce\]/${colors_off}}
      ANZ_SPACES=62
      if [ ${OPTION_FLAG[nocolor]} -eq 1 ]; then ((ANZ_SPACES-=17)); fi
      ((ANZ_SPACES-=${#SHOW_NAME}))
      ACTION_MESSAGE=" $SHOW_NAME"
      i=1; while [ $i -lt $ANZ_SPACES ]; do ACTION_MESSAGE+=" "; ((i+=1)); done
      ACTION_MESSAGE+="... "
      if [ "$DESKTOP_ENVIRONMENT" == "MATE" ] ||
          [ "${USER_CONF_MAO[$IDX_NAME]}" != "true" ];
      then
        ask_yes_or_no_plus "" " $SHOW_NAME" "" ""
        DO_THE_CONFIG=$?
        if [ $DO_THE_CONFIG -eq 1 ];
        then
          e_and_l -n "${ACTION_MESSAGE//96m/93m}"
          # --------------------------------------------------------------
          # Bei dconf-Änderung ("desktopu") zusätzliches Backup erstellen
          # --------------------------------------------------------------
          # if [ "$IDX_NAME" == "desktopu" ];
          # then
          #   sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" dconf dump / 1>${DCONF_USER_BACKUP} 2>/dev/null
          #   chown -R "$USER_USERNAME:$USER_USERNAME" "${DCONF_USER_BACKUP}" &>/dev/null
          #   chmod -R 0664 "${DCONF_USER_BACKUP}" &>/dev/null
          # fi
          # ----------------------------------------------------------
          # Wenn keine Datei im Spiel ist, nur Kommando ausführen ...
          # ----------------------------------------------------------
          if [ "${USER_CONF_SRC[$IDX_NAME]}" == "" ] &&
             [ "${USER_CONF_DST[$IDX_NAME]}" == "" ];
          then
            { eval "${USER_CONF_COM[$IDX_NAME]}" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
            if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
            then
              e_and_l "$OK_TAG"
            else
              e_and_l "$ERROR_TAG $LINENO"
              add_full_log
            fi
          else # ... sonst Datei downloaden ...
            DOWNLOAD_FILE_NAME=${USER_CONF_SRC[$IDX_NAME]}
            DOWNLOAD_FILE_URL="$RESSOURCE_DOWNLOADER/cfg/$DOWNLOAD_FILE_NAME"
            LOCAL_DOWNLOAD_FILE="$DOWNLOAD_DIR/$DOWNLOAD_FILE_NAME"
            wget -nv --post-data="&u=$USER_USERNAME&p=$DECODED_PASS" -O "$LOCAL_DOWNLOAD_FILE" "$DOWNLOAD_FILE_URL" &>"$LOG_TEMP"
            if [ $? -eq 0 ] &&
               [ -s "$LOCAL_DOWNLOAD_FILE" ] &&
               [ $(grep -i -c -E "Error\s*404" "$LOCAL_DOWNLOAD_FILE") -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "$LOCAL_DOWNLOAD_FILE" &>/dev/null
              PERSONAL_ACTION_RESULT=0
              # ... wenn nach dem Download etwas getan werden soll,
              # dann die entsprechenden Aktionen durchführen
              if [ "${USER_CONF_COM[$IDX_NAME]}" != "" ];
              then
                DO_SOME_ACTION=1
                # Wenn eine Datei kopiert werden soll ...
                if [ $(echo "${USER_CONF_COM[$IDX_NAME]}" | grep -i -c -E "cp -f ") -gt 0 ];
                then
                  # Ziel-Ordner anlegen, falls noch nicht vorhanden
                  # (sicherheitshalber nur innerhalb des eigenen Benutzer-Ordners)
                  THE_DST_DIR="${USER_CONF_DST[$IDX_NAME]%/*}"
                  if [ $(echo -n "${USER_CONF_DST[$IDX_NAME]}" | grep -i -c -E "${USER_HOME_DIR}" 2>/dev/null) -gt 0 ] &&
                      [ ! -d "$THE_DST_DIR" ];
                  then
                    mkdir -p "$THE_DST_DIR" &>/dev/null
                    chown -R "$USER_USERNAME:$USER_USERNAME" "$THE_DST_DIR" &>/dev/null
                  fi
                  # Nichts machen wenn Zieldatei und Quelldatei identisch sind ;)
                  if
                    [ -f "$LOCAL_DOWNLOAD_FILE" ] &&
                    [ -f "${USER_CONF_DST[$IDX_NAME]}" ];
                  then
                    diff "$LOCAL_DOWNLOAD_FILE" "${USER_CONF_DST[$IDX_NAME]}" &>/dev/null
                    DO_SOME_ACTION=$?
                  fi
                fi
                # Wenn die vorherige Prüfung ergeben hat, dass etwas zu tun ist,
                # dann entsprechende Aktion durchführen ...
                if [ $DO_SOME_ACTION -ne 0 ];
                then
                  if [ -s "${USER_CONF_DST[$IDX_NAME]}" ] &&
                     [ ! -d "${USER_CONF_DST[$IDX_NAME]}" ];
                  then
                    create_backup_file "${USER_CONF_DST[$IDX_NAME]}"
                  fi
                  { eval "${USER_CONF_COM[$IDX_NAME]}" 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$LOG_TEMP"
                  if [ $(cat "$LAST_EXIT_CODE") -eq 0 ];
                  then
                    e_and_l "$OK_TAG"
                    if [ $(echo -n "${USER_CONF_DST[$IDX_NAME]}" | grep -i -c -E "${USER_HOME_DIR}" 2>/dev/null) -gt 0 ] &&
                       [ -f "${USER_CONF_DST[$IDX_NAME]}" ];
                    then
                      chown -R "$USER_USERNAME:$USER_USERNAME" "${USER_CONF_DST[$IDX_NAME]}" &>/dev/null
                      chmod -R 0664 "${USER_CONF_DST[$IDX_NAME]}" &>/dev/null
                    fi
                  else
                    e_and_l "$ERROR_TAG $LINENO"
                    PERSONAL_ACTION_RESULT=1
                    add_full_log
                  fi
                else
                  # e_and_l "$NC_TAG"
                  # Um keine Verwirrung zu stiften, immer einfach nur OK anzeigen,
                  # selbst wenn es keine Änderung der Konfiguration gegeben hat ;)
                  e_and_l "$OK_TAG"
                fi
              else
                e_and_l "$OK_TAG"
              fi
              # Optionale Meldung anzeigen ...
              if [ $PERSONAL_ACTION_RESULT -eq 0 ] &&
                  [ "${USER_CONF_MSG[$IDX_NAME]}" != "" ];
              then
                e_and_l " $HINWEIS_TAG: ${USER_CONF_MSG[$IDX_NAME]}"
              fi
            else
              # e_and_l "${bold_red}Daten nicht von diesem System${colors_off}"
              e_and_l "$ERROR_TAG"
              add_full_log
            fi
          fi
          remove_file "$LAST_EXIT_CODE"
          remove_file "$LOCAL_DOWNLOAD_FILE"
        fi
      else
        e_and_l "$ACTION_MESSAGE${light_yellow}wird übersprungen${colors_off}"
      fi
    done
  else
    e_and_l "${bold_red}Ungültige Zugangsdaten${colors_off}"
  fi
  remove_file "$THE_TEMP_FILE"
fi # Ende [personal]

#===============================================================================
# Desktop- und Anwendungs-Einstellungen speichern oder wiederherstellen
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  if [ ${OPTION_FLAG[dload]} -eq 1 ] ||
     [ ${OPTION_FLAG[dsave]} -eq 1 ];
  then
    if [ ${OPTION_FLAG[dload]} -eq 1 ] &&
       [ ${OPTION_FLAG[dsave]} -eq 1 ];
    then
      e_and_l "$FULL_LINE"
      e_and_l " ${bold_blue}Desktop- und Anwendungs-Einstellungen${colors_off}"
      e_and_l "$FULL_LINE"
      e_and_l " $ERROR_TAG: Die Aktionen ${bold_white}dload${colors_off} und ${bold_white}dsave${colors_off} können nicht zusammen ausgeführt werden!"
    else
      # ------------------------------------------------------------------------
      # Speichern
      # ------------------------------------------------------------------------
      if [ ${OPTION_FLAG[dsave]} -eq 1 ];
      then
        e_and_l "$FULL_LINE"
        e_and_l " ${bold_blue}Desktop- und Anwendungs-Einstellungen speichern${colors_off}"
        e_and_l "$FULL_LINE"
        DO_SAVE_FILE=1
        if [ -s "$DCONF_USER_FILE" ];
        then
          FILE_DATE=$(date -r ${DCONF_USER_FILE} "+%d.%m.%Y %H:%M:%S")
          e_and_l " Es ist schon eine Sicherungsdatei vom ${bold_cyan}$FILE_DATE${colors_off} vorhanden!"
          ask_yes_or_no_plus "" " Bestehende Sicherungsdatei überschreiben" "" "n"
          DO_SAVE_FILE=$?
        fi
        if [ $DO_SAVE_FILE -eq 1 ];
        then
          create_backup_file "$DCONF_USER_FILE"
          e_and_l -n " Erstelle Sicherungsdatei ${bold_yellow}${DCONF_USER_FILE##*/}${colors_off} ... "
          sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" dconf dump / 1>${DCONF_USER_FILE} 2>/dev/null
          if [ $? -eq 0 ];
          then
            chown -R "$USER_USERNAME:$USER_USERNAME" "${DCONF_USER_FILE}" &>/dev/null
            chmod -R 0664 "${DCONF_USER_FILE}" &>/dev/null
            e_and_l "$OK_TAG"
          else
            e_and_l "$ERROR_TAG"
          fi
        fi
      fi
      # ------------------------------------------------------------------------
      # Laden
      # ------------------------------------------------------------------------
      if [ ${OPTION_FLAG[dload]} -eq 1 ];
      then
        e_and_l "$FULL_LINE"
        e_and_l " ${bold_blue}Desktop- und Anwendungs-Einstellungen wiederherstellen${colors_off}"
        e_and_l "$FULL_LINE"
        if [ -s "$DCONF_USER_FILE" ];
        then
          FILE_DATE=$(date -r ${DCONF_USER_FILE} "+%d.%m.%Y %H:%M:%S")
          e_and_l " Die Sicherungsdatei hat das Datum ${bold_cyan}$FILE_DATE${colors_off}. Alle aktuellen"
          ask_yes_or_no_plus "" " Einstellungen auf diesen Stand zurücksetzen" "$DCONF_USER_FILE" "n"
          if [ $? -eq 1 ];
          then
            e_and_l -n " Sichere aktuelle Einstellungen in ${bold_yellow}${DCONF_USER_BACKUP##*/}${colors_off} ... "
            sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" dconf dump / 1>${DCONF_USER_BACKUP} 2>/dev/null
            if [ $? -eq 0 ];
            then
              chown -R "$USER_USERNAME:$USER_USERNAME" "${DCONF_USER_BACKUP}" &>/dev/null
              chmod -R 0664 "${DCONF_USER_BACKUP}" &>/dev/null
              e_and_l "$OK_TAG"
              e_and_l -n " Stelle Einstellungen aus der Sicherungsdatei wieder her ... "
              sudo -u ${USER_USERNAME} DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_UID}/bus" dconf load / < ${DCONF_USER_FILE} &>/dev/null
              if [ $? -eq 0 ];
              then
                e_and_l "$OK_TAG"
              else
                e_and_l "$ERROR_TAG"
              fi
            else
              e_and_l "$ERROR_TAG"
            fi
          fi
        else
          e_and_l " $ERROR_TAG: Keine Sicherungsdaten gefunden!"
        fi
      fi
    fi
  fi
fi

#===============================================================================
# Referenzwerte dieses Systems erstellen (Benchmarking)
#===============================================================================
if [ ${OPTION_FLAG[listonly]} -eq 0 ] &&
   [ ${OPTION_FLAG[sysbench]} -eq 1 ];
then
  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Referenzwerte dieses Systems erstellen (Benchmarks)${colors_off} ${dark_gray}[sysbench]${colors_off}"
  e_and_l "$FULL_LINE"
  e_and_l -n " Prüfe Voraussetzungen für das ${bold_white}Benchmarking${colors_off}, bitte warten ... "
  if ! sysbench --version &>/dev/null;
  then
    if [ $(apt list "sysbench" 2>/dev/null | grep -i -c -E "sysbench") -gt 0 ];
    then
      apt install sysbench -y &>"$LOG_TEMP"
      if [ $? -eq 0 ];
      then
        e_and_l "$OK_TAG"
      else
        e_and_l "$ERROR_TAG"
      fi
      add_full_log
    else
      e_and_l "$ERROR_TAG"
    fi
  else
    e_and_l "$OK_TAG"
  fi
  if sysbench --version &>/dev/null;
  then
    e_and_l " Erstelle ${light_cyan}Referenzwerte${colors_off} mit sieben Tests, jeder Test dauert etwa 10 Sekunden."
    # --------------------------------
    # System-Informationen hinzufügen
    # --------------------------------
    BENCHMARK_FILE="$DOWNLOAD_DIR/benchmarks_$(hostname).list"
    BENCH_FILE_TEXT=$'\n'
    BENCH_FILE_TEXT+=" $HALF_MINUS_LINE"$'\n'
    BENCH_FILE_TEXT+=" Benchmarking von $(hostname)"$'\n'
    BENCH_FILE_TEXT+=" Datum: $(date)"$'\n'
    BENCH_FILE_TEXT+=" $HALF_MINUS_LINE"$'\n'
    BENCH_FILE_TEXT+=" System-Informationen"$'\n'
    BENCH_FILE_TEXT+=" $HALF_MINUS_LINE"$'\n'
    SYSTEM_INFO="$(system_info_summary)"
    BENCH_FILE_TEXT+="$SYSTEM_INFO"$'\n'
    BENCH_FILE_TEXT+=" $HALF_MINUS_LINE"$'\n'
    BENCH_FILE_TEXT+=" Referenzwerte"$'\n'
    BENCH_FILE_TEXT+=" $HALF_MINUS_LINE"$'\n'
    echo -e $(clear_text "$BENCH_FILE_TEXT") > "$BENCHMARK_FILE"
    # -----------------------
    # Benchmarks durchführen
    # -----------------------
    BENCHMARK_TESTS=(CPU Memory Threads)
    bench_loop=1
    while [ $bench_loop -lt 3 ];
    do
      if [ $bench_loop -eq 1 ];
      then
        BENCH_THREADS=1
        BENCH_THRTEXT="single core"
      fi
      if [ $bench_loop -eq 2 ];
      then
        BENCH_THREADS=$CPU_CORES
        BENCH_THRTEXT="$CPU_CORES cores"
      fi
      e_and_l "$HALF_MINUS_LINE"
      for benchmark in ${BENCHMARK_TESTS[@]};
      do
        e_and_l -n " Benchmarking ${light_cyan}$benchmark $BENCH_THRTEXT${colors_off}, bitte warten ..."
        ((ANZ_SPACES=7-${#benchmark}))
        insert_spaces $ANZ_SPACES
        BENCHMARK_NAME="$(echo -n $benchmark | tr '[:upper:]' '[:lower:]')"
        RESULT="$(LANG=C sysbench --threads=${BENCH_THREADS} "$BENCHMARK_NAME" run | grep -i -E "(total number)" | sed -E "s/\s+/ /gi" | cut -d':' -f 2 | xargs 2>/dev/null)"
        RESULT=$(printf "%'d" "$RESULT")
        e_and_l " ${bold_yellow}$RESULT${colors_off} Punkte"
        echo -e " $benchmark $BENCH_THRTEXT: $RESULT" >> "$BENCHMARK_FILE"
      done
      ((bench_loop+=1))
      echo -e -n " " >> "$BENCHMARK_FILE"
      echo -e $(clear_text "$HALF_MINUS_LINE") >> "$BENCHMARK_FILE"
    done
    e_and_l "$HALF_MINUS_LINE"
    e_and_l -n " Benchmarking ${light_cyan}Checksum Calculating${colors_off}, bitte warten ... "
    SHA_BENCHPOINTS=1
    CHECK_TIME_START=$(date +%s)
    SHA_DURATION=0
    while [ $SHA_DURATION -lt 10 ];
    do
      sha256sum &>/dev/null <<< "$i"
      SHA_DURATION=$(($(date +%s) - CHECK_TIME_START))
      ((SHA_BENCHPOINTS+=1))
    done
    RESULT=$(printf "%'d" "$SHA_BENCHPOINTS")
    echo -e "${bold_yellow}$RESULT${colors_off} Punkte (relativ)"
    echo -e " Checksum Calculating: $RESULT" >> "$BENCHMARK_FILE"
    # -----------------------
    if [ -s "$BENCHMARK_FILE" ];
    then
      e_and_l "$HALF_MINUS_LINE"
      e_and_l " $HINWEIS_TAG: Die Referenzwerte sind als Datei gespeichert in:"
      e_and_l " ${light_yellow}$BENCHMARK_FILE${colors_off}"
    fi
  else
    e_and_l "$(skip_text " Erstellung von Referenzwerten dieses System" "$NA_TXT")"
  fi
fi

#===============================================================================
# Entfernen eines Programmpakets mit zugehörigen Daten
#===============================================================================
if [ ${OPTION_FLAG[remove]} -eq 1 ] &&
   [ "$REMOVE_PKG_NAME" != "" ];
then
  # ----------------------------------------------------------------------------
  # Option zur Entfernung ermitteln
  # ----------------------------------------------------------------------------
  declare -A REMOVE_TEXT
  REMOVE_TEXT[0]="Abbrechen, Programmpaket nicht entfernen"
  REMOVE_TEXT[1]="Programm entfernen und Konfiguration behalten"
  REMOVE_TEXT[2]="Programm und dessen Konfiguration entfernen"
  REMOVE_TEXT[3]="Programm und alle zugehörigen Daten enfernen"
  REMOVE_ACTION=-1

  e_and_l "$FULL_LINE"
  e_and_l " ${bold_blue}Entfernen eines Programmpakets mit zugehörigen Daten${colors_off}"
  e_and_l "$FULL_LINE"
  get_install_status "$REMOVE_PKG_NAME"
  INST_STATUS=$?
  if [ $INST_STATUS -ne 0 ];
  then
    # --------------------------------------------------------------------------
    # Prüfen ob mehrere Versionen (aus verschiedenen Quellen) installiert sind
    # --------------------------------------------------------------------------
    INST_MODE_LIST="0"
    # ----
    # STD
    # ----
    if [ $(LANG=C dpkg-query -W -f='${Status}' "$REMOVE_PKG_NAME" 2>/dev/null | grep -i -c -E "ok installed") -ne 0 ];
    then
      INST_MODE_LIST+=",1"
    fi
    # -----
    # SNAP
    # -----
    if [ $SNAP_ACTIVE -gt 0 ];
    then
      if [ $(LANG=C snap info "$REMOVE_PKG_NAME" 2>/dev/null | grep -i -c -E "installed\:") -ne 0 ];
      then
        INST_MODE_LIST+=",2"
      fi
    fi
    # --------------
    # DEB (in /opt)
    # --------------
    OPT_PKG_INST_NAME="${DEB_PKG_NAME[$REMOVE_PKG_NAME]}"
    if [ "$OPT_PKG_INST_NAME" == "" ];
    then
      OPT_PKG_INST_NAME="${WEB_PKG_NAME[$REMOVE_PKG_NAME]}"
      if [ "$OPT_PKG_INST_NAME" == "" ];
      then
        OPT_PKG_INST_NAME="$REMOVE_PKG_NAME"
      fi
    fi
    if [ -d "/opt/$OPT_PKG_INST_NAME" ];
    then
      INST_MODE_LIST+=",3"
    fi
    # ----
    # WEB
    # ----
    WEB_PKG_INST_NAME="${WEB_PKG_NAME[$REMOVE_PKG_NAME]}"
    if [ "$WEB_PKG_INST_NAME" == "" ];
    then
      WEB_PKG_INST_NAME="$REMOVE_PKG_NAME"
    fi
    if [ -d "$WEB_PKG_DIR/$WEB_PKG_INST_NAME" ];
    then
      INST_MODE_LIST+=",4"
    fi
    # -----
    # FLAT
    # -----
    if [ $FLATPAK_ACTIVE -eq 1 ] &&
       [ -s "$FLATPAK_INSTALLED_PKG_LIST" ];
    then
      FLATPAK_RNAM=$(echo "$REMOVE_PKG_NAME" | sed 's/[ -_]//g' | xargs)
      if [ $(grep -c -i -E "\.$FLATPAK_RNAM[0-9]*[\/\.]" ${FLATPAK_INSTALLED_PKG_LIST}) -gt 0 ]
         [ $(grep -c -i -E "^$FLATPAK_RNAM[0-9]*\s+[0-9]" ${FLATPAK_INSTALLED_PKG_LIST}) -gt 0 ];
      then
        INST_MODE_LIST+=",6"
      fi
    fi
    # -----------------------------------------------------------------------
    # SHAR
    # -----
    # Zuletzt prüfen, damit diese Art nur dann mit hinzugefügt wird, wenn
    # noch keine andere Art aufgeführt ist, weil die vorherigen Methoden
    # ihre Programme ggf. auch in /usr/share installiert haben könnten und
    # diese auch erst auf deren entsprechende Art entfernt werden sollten!
    # -----------------------------------------------------------------------
    SHAR_PKG_INST_DIR="/usr/share/$REMOVE_PKG_NAME"
    if [ "$INST_MODE_LIST" == "0" ] &&
       [ -d "$SHAR_PKG_INST_DIR" ];
    then
      INST_MODE_LIST+=",5"
    fi
    # --------------------------------------------------------------------------
    # Wenn Paket mehrfach installiert Liste und Auswahl anzeigen
    # --------------------------------------------------------------------------
    if [ ${#INST_MODE_LIST} -gt 3 ]; # "0,n" z.B. "0,2,4"
    then
      e_and_l " Das Paket ${bold_yellow}$REMOVE_PKG_NAME${colors_off} scheint mehrfach installiert:"
      # ----
      # STD
      # ----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",1") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_apt_version "$REMOVE_PKG_NAME" 0)
        e_and_l -n " [${bold_yellow}1${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "als Paket aus dem Standard-Repository"
      fi
      # -----
      # SNAP
      # -----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",2") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_snap_version "$REMOVE_PKG_NAME" 0)
        e_and_l -n " [${bold_yellow}2${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "als Snap-Paket"
      fi
      # ----
      # DEB
      # ----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",3") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_deb_version "$REMOVE_PKG_NAME")
        e_and_l -n " [${bold_yellow}3${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "in /opt/$OPT_PKG_INST_NAME"
      fi
      # ----
      # WEB
      # ----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",4") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_web_version "$REMOVE_PKG_NAME")
        e_and_l -n " [${bold_yellow}4${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "in $WEB_PKG_DIR/$WEB_PKG_INST_NAME"
      fi
      # -----
      # SHAR
      # (zur Vollständigkeit - sollte hier ja eigentlich nicht vorkommen - s.o)
      # -----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",5") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_shar_version "$REMOVE_PKG_NAME")
        e_and_l -n " [${bold_yellow}5${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "in $SHAR_PKG_INST_DIR"
      fi
      # -----
      # FLAT
      # -----
      if [ $(echo "$INST_MODE_LIST" | grep -c -E ",6") -ne 0 ];
      then
        TMP_PKG_VERSION=$(get_pkg_flatpak_version "$REMOVE_PKG_NAME" 1)
        e_and_l -n " [${bold_yellow}6${colors_off}] "
        if [ "$TMP_PKG_VERSION" != "" ]; then e_and_l -n "Version $TMP_PKG_VERSION "; fi
        e_and_l "als Flatpak"
      fi
      # ------------------------------------------
      # Auswahl der zu entfernenden Paket-Version
      # ------------------------------------------
      e_and_l -n " Bitte auswählen, welche Version entfernt werden soll: "
      INST_STATUS=0
      while [ $INST_STATUS -eq 0 ];
      do
        read -N 1 -r -s INST_STATUS
        INST_STATUS=$(echo $INST_STATUS | sed 's/[^0-9]*//g')
        if [ "$INST_STATUS" == "" ] ||
           [ $(echo "$INST_MODE_LIST" | grep -c -E "$INST_STATUS") -eq 0 ];
        then
          INST_STATUS=0
        fi
      done
      e_and_l "$INST_STATUS"
    fi
    # --------------------------------------------------------------------------
    # Auswahl der Optionen zur Entfernung des Paketes
    # --------------------------------------------------------------------------
    TMP_PKG_TYPE="$(inst_status_to_name $INST_STATUS)"
    e_and_l " Optionen zur Entfernung von ${bold_yellow}$REMOVE_PKG_NAME${colors_off} (${bold_magenta}$TMP_PKG_TYPE${colors_off}):"
    i=0
    while [ $i -lt 4 ];
    do
      e_and_l " [${bold_yellow}$i${colors_off}] ${REMOVE_TEXT[$i]}"
      ((i+=1))
    done
    while [ $REMOVE_ACTION -lt 0 ];
    do
      e_and_l -n " Bitte eine Option auswählen: "
      while [ $REMOVE_ACTION -lt 0 ] ||
            [ $REMOVE_ACTION -gt 3 ];
      do
        read -N 1 -r -s REMOVE_ACTION
        REMOVE_ACTION=$(echo $REMOVE_ACTION | sed 's/[^0-9]*//g')
        if [ "$REMOVE_ACTION" == "" ]; then REMOVE_ACTION=-1; fi
      done
      if [ $REMOVE_ACTION -eq 0 ];
      then
        e_and_l "Abbruch"
      else
        e_and_l "$REMOVE_ACTION"
        ask_yes_or_no_plus "" " Wirklich ${REMOVE_TEXT[$REMOVE_ACTION]}" "" "n"
        if [ $? -eq 0 ];
        then
          REMOVE_ACTION=-1
        fi
      fi
    done
  else
    # ----------------------------------------------------------------------
    # Prüfen ob es andere ähnlich lautende installierte Pakete gibt
    # (Derzeit nur für installierte Pakete der Art STD, FLAT, SNAP und WEB)
    # ----------------------------------------------------------------------
    GUESS_INSTALL_LIST_APT="$DOWNLOAD_DIR/guess_install_list_apt"
    GUESS_INSTALL_LIST_FLAT="$DOWNLOAD_DIR/guess_install_list_flat"
    GUESS_INSTALL_LIST_SNAP="$DOWNLOAD_DIR/guess_install_list_snap"
    GUESS_INSTALL_LIST_WEB="$DOWNLOAD_DIR/guess_install_list_web"
    GUESS_NAME="${REMOVE_PKG_NAME/-qt/}"
    # ----
    # STD
    # ----
    apt list *${GUESS_NAME}* 2>/dev/null | grep -i install 1>"$GUESS_INSTALL_LIST_APT" 2>/dev/null
    # -----
    # FLAT
    # -----
    if [ -s "$FLATPAK_INSTALLED_PKG_LIST" ];
    then
      # ------------------------------------------------------------------
      # Sicherheitshalber nur installierte "Anwendungen" (--app) anzeigen
      # ------------------------------------------------------------------
      cat "$FLATPAK_INSTALLED_PKG_LIST" | grep -i ${GUESS_NAME} 1>"$GUESS_INSTALL_LIST_FLAT" 2>/dev/null
    fi
    # -----
    # SNAP
    # -----
    if [ $SNAP_ACTIVE -gt 0 ];
    then
      snap list 2>/dev/null | grep -i ${GUESS_NAME} 1>"$GUESS_INSTALL_LIST_SNAP" 2>/dev/null
    fi
    # ----
    # WEB
    # ----
    if [ -d $WEB_PKG_DIR ];
    then
      ls -1 "$WEB_PKG_DIR" | sed -E "s/\'//g" | grep -i ${GUESS_NAME} > "$GUESS_INSTALL_LIST_WEB" 2>/dev/null
    fi
    # -----------------------------------------------------
    # Wenn es ähnlich lautende Pakete gibt, diese anzeigen
    # -----------------------------------------------------
    if [ -s "$GUESS_INSTALL_LIST_APT" ] ||
       [ -s "$GUESS_INSTALL_LIST_FLAT" ] ||
       [ -s "$GUESS_INSTALL_LIST_SNAP" ] ||
       [ -s "$GUESS_INSTALL_LIST_WEB" ];
    then
      e_and_l " $HINWEIS_TAG: Es sind ähnlich lautende Pakete installiert, meintest Du vielleicht:"
      # ----
      # STD
      # ----
      if [ -s "$GUESS_INSTALL_LIST_APT" ];
      then
        while read guess;
        do
          GUESS_PKG=${guess%%/*}
          if [ "$GUESS_PKG" != "" ];
          then
            e_and_l " - $GUESS_PKG (${light_magenta}STD${colors_off})"
          fi
        done < "$GUESS_INSTALL_LIST_APT"
      fi
      # -----
      # FLAT
      # -----
      if [ -s "$GUESS_INSTALL_LIST_FLAT" ];
      then
        while read guess;
        do
          GUESS_PKG=$(echo ${guess} | grep -i -E "\..*$GUESS_NAME.*[\/\.]" | tail -n 1 | cut -f 1 | xargs | sed 's/ /_/g' | tr '[:upper:]' '[:lower:]')
          if [ "$GUESS_PKG" != "" ];
          then
            e_and_l " - $GUESS_PKG (${light_magenta}FLAT${colors_off})"
          fi
        done < "$GUESS_INSTALL_LIST_FLAT"
      fi
      # -----
      # SNAP
      # -----
      if [ -s "$GUESS_INSTALL_LIST_SNAP" ];
      then
        while read guess;
        do
          GUESS_PKG=$(echo ${guess} | awk '{print $1}' | xargs)
          if [ "$GUESS_PKG" != "" ];
          then
            e_and_l " - $GUESS_PKG (${light_magenta}SNAP${colors_off})"
          fi
        done < "$GUESS_INSTALL_LIST_SNAP"
      fi
      # ----
      # WEB
      # ----
      if [ -s "$GUESS_INSTALL_LIST_WEB" ];
      then
        while read guess;
        do
          if [ "$guess" != "" ];
          then
            for p in ${!WEB_PKG_NAME[@]};
            do
              if [ "${WEB_PKG_NAME[$p]}" == "$guess" ] &&
                 [ $(find "$WEB_PKG_DIR/$guess" -type f -executable 2>/dev/null | wc -l) -gt 0 ];
              then
                e_and_l " - ${WEB_PKG_NAME[$p]} [$p] (${light_magenta}WEB${colors_off})"
              fi
            done
          fi
        done < "$GUESS_INSTALL_LIST_WEB"
      fi
      e_and_l ""
      remove_file "$GUESS_INSTALL_LIST_APT"
      remove_file "$GUESS_INSTALL_LIST_FLAT"
      remove_file "$GUESS_INSTALL_LIST_SNAP"
      remove_file "$GUESS_INSTALL_LIST_WEB"
    fi
    e_and_l " Ein Paket ${bold_yellow}$REMOVE_PKG_NAME${colors_off} scheint nicht ordentlich installiert zu sein."
    ask_yes_or_no_plus "" " Sollen hinterbliebene Daten von diesem Paket gesucht werden" "" "n"
    if [ $? -eq 1 ];
    then
      REMOVE_ACTION=3
    fi
  fi
  echo -e ""
  # ----------------------------------------------------------------------------
  # Entfernung je nach Installationsart durchführen
  # ----------------------------------------------------------------------------
  if [ $REMOVE_ACTION -gt 0 ];
  then
    # --------------------------------------------------------------------------
    # Nicht installiertes Paket, "nur" hinterbliebene Daten löschen
    # --------------------------------------------------------------------------
    if [ $INST_STATUS -eq 0 ];
    then
      e_and_l " ${light_blue}Schritt 1/3:${colors_off} Löschen verbliebener Paketrückstände"
      e_and_l " Starte Suche, bitte warten ... $FERTIG_TAG" # Nur Info-Anzeige
      TMP_PURGE_OUT="$DOWNLOAD_DIR/purge_output.tmp"
      if [ $(apt list "$REMOVE_PKG_NAME" -a 2>/dev/null | grep -c -i -E "$REMOVE_PKG_NAME") -gt 0 ];
      then
        { apt purge "$REMOVE_PKG_NAME" -y 2>&1; echo -e -n "$?" > "$LAST_EXIT_CODE"; } | tee "$TMP_PURGE_OUT"
        REMOVE_RESULT=$(cat "$LAST_EXIT_CODE")
        if [ $REMOVE_RESULT -eq 0 ];
        then
          e_and_l " Gefundene Paketrückstände wurden entfernt ... $OK_TAG"
        fi
      fi
      if [ ! -s "$TMP_PURGE_OUT" ];
      then
        e_and_l " Es sind keine Paketrückstände mehr vorhanden ... $OK_TAG"
      fi
      remove_file "$TMP_PURGE_OUT"
      remove_file "$LAST_EXIT_CODE"
      remove_snapshots "$REMOVE_PKG_NAME" 1
      remove_starter "$REMOVE_PKG_NAME"
      remove_cfg "$REMOVE_PKG_NAME" 1
      remove_dat "$REMOVE_PKG_NAME"
    fi

    # --------------------------------------------------------------------------
    # Standard-Paketverwaltung (apt) und Snaps
    # --------------------------------------------------------------------------
    if [ $INST_STATUS -eq 1 ] ||
       [ $INST_STATUS -eq 2 ];
    then
      e_and_l -n " ${light_blue}Schritt 1/$REMOVE_ACTION:${colors_off}"
      REMOVE_RESULT=-1
      if [ $REMOVE_ACTION -eq 1 ];
      then
        remove_pkg "$REMOVE_PKG_NAME" 0 # remove
      else
        remove_pkg "$REMOVE_PKG_NAME" 1 # purge
      fi
      # -------------------------------------------
      # Bei Snap auch noch die Snapschüsse löschen
      # -------------------------------------------
      if [ $INST_STATUS -eq 2 ];
      then
        remove_snapshots "$REMOVE_PKG_NAME" 1
      fi
      if [ $REMOVE_RESULT -eq 0 ];
      then
        remove_starter "$REMOVE_PKG_NAME"
        if [ $REMOVE_ACTION -gt 1 ];
        then
          remove_cfg "$REMOVE_PKG_NAME" 0
        fi
        if [ $REMOVE_ACTION -gt 2 ];
        then
          remove_dat "$REMOVE_PKG_NAME"
        fi
      fi
    fi

    # --------------------------------------------------------------------------
    # Ordner mit ausführbaren Dateien (DEB, WEB und SHAR)
    # --------------------------------------------------------------------------
    if [ $INST_STATUS -eq 3 ] ||
       [ $INST_STATUS -eq 4 ] ||
       [ $INST_STATUS -eq 5 ];
    then
      # ------------------------------------------------------------------------
      # Installations-Ordner ermitteln
      # ------------------------------------------------------------------------
      e_and_l " ${light_blue}Schritt 1/$REMOVE_ACTION:${colors_off} Löschen von ${bold_yellow}$REMOVE_PKG_NAME${colors_off} ..."
      THE_PKG_INST_DIR=""
      # ----
      # DEB
      # ----
      if [ $INST_STATUS -eq 3 ] &&
         [ "$OPT_PKG_INST_NAME" != "" ];
      then
        THE_PKG_INST_DIR="/opt/$OPT_PKG_INST_NAME"
      fi
      # ----
      # WEB
      # ----
      if [ $INST_STATUS -eq 4 ] &&
         [ "$WEB_PKG_INST_NAME" != "" ];
      then
        THE_PKG_INST_DIR="$WEB_PKG_DIR/$WEB_PKG_INST_NAME"
      fi
      # -----
      # SHAR
      # -----
      if [ $INST_STATUS -eq 5 ] &&
         [ "$SHAR_PKG_INST_DIR" != "" ];
      then
        THE_PKG_INST_DIR="$SHAR_PKG_INST_DIR"
      fi
      # ------------------------------------------------------------------------
      if [ "$THE_PKG_INST_DIR" != "" ] &&
         [ -d "$THE_PKG_INST_DIR" ];
      then
        # -----------------------------------------------------------
        # Wenn es ein Skript oder Programm zur De-Installation gibt,
        # dann Hinweis darauf anzeigen und weiter nichts machen ...
        # -----------------------------------------------------------
        REMOVE_SCRIPT_FOUND=""
        REMOVE_SCRIPT_LIST="uninstall uninstall.sh deinstall deinstall.sh remove remove.sh"
        for rm_script in ${REMOVE_SCRIPT_LIST[@]};
        do
          if [ -s "$THE_PKG_INST_DIR/${rm_script}" ];
          then
            REMOVE_SCRIPT_FOUND="$THE_PKG_INST_DIR/$rm_script"
            break
          fi
        done
        if [ "$REMOVE_SCRIPT_FOUND" != "" ];
        then
          e_and_l " $ACHTUNG_TAG: Das Programm verfügt über ein eigenes De-Installations-Skript."
          e_and_l " Zu finden unter: ${light_yellow}$REMOVE_SCRIPT_FOUND${colors_off}"
          e_and_l " Bitte dieses zuerst manuell ausführen und danach nochmals versuchen."
        # ---------------------------------------------------------
        # ... sonst Installations-Ordner mit allen Dateien löschen
        # ---------------------------------------------------------
        else
          rm -f -r -d "$THE_PKG_INST_DIR"
          if [ $? -eq 0 ];
          then
            e_and_l " Das Programm wurde aus ${light_yellow}$THE_PKG_INST_DIR${colors_off} entfernt ... $OK_TAG"
            remove_starter "$REMOVE_PKG_NAME"
            if [ $REMOVE_ACTION -gt 1 ];
            then
              remove_cfg "$REMOVE_PKG_NAME" 0
            fi
            if [ $REMOVE_ACTION -gt 2 ];
            then
              remove_dat "$REMOVE_PKG_NAME"
            fi
          else
            e_and_l " $ERROR_TAG: Das Programm konnte ${bold_red}nicht${colors_off} entfernt werden!"
          fi
        fi
      fi
    fi

    # --------------------------------------------------------------------------
    # Flatpak
    # --------------------------------------------------------------------------
    if [ $INST_STATUS -eq 6 ];
    then
      e_and_l -n " ${light_blue}Schritt 1/$REMOVE_ACTION:${colors_off}"
      remove_pkg "$REMOVE_PKG_NAME" 0
      if [ $REMOVE_RESULT -eq 0 ];
      then
        remove_starter "$REMOVE_PKG_NAME"
        if [ $REMOVE_ACTION -gt 1 ];
        then
          remove_cfg "$REMOVE_PKG_NAME" 0
        fi
        if [ $REMOVE_ACTION -gt 2 ];
        then
          remove_dat "$REMOVE_PKG_NAME"
        fi
        update_flatpak_list
      fi
    fi
    # --------------------------------------------------------------------------

    echo -e ""
  fi
  # ----------------------------------------------------------------------------
  # e_and_l "$FULL_LINE"
fi # Ende [remove]

#===============================================================================
# Aufräumen und Hinweise am Ende anzeigen
#===============================================================================
clean_on_exit
e_and_l "$FULL_LINE"
e_and_l " ${bold_blue}Hinweise${colors_off}"
e_and_l "$FULL_LINE"
anzahl_hinweise=0
if [ -s "$USER_SCRIPT_CONFIG" ] ||
   [ -s "$USER_PAKET_LIST" ];
then
  e_and_l " Ordner mit gespeicherten Einstellungen: ${light_yellow}$SCRIPT_CONFIG_DIR${colors_off}"
  ((anzahl_hinweise+=1))
fi
if [ ${OPTION_FLAG[listonly]} -eq 0 ];
then
  if [ $TOTAL_PACKS -gt 0 ] ||
     [ $USE_ILIST_FILE -eq 1 ];
  then
    if [ -d "$WEB_PKG_DIR" ] &&
       [ $(ls -1 "$WEB_PKG_DIR" | wc -w) -gt 0 ];
    then
      e_and_l " Ordner mit externen Programmen (WEB): ${light_yellow}$WEB_PKG_DIR${colors_off}"
      ((anzahl_hinweise+=1))
    fi
  fi
  if [ -d "$DOWNLOAD_DIR" ] &&
     [ $(ls -1 "$DOWNLOAD_DIR" | wc -w) -gt 0 ];
  then
    e_and_l " Ordner mit gespeicherten Dateien: ${light_yellow}$DOWNLOAD_DIR${colors_off}"
    ((anzahl_hinweise+=1))
  fi
  if [ -s "$DCONF_USER_BACKUP" ];
  then
    e_and_l "$HALF_LINE"
    e_and_l " $ACHTUNG_TAG: Es liegt ein Konfigurations-Backup für ${light_cyan}Desktop & diverse Tools${colors_off} vor."
    e_and_l " Zurücksetzen der Einstellungen auf diese Konfiguration (ohne sudo):"
    e_and_l " ${light_magenta}dconf load / < ${DCONF_USER_BACKUP}${colors_off}"
    ((anzahl_hinweise+=1))
  fi
else
  e_and_l " Wenn die Option ${bold_white}listonly${colors_off} zur Auflistung der Paketnamen angegeben ist, werden"
  e_and_l " alle anderen angegebenen Optionen außer der Kategorieauswahl ignoriert."
  ((anzahl_hinweise+=1))
fi
if [ $anzahl_hinweise -gt 0 ]; then e_and_l "$HALF_LINE"; fi
echo -e " Aufruf per Kommandozeile:"
echo -e "${light_yellow} ${0} $COMMAND_LINE_STRING ${colors_off}"

show_full_bg_line
e_and_l ""
e_and_l " ${bold_green}Alles erledigt${colors_off}, Verarbeitungszeit: ${light_yellow}$(time_to_string $(($(date +%s) - SCRIPT_TIME_START)) false true)${colors_off}."

e_and_l ""
e_and_l " Was soll jetzt passieren?"
e_and_l " [${bold_yellow}0${colors_off}] Nichts, Lissy beenden"
e_and_l " [${bold_yellow}1${colors_off}] Neuer Durchlauf mit aktuellen Einstellungen (ohne Auswahl-Menü)"
e_and_l " [${bold_yellow}2${colors_off}] Neuer Durchlauf mit aktuellen Einstellungen (mit Auswahl-Menü)"
e_and_l " [${bold_yellow}3${colors_off}] Neuer Durchlauf mit Standard-Einstellungen (mit Auswahl-Menü)"
e_and_l " [${bold_yellow}4${colors_off}] Alle benutzerspezifischen Einstellungen und Listen löschen"
e_and_l " [${bold_yellow}5${colors_off}] Rechner neu starten (Reboot)"
e_and_l " [${bold_yellow}6${colors_off}] Rechner ausschalten (Shutdown)"
e_and_l ""
e_and_l -n " Bitte auswählen: "

# Info als Pop-up anzeigen
# if zenity --version &>/dev/null;
# then
#   zenity --info --title="Info von Lissy" --text="Alles erledigt, bitte Aktion\nim Terminal auswählen." &>/dev/null &
# fi

ACTION=-1
while [ $ACTION -lt 0 ] ||
      [ $ACTION -gt 6 ];
do
  read -N 1 -r -s ACTION
  ACTION=$(echo $ACTION | sed 's/[^0-9]*//g')
  if [ "$ACTION" == "" ]; then ACTION=-1; fi
done
e_and_l "$ACTION"

case $ACTION in
  1) ${0} $COMMAND_LINE_STRING nomenu recall ;;
  2) ${0} $COMMAND_LINE_STRING recall ;;
  3) ${0} noconfig recall ;;
  4) e_and_l " $ACHTUNG_TAG: Dies löscht alle individuell gespeicherten Einstellungen und Listen!"
     ask_yes_or_no_pure " Wirklich alle gespeicherten Daten dieses Programms löschen"
     if [ $? -eq 1 ]; then ${0} noconfig recall; fi ;;
  5) ask_yes_or_no_pure " Den Rechner jetzt wirklich neu starten"
     if [ $? -eq 1 ]; then reboot; fi ;;
  6) ask_yes_or_no_pure " Den Rechner jetzt wirklich ausschalten"
     if [ $? -eq 1 ]; then shutdown +0; fi ;;
esac

if [ $RECALL -eq 0 ];
then
  e_and_l ""
  e_and_l " ${bold_green}Vielen Dank${colors_off} für die Benutzung von Lissy. ${bold_green}Auf Wiedersehen${colors_off} ..."
fi
e_and_l ""

################################################################################
#                                                                              #
#                                     Ende                                     #
#                                                                              #
################################################################################
