#!/usr/bin/env bash
# Author: Castro-Fidel (linux-gaming.ru)
# shellcheck disable=SC2140,SC2034,SC2068,SC2206
########################################################################
$PW_DEBUG
print_error () { printf "\E[31m%s Error: $@ %s\e[0m\n" ;}
export -f print_error

print_warning () { printf "\E[33m%s Warning: $@ %s\e[0m\n" ;}
export -f print_warning

print_info () { printf "\E[36m%s Info: $@ %s\e[0m\n" ;}
export -f print_info

print_ok () { printf "\E[35m%s OK: $@ %s\e[0m\n" ;}
export -f print_ok

print_var () { for vp in $@ ; do print_info "${vp}=${!vp}" ; done ;}
export -f print_var

print_wrapped () {
    local text="$1"
    local a="0"
    local b="$2"

    if [[ -n "$3" ]] ; then
        if (( ${#text} > b )); then
            echo "${text:a:b}${3}"
        else
            echo "$text"
        fi
    else
        while (( a < ${#text} )) ; do
            echo "${text:a:b}"
            ((a+=b))
        done
    fi
}
export -f print_wrapped

make_acronym () {
    local words acronym i
    words=($1)
    acronym="${words[0]:0:1}"
    for ((i=1 ; i<${#words[@]} ; i++)) ; do
        acronym+="${words[$i]:0:1}"
    done
    echo "$acronym"
}
export -f make_acronym

make_abbreviation () {
    local word abbreviation i
    word=$1
    for (( i=0 ; i<${#word} ; i++ )) ; do
        if [[ ${word:$i:1} =~ ^[A-Z]$ ]] ; then
            abbreviation+="${word:$i:1}"
        fi
    done
    echo "$abbreviation"
}
export -f make_abbreviation

check_variables () { [[ -z ${!1} ]] && export $1="$2" ;}

add_to_var () {
    if ! echo ${!1} | grep "$2" &>/dev/null
    then export $1="${!1} $2"
    fi
}

rm_from_var () {
    if echo ${!1} | grep "$2" &>/dev/null
    then export $1="$(echo "${!1//$2/}" | tr -s " ")"
    fi
}

add_to_array () {
    local array_name=$1
    local add_names=${*:2}

    if [[ -v "$array_name" ]] ; then
        for element in $add_names ; do
            eval "$array_name+=($element)"
        done
    else
        print_error "$array_name not found for array"
    fi
}

rm_from_array () {
    local array_name=$1
    local rm_names=${*:2}

    if [[ -v "$array_name" ]] ; then
        local count=0
        eval \
        "for element in \${$array_name[@]} ; do
            if [[ \$rm_names =~ \$element ]] ; then
                unset $array_name[\$count]
                $array_name=(\${$array_name[@]})
            fi
            ((count++))
        done"
    else
        print_error "$array_name not found for array"
    fi
}

fatal () {
    print_error "$@"
    exit 1
}

change_locale () {
    if [[ -f "${PORT_WINE_TMP_PATH}/PortProton_loc" ]] ; then
        LANGUAGE=$(<"${PORT_WINE_TMP_PATH}/PortProton_loc")

        # TODO: drop legacy check language after 01.01.2025
        if [[ "$LANGUAGE" == "RUS" ]] ; then
            LANGUAGE="ru"
            echo "ru" > "${PORT_WINE_TMP_PATH}/PortProton_loc"
        elif [[ "$LANGUAGE" == "ENG" ]] ; then
            LANGUAGE="en"
            echo "en" > "${PORT_WINE_TMP_PATH}/PortProton_loc"
        fi
    fi

    local GAME_LANGUAGE="$LANGUAGE"

    if check_gamescope_session ; then
        LANGUAGE="en"
    else
        [[ ! -f "${pw_yad}" ]] && pw_yad="yad"
        if [[ -z "$LANGUAGE" ]] \
        || [[ "${PW_FORCE_CHANGE_LOC}" == "1" ]] ; then
            SET_LANG=(
                "${pw_yad}" --list
                --window-icon="$PW_GUI_ICON_PATH/portproton.svg"
                --title="Select language for PortProton"
                --column="Language" --column=""
                --width=400 --height=200

                "Russian (Русский)"                     ru
                "English"                               en
                "Spanish (Español・Española)"            es
            )

            out=$("${SET_LANG[@]}")
            if [[ -z $out ]] \
            && [[ -n "$LANGUAGE" ]] ; then
                echo "${LANGUAGE}" > "${PORT_WINE_TMP_PATH}/PortProton_loc"
            elif [[ -z $out ]] ; then
                echo "en" > "${PORT_WINE_TMP_PATH}/PortProton_loc"
            else
                LANGUAGE=$(echo "$out" | cut -d '|' -f2)
                echo "${LANGUAGE}" > "${PORT_WINE_TMP_PATH}/PortProton_loc"
                create_translations
            fi
            unset PW_FORCE_CHANGE_LOC
            restart_pp
        fi
    fi
    export LANGUAGE

    case "$GAME_LANGUAGE" in
        ru)
            check_start_from_steam && export LC_ALL=ru_RU.UTF-8
            export FULL_LN="russian"
            export LANGUAGE_GIF="ru"
            ;;
        es)
            check_start_from_steam && export LC_ALL=es_ES.UTF-8
            export FULL_LN="spanish"
            export LANGUAGE_GIF="en"
            ;;
         *)
            export FULL_LN="english"
            export LANGUAGE_GIF="en"
            export LANGUAGE="en"
            ;;
    esac

}
export -f change_locale

generate_pot () {
    sed 's/{translations\[/(gettext \"/g' functions_helper > functions_helper_tmp
    sed -i 's/]}/")/g' functions_helper_tmp
    sed -i 's/eval_translations/gettext/g' functions_helper_tmp

    sed 's/{translations\[/(gettext \"/g' start.sh > start.sh_tmp
    sed -i 's/]}/")/g' start.sh_tmp
    sed -i 's/eval_translations/gettext/g' start.sh_tmp

    sed 's/{translations\[/(gettext \"/g' setup.sh > setup.sh_tmp
    sed -i 's/]}/")/g' setup.sh_tmp
    sed -i 's/eval_translations/gettext/g' setup.sh_tmp

    sed 's/{translations\[/(gettext \"/g' add_in_steam.sh > add_in_steam.sh_tmp
    sed -i 's/]}/")/g' add_in_steam.sh_tmp
    sed -i 's/eval_translations/gettext/g' add_in_steam.sh_tmp

    #Когда присходит предупреждение: синтаксис $"..." запрещен по соображениям безопасности; используйте eval_gettext
    #и ругается на строку в которой нет перевода, можно использовать sed -i '//d' и убрать эту строку
    #либо отредактировать сам код, чтобы не было такой ошибки (к примеру вместо двойных ковычек использовать в таком месте одинарные)

    for lang in $LANGUAGES_LIST
    do
        echo "${lang}"
        create_new_dir "${PORT_WINE_PATH}/data/locales/${lang}/LC_MESSAGES/"
        LANG_PO="${PORT_WINE_PATH}/data/locales/${lang}/LC_MESSAGES/PortProton.po"
        #LANG_MO="${PORT_WINE_PATH}/data/locales/${lang}/LC_MESSAGES/PortProton.mo"
        TEMPLATE_POT="${PORT_WINE_PATH}/data/locales/PortProton.pot"
        pushd "${PORT_WINE_PATH}" 1>/dev/null || fatal
        xgettext --no-location --from-code=UTF-8 --language Shell -i \
        "data/scripts/start.sh_tmp" \
        "data/scripts/setup.sh_tmp" \
        "data/scripts/functions_helper_tmp" \
        "data/scripts/add_in_steam.sh_tmp" \
        -o "$TEMPLATE_POT"
        popd 1>/dev/null || fatal
        if [[ -f "$LANG_PO" ]] ; then
            echo "update $LANG_PO file"
            msgmerge --update "$LANG_PO" "$TEMPLATE_POT"
        else
            echo "create $LANG_PO file"
            msginit --input="$TEMPLATE_POT" --locale="${lang}" --output="$LANG_PO"
        fi
        #msgfmt --output-file="$LANG_MO" "$LANG_PO"
    done
    try_remove_file "${PORT_SCRIPTS_PATH}/start.sh_tmp"
    try_remove_file "${PORT_SCRIPTS_PATH}/setup.sh_tmp"
    try_remove_file "${PORT_SCRIPTS_PATH}/functions_helper_tmp"
    try_remove_file "${PORT_SCRIPTS_PATH}/add_in_steam.sh_tmp"
    try_remove_dir "${PW_CACHE_LANG_PATH}"
}
export -f generate_pot

eval_translations () {
    # Для того чтобы раскрывать переменную уже после создания массива
    # Вместо {translations[\$TEST text]} нужно (eval_translations "\$%TEST% text" "TEST=test"), перевод должен быть с %% тоже
    # В остальных случаях можно использовать {translations[\$TEST text]} ,но переменную нужно обьявлять до создания массива
    # до source "${PW_CACHE_LANG_PATH}/$LANGUAGE" или можно использовать команды {translations[\$(cat file.txt) text]}
    # но тогда выполнение команды будет происходить во время создания массива всегда, а не там где это требуется
    echo "${translations[$1]//\$*"%"/${2//*=/}}"
}

create_translations () {
    local po_file msgid msgstr
    [[ ! -d $PW_CACHE_LANG_PATH ]] && create_new_dir "$PW_CACHE_LANG_PATH"
    cat << EOF > "${PW_CACHE_LANG_PATH}/$LANGUAGE"
#!/usr/bin/env bash
TRANSLATIONS_VER=$scripts_install_ver
declare -A translations=(
EOF
    if [[ $LANGUAGE == "en" ]] ; then
        po_file="${PORT_WINE_PATH}/data/locales/PortProton.pot"
    else
        po_file="${PORT_WINE_PATH}/data/locales/$LANGUAGE/LC_MESSAGES/PortProton.po"
    fi

    while IFS= read -r line ; do
        while [[ $line =~ msgid ]] ; do
                unset msgid
                msgid="$line"
                read -r line
            while [[ ! $line =~ msgstr ]] ; do
                msgid+="$line"
                read -r line
            done
            if [[ $line =~ msgstr ]]; then
                if [[ $LANGUAGE == "en" ]] ; then
                    if [[ $msgid == "msgid   \"\"" ]] ; then
                        continue
                    fi
                    msgstr="$msgid"
                else
                    unset msgstr
                    msgstr="$line"
                    read -r line
                    while [[ ! $line =~ msgid ]] ; do
                        msgstr+=$line
                        read -r line
                        if [[ -z $line ]] ; then
                            break
                        fi
                    done
                fi
            fi
        if [[ $LANGUAGE != "en" ]] ; then
            msgstr=${msgstr//"msgstr "/}
            msgid=${msgid//"msgid "/}
        fi
        msgstr=${msgstr//" "/-_-}
        msgstr=${msgstr//"\n"\"\"/+_+}
        msgstr=${msgstr//\"\"/}
        msgstr=${msgstr//#*/}
        msgstr=${msgstr//"*"/#_#}
        msgid=${msgid//" "/-_-}
        msgid=${msgid//"\n"\"\"/+_+}
        msgid=${msgid//\"\"/}
        msgid=${msgid//#*/}
        msgid=${msgid//"*"/#_#}
        if [[ $msgid != "" ]] ; then
            if [[ -z $msgstr ]] ; then
                msgstr="$msgid"
            fi
            if [[ $msgid =~ \$ ]] ; then
                msgid=${msgid//\$/\\$}
                if [[ $msgstr =~ \$% ]] ; then
                    msgstr=${msgstr//\$/\\$}
                fi
            fi
            echo \["$msgid"\]="$msgstr" >> "${PW_CACHE_LANG_PATH}/$LANGUAGE"
        fi
        done
    done < "$po_file"
    IFS="$orig_IFS"

    echo ")" >> "${PW_CACHE_LANG_PATH}/$LANGUAGE"
    sed -i 's/+_+/\n/g' "${PW_CACHE_LANG_PATH}/$LANGUAGE"
    sed -i 's/#_#/\*/g' "${PW_CACHE_LANG_PATH}/$LANGUAGE"
    sed -i 's/-_-/ /g' "${PW_CACHE_LANG_PATH}/$LANGUAGE"
    if [[ $LANGUAGE == "en" ]] ; then
        sed -i 's/msgid   //g' "${PW_CACHE_LANG_PATH}/$LANGUAGE"
    fi
}
export -f create_translations

try_copy_file () {
    if [[ ! -f "$1" ]] ; then print_info "file $1 not found for copy" && return 1
    elif [[ -z "$2" ]] ; then print_error "no way to copy file $1" && return 1
    elif [[ -L "$2" ]] ; then print_warning "$2 is a file with a symbolic link"
        try_remove_file "$2"
        cp -f "$1" "$2" && return 0 || return 1
    elif [[ -f "$2.sha256sum" ]] ; then print_warning "$2 this file has sha256sum"
        try_remove_file "$2"
        try_remove_file "$2.sha256sum"
        cp -f "$1" "$2" && return 0 || return 1
    else
        [[ -e "$2/$(basename "$1")" ]] && rm -f "$2/$(basename "$1")"
        cp -f "$1" "$2" && return 0 || return 1
    fi
}
export -f try_copy_file

try_copy_file_with_checksums () {
    if [[ ! -f "$1" ]] ; then print_info "file $1 not found for copy" && return 1
    elif [[ -z "$2" ]] ; then print_error "no way to copy file $1" && return 1
    elif [[ -L "$2" ]] ; then print_warning "$2 is a file with a symbolic link"
        try_remove_file "$2"
        if cp -f "$1" "$2" ; then
            if [[ "${PW_FILESYSTEM}" == "ext2/ext3" ]] \
            || [[ "${PW_FILESYSTEM}" == "f2fs" ]] \
            || [[ "${PW_FILESYSTEM}" != "btrfs" ]]
            then
                checksum1="$(sha256sum "$1")"
                echo "${checksum1// */}" > "$2.sha256sum"
            fi
            return 0
        else
            return 1
        fi
    else
        if [[ "${PW_FILESYSTEM}" == "ext2/ext3" ]] \
        || [[ "${PW_FILESYSTEM}" == "f2fs" ]] \
        || [[ "${PW_FILESYSTEM}" != "btrfs" ]]
        then
            checksum1="$(sha256sum "$1")"
            if [[ ! -f "$2" ]] ; then
                if cp -f "$1" "$2" ; then
                    echo "${checksum1// */}" > "$2.sha256sum"
                    return 0
                else
                    return 1
                fi
            else
                if [[ ! -f "$2.sha256sum" ]] ; then
                    checksum2="$(sha256sum "$2")"
                    echo "${checksum2// */}" > "$2.sha256sum"
                else
                    checksum2="$(<"$2.sha256sum")"
                fi
            fi
            if [[ "${checksum1// */}" == "${checksum2// */}" ]] ; then
                return 0
            else
                try_remove_file "$2"
                if cp -f "$1" "$2" ; then
                    echo "${checksum1// */}" > "$2.sha256sum"
                    return 0
                else
                    return 1
                fi
            fi
        else
            [[ -e "$2/$(basename "$1")" ]] && rm -f "$2/$(basename "$1")"
            cp -f "$1" "$2" && return 0 || return 1
        fi
    fi
}
export -f try_copy_file_with_checksums

try_copy_dir () {
    if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for copy"
    elif [[ -z "$2" ]] ; then print_error "no way to copy directory $1"
    else
        cp -fr "$1" "$2"
        [[ "$?" != 0 ]] && print_error "failed to copy directory $1 to $2" || return 0
    fi
    return 1
}
export -f try_copy_dir

try_remove_file () {
    if [[ -f "$1" ]] || [[ ! -e "$1" ]] ; then
        rm -f "$1"
        [[ "$?" == 0 ]] && return 0 || return 1
    fi
}
export -f try_remove_file

try_remove_dir () {
    if [[ -d "$1" ]] ; then
        rm -fr "$1"
        [[ "$?" == 0 ]] && return 0 || return 1
    fi
}
export -f try_remove_dir

create_new_dir () {
    if [[ ! -d "$1" ]] ; then
        mkdir -p "$1"
    fi
    return 0
}

try_force_link_file () {
    if [[ ! -f "$1" ]] ; then
        print_warning "file not found for link: $1"
        if [[ -f "$2" ]] ; then
            try_remove_file "$2"
            print_warning "removed old link: $2"
        fi
        return 1
    elif [[ -z "$2" ]] ; then print_error "no way to link file $1" && return 1
    elif [[ -f "$2.sha256sum" ]] ; then print_warning "$2 this file has sha256sum"
        try_remove_file "$2"
        try_remove_file "$2.sha256sum"
        ln -s -f -r "$1" "$2"
        return 0
    else
        try_remove_file "$2"
        ln -s -f -r "$1" "$2"
        return 0
    fi
    return 1
}
export -f try_force_link_file

check_symlink () {
    CHK_SYMLINK_FILE="$(file "$1")"
    if [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep -v "broken" | grep "symbolic link to" | awk '{print $1}')" ]] ; then
        return 0
    elif [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep "broken symbolic link to" | awk '{print $1}')" ]] ; then
        print_error "remove broken symlink: $CHK_SYMLINK_FILE"
        rm -fr "$CHK_SYMLINK_FILE"
        return 1
    else
        return 1
    fi
}
export -f check_symlink

try_force_link_dir () {
    if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for link"
    elif [[ -z "$2" ]] ; then print_error "no way to link directory $1"
    else
        ln -s -f -r "$1" "$2"
        [[ "$?" != 0 ]] && print_error "failed to link directory $1 to $2" || return 0
    fi
    return 1
}
export -f try_force_link_dir

check_process () {
    [[ -z "$(ps cax | grep "$1" | awk '{print $1}')" ]] && return 0 || return 1
}
export -f check_process

try_check_sha256sum () {
    if [[ "$no_mirror" == true ]] ; then
        print_ok "Used no_mirror downloading. Skipping check sha256sum."
        return 0
    fi
    SHA256SUM_EXT=$(curl --silent -L "${1//.tar*/}.sha256sum" | awk '{print $1}')
    if [[ ${#SHA256SUM_EXT} == 64 ]] ; then
        SHA256SUM_INT=$(sha256sum "$dest" | awk '{print $1}')
        if [[ "$SHA256SUM_EXT" == "$SHA256SUM_INT" ]] ; then
            print_ok "Verification sha256sum was successfully."
            return 0
        else
            print_error "Verification sha256sum was failed."
            return 1
        fi
    else
        print_warning "sha256sum not found for $(basename "$dest") on server. Skip it."
        return 0
    fi
}

try_download () {
    export dest="$2"
    local silent="false"
    export no_mirror="false"
 
    case "$3" in
           silent)
                silent=true ;;
        no_mirror)
                no_mirror=true
    esac

    local filename
    if [[ -n "${PW_AUTOINSTALL_EXE}" ]] \
    && [[ "$no_mirror" == "true" ]]
    then
        filename="$(basename "${PW_AUTOINSTALL_EXE}")"
    else
        filename="$(basename "$1")"
    fi

    if [[ "${MIRROR}" == CLOUD ]] \
    && [[ "$no_mirror" != "true" ]]
    then
        FIRST_URL=("$url_cloud/$filename")
        SECOND_URL=($1)
    else
        FIRST_URL=($1)
        SECOND_URL=("$url_cloud/$filename")
    fi

    [[ ! -f "${pw_yad}" ]] && local pw_yad="yad"

    # If gamescope session is active, use PW_TERM for downloading
    if check_gamescope_session ; then
        $PW_TERM "echo ; echo ; echo \"Downloading: $filename. Please wait...\" \
        ; curl -f -# -A 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)' -H 'Cache-Control: no-cache, no-store' \
        -H 'Pragma: no-cache' -L ${FIRST_URL[@]} -o \"$dest\""
        [[ "$?" != 0 ]] && return 1 || return 0
    fi

    # Normal download
    print_info "Download $filename from ${FIRST_URL[0]}..."
    set -o pipefail
    if [[ "$silent" == "true" ]] ; then
        curl -f -# -A 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)' -H 'Cache-Control: no-cache, no-store' \
        -H 'Pragma: no-cache' -L ${FIRST_URL[@]} -o "$dest" 2>&1
    else
        curl -f -# -A 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)' -H 'Cache-Control: no-cache, no-store' \
        -H 'Pragma: no-cache' -L ${FIRST_URL[@]} -o "$dest" 2>&1 | \
        tr '\r' '\n' | sed -ur 's|[# ]+||g;s|.*=.*||g;s|.*|#Downloading at &\n&|g' | \
        "$pw_yad" --progress --pulsate --text="${translations[Downloading]} $filename" --auto-close --no-escape \
        --auto-kill --text-align="center" --fixed --no-buttons --title "PortProton" --width=500 --height=90 \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --borders="$PROGRESS_BAR_BORDERS_SIZE"
    fi

    if [[ "${PIPESTATUS[0]}" != 0 ]] ; then
        if [[ "$no_mirror" != "true" ]] ; then
            print_warning "Failed download $filename from ${FIRST_URL[0]}, trying mirror: ${SECOND_URL[0]}"
            curl -f -# -A 'Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)' -H 'Cache-Control: no-cache, no-store' \
            -H 'Pragma: no-cache' -L ${SECOND_URL[@]} -o "$dest" 2>&1 | \
            tr '\r' '\n' | sed -ur 's|[# ]+||g;s|.*=.*||g;s|.*|#Downloading at &\n&|g' | \
            "$pw_yad" --progress --pulsate --text="${translations[Downloading]} $filename" --auto-close --no-escape \
            --auto-kill --text-align="center" --fixed --no-buttons --title "PortProton" --width=500 --height=90 \
            --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --borders="$PROGRESS_BAR_BORDERS_SIZE"
        fi
        if [[ "${PIPESTATUS[0]}" != 0 ]] ; then
            print_error "Failed to download $filename from mirror. Skipping..."
            return 1
        else
            print_ok "File downloaded successfully: $filename from ${SECOND_URL[0]}"
            if try_check_sha256sum ${SECOND_URL[@]} ; then
                return 0
            else
                try_remove_file "$dest"
                return 1
            fi
        fi
    fi
    print_ok "File downloaded successfully: $filename from ${FIRST_URL[0]}"
    if try_check_sha256sum ${FIRST_URL[@]} ; then
        return 0
    else
        try_remove_file "$dest"
        return 1
    fi
}

var_winedlloverride_update () {
    if [[ "$WINEDLLOVERRIDES" ]]
    then export WINEDLLOVERRIDES="$1;$WINEDLLOVERRIDES"
    else export WINEDLLOVERRIDES="$1"
    fi
    return 0
}

var_vkd3d_config_update () {
    if echo "$VKD3D_CONFIG" | grep "$1"
    then return 0
    elif [[ "$VKD3D_CONFIG" ]]
    then export VKD3D_CONFIG="$1;$VKD3D_CONFIG"
    else export VKD3D_CONFIG="$1"
    fi
    return 0
}

var_radv_perftest_config_update () {
    if echo "$RADV_PERFTEST" | grep "$1"
    then return 0
    elif [[ "$RADV_PERFTEST" ]]
    then export RADV_PERFTEST="$1;$RADV_PERFTEST"
    else export RADV_PERFTEST="$1"
    fi
    return 0
}

var_pw_vk_istance_layers_config_update () {
    if echo "$PW_VK_INSTANCE_LAYERS" | grep "$1"
    then return 0
    elif [[ "$PW_VK_INSTANCE_LAYERS" ]]
    then export PW_VK_INSTANCE_LAYERS="$1:$PW_VK_INSTANCE_LAYERS"
    else export PW_VK_INSTANCE_LAYERS="$1"
    fi
    return 0
}

var_ld_library_path_update () {
    if echo "$LD_LIBRARY_PATH" | grep "$1"
    then return 0
    elif [[ "$LD_LIBRARY_PATH" ]]
    then export LD_LIBRARY_PATH="$1:$LD_LIBRARY_PATH"
    else export LD_LIBRARY_PATH="$1"
    fi
    return 0
}

# GUI NOTIFY SEND
pw_notify_send () {
    if command -v gdbus &>/dev/null ; then
        local app="PortProton"
        local icon=""
        local timeout="5000"
        local title=""
        local body=""

        local OPTIND="1"
        while getopts a:i:t: opt ; do
            case "$opt" in
                a)
                    local app=$OPTARG
                    ;;
                i)
                    case "$OPTARG" in
                        info) local OPTARG="${PORT_WINE_PATH}/data/img/gui/notify_info.svg";;
                        warning) local OPTARG="${PORT_WINE_PATH}/data/img/gui/notify_warning.svg";;
                        error) local OPTARG="${PORT_WINE_PATH}/data/img/gui/notify_error.svg";;
                    esac
                    local icon=$OPTARG
                    ;;
                t)
                    local timeout=$OPTARG
                    ;;
                *)
                    echo "usage: $0
                    [-a] name application (PortProton default)
                    [-i] info, warning, error (none default)
                    [-t] timeout in ms (5000 default)" >&2
                    return 1
                    ;;
            esac
        done
        shift $(( OPTIND - 1 ))
        [[ "$1" == "--" ]] && shift

        local title="$1"
        shift
        local body="$*"

        gdbus call --session --dest org.freedesktop.Notifications \
            --object-path /org/freedesktop/Notifications \
            --method org.freedesktop.Notifications.Notify \
            "$app" 0 "$icon" "$title" "$body" "[]" "{}" "$timeout" &>/dev/null
        return 0
    fi
}
export -f pw_notify_send

check_start_from_steam () {
    if [[ "${START_FROM_STEAM}" == 1 ]]
    then return 0
    else return 1
    fi
}

check_gamescope_session () {
    if [[ -n "$GAMESCOPE_IN_USE" ]]
    then [[ "$GAMESCOPE_IN_USE" == 1 ]] && return 0 || return 1
    fi
    if echo "${DESKTOP_SESSION}" | grep -i "gamescope" &>/dev/null ; then
        export GAMESCOPE_IN_USE=1
        return 0
    else
        export GAMESCOPE_IN_USE=0
        return 1
    fi
}

check_wayland_session () {
    if [[ -n "$WAYLAND_IN_USE" ]]
    then [[ "$WAYLAND_IN_USE" == 1 ]] && return 0 || return 1
    fi
    if echo "${XDG_SESSION_TYPE}" | grep -i "wayland" &>/dev/null ; then
        export WAYLAND_IN_USE=1
        return 0
    else
        export WAYLAND_IN_USE=0
        return 1
    fi
}
export -f check_wayland_session

check_flatpak () {
    if [[ -n "$FLATPAK_IN_USE" ]]
    then [[ "$FLATPAK_IN_USE" == 1 ]] && return 0 || return 1
    fi
    if grep -i "flatpak" /etc/os-release &>/dev/null ; then
        export FLATPAK_IN_USE=1
        if grep -i "Alpine Linux" "/run/host/etc/os-release" &>/dev/null ; then
            export ALPINE_FP=1
        fi
        return 0
    else
        export FLATPAK_IN_USE=0
        return 1
    fi
}
export -f check_flatpak

background_pid () {
    local arg1=$1 # --start или --end
    local arg2=$2 # Название команды
    local arg3=$3 # Номер процесса (1,2,3..)

    if [[ "$START_FROM_STEAM" == 1 ]] \
    || [[ "$PW_GUI_DISABLED_CS" == 1 ]] \
    || [[ -n "$PW_DEBUG" ]] ; then
        case $arg1 in
            --start) eval "$arg2" ;;
            --end) : ;;
        esac
    else
        get_bg_pid () {
            eval "echo \${$1}"
        }
        case $arg1 in
            --start)
                eval "$arg2 &"
                local PID=$!
                export bg_pid"${arg3}"="$PID" ;;
            --end)
                local PID=$(get_bg_pid bg_pid"${arg3}")
                [[ -z $PID ]] && return 1
                wait "$PID" 2>/dev/null && return 0 ;;
        esac
    fi
}
export -f background_pid

unpack () {
    case $1 in
         *.tar.xz) local command="tar -Jxhf";;
         *.tar.gz) local command="tar -xhzf" ;;
        *.tar.zst) local command="tar -I zstd -xhf" ;;
            *.tar) local command="tar -xhf" ;;
    esac

    case $3 in
        silent) local silent=true ;;
    esac

    # If gamescope session is active, use PW_TERM for unpack
    if check_gamescope_session ; then
        $PW_TERM "echo ; echo ; echo \"Unpacking file: $1. Please wait...\" ; $command \"$1\" -C \"$2\""
        [[ "$?" != 0 ]] && return 1 || return 0
    elif [[ "$silent" != "true" ]] ; then
        set -o pipefail
        pw_start_progress_bar_cover_block "${COVERS_PATH}/unpacking_${LANGUAGE_GIF}.gif"
        $command "$1" -C "$2" 2>/dev/null
        pw_stop_progress_bar
        [[ "${PIPESTATUS[0]}" != 0 ]] && print_error "File $1 unpacking error." && return 1 || return 0
    else
        $command "$1" -C "$2" && return 0 || return 1
    fi
}

debug_timer () {
    if [[ "$1" == "--start" ]] ; then
        START=$(date +%s%N)
        if [[ "$2" == "-s" ]] ; then
            case $3 in
                PW_TIME_IN_GAME)
                    START_PW_TIME_IN_GAME=$START ;;
                UPDATE_ETERFUND)
                    START_UPDATE_ETERFUND=$START ;;
                UPDATE_GITHUB)
                    START_UPDATE_GITHUB=$START ;;
                UPDATE_PP_GITEA)
                    START_UPDATE_PP_GITEA=$START ;;
            esac
        fi
    elif [[ "$1" == "--end" ]] ; then
        END=$(date +%s%N)
        if [[ -n "$2" ]] ; then
            if [[ "$2" == "-s" ]] ; then
                case $3 in
                    PW_TIME_IN_GAME)
                        START=$START_PW_TIME_IN_GAME ;;
                    UPDATE_ETERFUND)
                        START=$START_UPDATE_ETERFUND ;;
                    UPDATE_GITHUB)
                        START=$START_UPDATE_GITHUB ;;
                    UPDATE_PP_GITEA)
                        START=$START_UPDATE_PP_GITEA ;;
                esac
                export "$3"="$((( END - START )/1000000 ))"
            else
                DIFF=$((( END - START )/1000000 ))
                print_warning "It took $DIFF milliseconds for $2"
            fi
        else
            DIFF=$((( END - START )/1000000 ))
            print_warning "It took $DIFF milliseconds"
        fi
    fi
}

# Поиск нужного .desktop файла по $portwine_exe (для показа в комментариях нужного времени)
# Параллельное создание базы по времени после завершения приложения
search_desktop_file () {
    local desktop_file desktop_file_new EXEC_DESKTOP line1 line2 TIME_TOTAL
    for desktop_file in "$PORT_WINE_PATH"/* ; do
        desktop_file_new="${desktop_file//"$PORT_WINE_PATH/"/}"
        if [[ $desktop_file_new =~ .desktop$ ]] ; then
            if [[ ! $desktop_file_new =~ (PortProton|readme) ]] ; then
                while IFS= read -r line1 ; do
                    if [[ $line1 =~ ^Exec= ]] ; then
                        if check_flatpak ; then
                            EXEC_DESKTOP=${line1//Exec=flatpak run ru.linux_gaming.PortProton /}
                        else
                            EXEC_DESKTOP=${line1//Exec=env \"$PORT_SCRIPTS_PATH\/start.sh\" /}
                        fi
                    fi
                done < "$desktop_file"
                while IFS=" " read -r -a line2 ; do
                    if [[ ${line2[1]} == "$ENTRY_POINT" ]] ; then
                        break
                    fi
                done < "$PORT_WINE_TMP_PATH/statistics"
                if [[ $portwine_exe == "${EXEC_DESKTOP//\"/}" ]] ; then
                    DESKTOP_CORRECT_FILE="$desktop_file"
                fi
            fi
        fi
    done
    IFS="$orig_IFS"
    if [[ -n ${line2[2]} ]]
    then TIME_CURRENT=${line2[2]}
    else TIME_CURRENT=0
    fi
    export TIME_CURRENT
    # Проверка новых десктоп файлов, чтобы их можно было сортировать первыми при первом создании в главном меню
    if [[ $PW_NEW_DESKTOP == 1 ]] && [[ ${line2[3]} != NEW_DESKTOP ]] ; then
        if [[ -n ${line2[1]} ]] ; then
            sed -i "s|$ENTRY_POINT $TIME_CURRENT OLD_DESKTOP|$ENTRY_POINT $TIME_CURRENT NEW_DESKTOP|" "$PORT_WINE_TMP_PATH/statistics"
        else
            echo "${portwine_exe// /#@_@#} $ENTRY_POINT $TIME_CURRENT NEW_DESKTOP" >> "$PORT_WINE_TMP_PATH/statistics"
        fi
    fi
    unset PW_NEW_DESKTOP
    # Когда приложение было запущено и завершено
    if [[ -n $PW_TIME_IN_GAME ]] ; then
        TIME_TOTAL=$(( TIME_CURRENT + PW_TIME_IN_GAME ))
        if [[ -n ${line2[1]} ]] ; then
            # Когда есть предыдущее время
            sed -i "s|$ENTRY_POINT $TIME_CURRENT|$ENTRY_POINT $TIME_TOTAL|" "$PORT_WINE_TMP_PATH/statistics"
        else
            # Когда только запустили приложение первый раз
            echo "${portwine_exe// /#@_@#} $ENTRY_POINT $TIME_TOTAL OLD_DESKTOP" >> "$PORT_WINE_TMP_PATH/statistics"
        fi
        # Здесь добавляются новые линии для статистики по аналогии, к примеру ${line2[4]}
        # L4 важен, чтобы не было путаницы из-за sed, то что используется \(.*\), для ${line2[5]} это будет L5 и т.д.
        if [[ -z ${line2[4]} ]] ; then
            line2[4]=1
            sed -i "s|$ENTRY_POINT \(.*\)|$ENTRY_POINT \1 L4-${line2[4]}|" "$PORT_WINE_TMP_PATH/statistics"
        else
            line2[4]=${line2[4]//L4-/}
            NUMBER_OF_STARTS=$(( line2[4] + 1 ))
            sed -i "s|$ENTRY_POINT \(.*\) L4-${line2[4]}|$ENTRY_POINT \1 L4-$NUMBER_OF_STARTS|" "$PORT_WINE_TMP_PATH/statistics"
        fi
    fi
    # Ремонтирует путь на новый, если вдруг путь до .exe файла битый или изменился, но .exe файл он опознал
    if [[ -n ${line2[1]} ]] && [[ ${line2[0]} != "${portwine_exe// /#@_@#}" ]] ; then
        [[ -z $TIME_TOTAL ]] && TIME_TOTAL=$TIME_CURRENT
        sed -i "s|${line2[0]} $ENTRY_POINT $TIME_CURRENT|${portwine_exe// /#@_@#} $ENTRY_POINT $TIME_TOTAL|" "$PORT_WINE_TMP_PATH/statistics"
    fi
}

create_name_desktop () {
    search_desktop_file
    if [[ -n $DESKTOP_NAME_FILE ]] ; then
        DESKTOP_NAME_FILE_OLD=$DESKTOP_NAME_FILE
        unset DESKTOP_NAME_FILE
    fi
    if [[ -n $DESKTOP_NAME_YAD ]] ; then
        DESKTOP_NAME_FILE="${DESKTOP_NAME_YAD//.desktop/}"
        unset DESKTOP_NAME_YAD
    elif [[ -n $name_desktop ]] ; then
        DESKTOP_NAME_FILE="$name_desktop"
        unset name_desktop
    elif [[ -n $DESKTOP_CORRECT_FILE ]] ; then
        DESKTOP_NAME_FILE="${DESKTOP_CORRECT_FILE//"$PORT_WINE_PATH/"/}"
        unset DESKTOP_CORRECT_FILE
        DESKTOP_NAME_FILE="${DESKTOP_NAME_FILE//.desktop/}"
    fi

    if [[ -z $PORTWINE_DB ]] ; then
        PORTWINE_DB_DESKTOP="$(basename "${portwine_exe%.[Ee][Xx][Ee]}")"
    else
        PORTWINE_DB_DESKTOP="$PORTWINE_DB"
    fi
    if [[ -n $PORTPROTON_NAME ]] ; then
        PORTPROTON_NAME_ABBR=$(make_abbreviation "$PORTPROTON_NAME")
        PORTPROTON_NAME_ACRO=$(make_acronym "$PORTPROTON_NAME")
    fi
    if [[ -n $FILE_DESCRIPTION ]] ; then
        FILE_DESCRIPTION_ABBR=$(make_abbreviation "$FILE_DESCRIPTION")
        FILE_DESCRIPTION_ACRO=$(make_acronym "$FILE_DESCRIPTION")
    fi

    if [[ -n $DESKTOP_NAME_FILE ]] ; then
        PW_NAME_DESKTOP_PROXY="$DESKTOP_NAME_FILE"
    elif [[ -n $DESKTOP_NAME_FILE_OLD && ${PORTWINE_DB_DESKTOP^^} =~ ${DESKTOP_NAME_FILE_OLD^^} ]] ; then
        PW_NAME_DESKTOP_PROXY="$DESKTOP_NAME_FILE_OLD"
    elif [[ -n $PORTPROTON_NAME && ${PORTPROTON_NAME^^} =~ ${PORTWINE_DB_DESKTOP^^} && $PORTPROTON_NAME != "$PORTWINE_DB_DESKTOP" ]] \
    || [[ -n $PORTPROTON_NAME && ${#PORTPROTON_NAME_ABBR} -gt 2 && ${PORTWINE_DB_DESKTOP^^} =~ $PORTPROTON_NAME_ABBR ]] \
    || [[ -n $PORTPROTON_NAME && ${#PORTPROTON_NAME_ACRO} -gt 2 && ${PORTWINE_DB_DESKTOP^^} =~ ${PORTPROTON_NAME_ACRO^^} ]]
    then
        PW_NAME_DESKTOP_PROXY="$PORTPROTON_NAME"
    elif [[ -n $FILE_DESCRIPTION && ${FILE_DESCRIPTION^^} =~ ${PORTWINE_DB_DESKTOP^^} && $FILE_DESCRIPTION != "$PORTWINE_DB_DESKTOP" ]] \
    || [[ -n $FILE_DESCRIPTION && ${#FILE_DESCRIPTION_ABBR} -gt 2 && ${PORTWINE_DB_DESKTOP^^} =~ $FILE_DESCRIPTION_ABBR ]] \
    || [[ -n $FILE_DESCRIPTION && ${#FILE_DESCRIPTION_ACRO} -gt 2 && ${PORTWINE_DB_DESKTOP^^} =~ ${FILE_DESCRIPTION_ACRO^^} ]]
    then
        PW_NAME_DESKTOP_PROXY="$FILE_DESCRIPTION"
    else
        unset PORTWINE_DB_PROXY PORTWINE_DB_NEW
        PORTWINE_DB_DESKTOP="${PORTWINE_DB_DESKTOP//_/ }"
        if [[ ${PORTWINE_DB_DESKTOP:0:1} =~ [a-z] ]] ; then
            PORTWINE_DB_UPPER="${PORTWINE_DB_DESKTOP^^}"
            PORTWINE_DB_DESKTOP="${PORTWINE_DB_UPPER:0:1}${PORTWINE_DB_DESKTOP:1}"
        fi
        if (( ${#PORTWINE_DB_DESKTOP} > 3 )) ; then
            for ((i=0 ; i<${#PORTWINE_DB_DESKTOP} ; i++)) ; do
                if [[ ${PORTWINE_DB_DESKTOP:i:2} =~ ([a-z][A-Z]|[a-z][0-9]) ]] \
                && [[ ! ${PORTWINE_DB_DESKTOP:i:3} =~ ([a-z][A-Z]" "|[a-z][0-9]" ") ]] ; then
                    PORTWINE_DB_PROXY+="${PORTWINE_DB_DESKTOP:i:1} "
                elif [[ ${PORTWINE_DB_DESKTOP:i:3} =~ [0-9][0-9][a-zA-Z] ]] ; then
                    PORTWINE_DB_PROXY+="${PORTWINE_DB_DESKTOP:i:2} "
                    ((i++))
                else
                    PORTWINE_DB_PROXY+="${PORTWINE_DB_DESKTOP:i:1}"
                fi
            done
            for ((i=0 ; i<${#PORTWINE_DB_PROXY} ; i++)) ; do
                if [[ ${PORTWINE_DB_PROXY:i:2} =~ " "[a-z] ]] ; then
                    PORTWINE_DB_UPPER="${PORTWINE_DB_PROXY:i:2}"
                    PORTWINE_DB_NEW+="${PORTWINE_DB_UPPER^^}"
                    ((i++))
                else
                    PORTWINE_DB_NEW+="${PORTWINE_DB_PROXY:i:1}"
                fi
            done
        else
            PORTWINE_DB_NEW="$PORTWINE_DB_DESKTOP"
        fi
        PW_NAME_DESKTOP_PROXY="$PORTWINE_DB_NEW"
    fi
}

# Конвертация секунд в дни, часы, минуты
seconds_to_time () {
    [[ ! $DESKTOP_WITH_TIME == enabled ]] && return 0
    [[ -z $1 ]] && return 0
    local seconds days hours minutes
    seconds=$1

    days=$((seconds / (60 * 60 * 24)))
    seconds=$((seconds % (60 * 60 * 24)))

    hours=$((seconds / (60 * 60)))
    seconds=$((seconds % (60 * 60)))

    minutes=$((seconds / 60))
    seconds=$((seconds % 60))

    if [[ $days =~ ^0$ ]] ; then
        days=
    elif [[ $days =~ ^1$ ]] ; then
        days="$days ${translations[day]}, "
    elif [[ $days =~ ^([2-9]1|[1-9][0-9]+1)$ ]] && [[ $LANGUAGE == ru ]] ; then
        days="$days ${translations[day]}, "
    elif [[ $days =~ ^([2-4]|[2-9][2-4]|[1-9][0-9]+[2-4])$ ]] && [[ $LANGUAGE == ru ]] ; then
        days="$days дня, "
    else
        days="$days ${translations[days]}, "
    fi

    if [[ $hours =~ ^0$ ]] ; then
        hours=
    elif [[ $hours =~ ^1$ ]] ; then
        hours="$hours ${translations[hour]} ${translations[and]} "
    elif [[ $hours =~ ^([2-4]|2[2-4])$ ]] && [[ $LANGUAGE == ru ]] ; then
        hours="$hours часа ${translations[and]} "
    elif [[ $hours =~ ^21$ ]] && [[ $LANGUAGE == ru ]] ; then
        hours="$hours ${translations[hour]} ${translations[and]} "
    else
        hours="$hours ${translations[hours]} ${translations[and]} "
    fi

    if [[ $minutes =~ ^0$ ]] ; then
        hours=${hours//" ${translations[and]} "/}
        minutes=
        if [[ -z $days ]] || [[ -z $hours ]] ; then
            days=${days//","/}
        fi
        if [[ -z $days ]] && [[ -z $hours ]] ; then
            minutes="${translations[less than a minute]}"
        fi
    elif [[ $minutes =~ ^1$ ]] ; then
        minutes="$minutes ${translations[minute]}"
    elif [[ $minutes =~ ^[2-5]1$ ]] && [[ $LANGUAGE == ru ]] ; then
        minutes="$minutes ${translations[minute]}"
    elif [[ $minutes =~ ^([2-4]|[2-5][2-4])$ ]] && [[ $LANGUAGE == ru ]] ; then
        minutes="$minutes минуты"
    else
        minutes="$minutes ${translations[minutes]}"
    fi

    echo -e "<b>\n${translations[Time spent]}: $days$hours$minutes</b>"
}

combobox_fix () {
    if [[ -z "$1" ]] ; then
        print_error "no argument specified for combobox_fix"
        return 1
    else
        local name1 name2
        if [[ "$1" == "--disabled" ]] ; then
            if [[ -z "$3" ]] ; then
                echo "${translations[Disabled]}"
                return 0
            fi
            name1="$2"
            name2="$3"
        elif [[ "$1" == "--empty" ]] ; then
            if [[ -z "$3" ]] ; then
                echo ""
                return 0
            fi
            name1="$2"
            name2="$3"
        else
            name1="$1"
            if [[ -z "$2" ]] ; then
                echo "${name1}"
                return 0
            fi
            name2="$2"
        fi
        local name3 name4
        name3="${name2//\!${name1}\!/\!}"
        name3="!${name3//${name1}\!/\!}"
        name3="${name3//\!\!/\!}"
        name4="${name3//*\!/}"
        if [[ ${name1} == "${name4}" ]] || [[ ${name1} == "\\${name4}" ]]
        then name3="${name3%\!"${name1}"}"
        fi
        if [[ "$1" == "--disabled" ]] ; then
            if [[ ${name1} == "disabled" ]] ; then
                name1="${translations[Disabled]}"
                if [[ ${name3} =~ enabled ]] ; then
                    name3="${name3//enabled/${translations[Enable]}}"
                fi
            elif [[ ${name1} != "disabled" ]] ; then
                fix_disabled="!${translations[Disable]}"
                if [[ ${name1} == "enabled" ]] ; then
                    name1="${translations[Enabled]}"
                fi
            fi
            echo "${name1}${name3}${fix_disabled}"
        elif [[ "$1" == "--empty" ]] ; then
            if [[ ${name1} != "" ]] ; then
                if [[ ${name1} == "\\" ]]
                then fix_empty=""
                else fix_empty="!"
                fi
            fi
            echo "${name1}${name3}${fix_empty}"
        else
            echo "${name1}${name3}"
        fi
        return 0
    fi
}

restart_pp () {
    case "$1" in
        --userconf) export RESTART_PP_USED="userconf" ;;
        --edit_db) export RESTART_PP_USED="edit_db" ;;
    esac
    /usr/bin/env bash -c ${pw_full_command_line[@]} &
    exit 0
}

pw_clear_pfx () {
    rm -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/.dot*
    rm -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/.prog*
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.wine_ver"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/userdef.reg"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.update-timestamp"
    try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/.windows-serial"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/windows/"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/ProgramData/Setup"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/ProgramData/Windows"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/ProgramData/WindowsTask"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/ProgramData/Package Cache"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Local Settings/Application Data/Microsoft"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Local Settings/Application Data/Temp"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Local Settings/Temporary Internet Files"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Application Data/Microsoft"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Application Data/wine_gecko"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/Public/Temp"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Local Settings/Application Data/Microsoft"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Local Settings/Application Data/Temp"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Local Settings/Temporary Internet Files"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Application Data/Microsoft"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Application Data/wine_gecko"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/users/steamuser/Temp"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files/Internet Explorer"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files/Windows Media Player"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files/Windows NT"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files (x86)/Internet Explorer"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files (x86)/Windows Media Player"
    try_remove_dir "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/Program Files (x86)/Windows NT"
    rm -f "${PORT_WINE_TMP_PATH}"/*.bin
    rm -f "${PORT_WINE_TMP_PATH}"/*.foz
    return 0
}

pw_reinstall_pp () {
    if [[ "${PW_REINSTALL_FROM_TERMINAL}" == 1 ]] ; then
        read -p "Do you want to reinstall PortProton? (Y,y - Yes):   " -n 1 -r
        if [[ ! $REPLY =~ ^[Yy]$ ]]
        then
            echo ""
            exit 1
        fi
    elif yad_question "${translations[Do you really want to reinstall PortProton?\\nFor this, an internet connection will be required.]}" ; then
        pw_clear_pfx
        try_remove_dir "${PORT_WINE_PATH}/data/dist"
        create_new_dir "${PORT_WINE_PATH}/data/dist"
        try_remove_dir "${PORT_WINE_TMP_PATH}/VULKAN"
        try_remove_file "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
        try_remove_file "${PORT_WINE_PATH}/data/user.conf"
        try_remove_file "${PORT_WINE_TMP_PATH}/scripts_ver"
        echo ""
        unset SKIP_CHECK_UPDATES
        print_info "Restarting PP for reinstall files..."
    fi
    restart_pp
}

check_user_conf () {
    if [[ ! -f "${USER_CONF}" ]] ; then
        cat << EOF > "${USER_CONF}"
#!/usr/bin/env bash"
# User overides db and var settings..."
# export DXVK_HUD=full"
# export GALLIUM_HUD=fps"
EOF
    fi
}

init_wine_ver () {
    if [[ "${PW_WINE_VER}" == "${translations[USE_SYSTEM_WINE]}" ]]
    then export PW_WINE_USE="USE_SYSTEM_WINE"
    elif [[ "${PW_WINE_VER}" == "${translations[GET-OTHER-WINE]}" ]]
    then gui_proton_downloader
    elif [[ -n "${PW_WINE_VER}" ]]
    then export PW_WINE_USE="$PW_WINE_VER"
    fi
    unset PW_WINE_VER

    if [[ "${PW_WINE_USE}" == "USE_SYSTEM_WINE" ]] \
    && command -v wine &>/dev/null ; then
        export WINEDIR="$RT_PREFIX/usr"
        WINE="$RT_PREFIX$(command -v wine)"
        export WINE
        export WINELOADER="$WINE"
        WINESERVER="$RT_PREFIX$(command -v wineserver)"
        export WINESERVER
        export PW_NO_FSYNC=1
        unset WINEDLLPATH
    else
        if [[ -d "${PORT_WINE_PATH}/data/dist" ]] ; then
        IFS=$'\n'
        for dist_dir in $(ls -1 "${PORT_WINE_PATH}/data/dist/") ; do
            dist_dir_new=$(echo "${dist_dir}" | awk '$1=$1' | sed -e s/[[:blank:]]/_/g)
            if [[ ! -d "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}" ]] ; then
                mv -- "${PORT_WINE_PATH}/data/dist/$dist_dir" "${PORT_WINE_PATH}/data/dist/${dist_dir_new^^}"
            fi
        done
        IFS="$orig_IFS"
        fi
        if [[ -z $(ls "${PORT_WINE_PATH}/data/dist/" | grep "${PW_WINE_USE}") ]] ; then
            if [[ "$PW_WINE_USE" =~ PROTON_LG* ]]
            then export PW_WINE_USE=PROTON_LG
            else export PW_WINE_USE=WINE_LG
            fi
        fi
        if [[ "$PW_WINE_USE" == PROTON_LG ]]
        then export PW_WINE_USE="${PW_PROTON_LG_VER}"
        elif [[ "$PW_WINE_USE" == WINE_LG ]]
        then export PW_WINE_USE="${PW_WINE_LG_VER}"
        fi

        export WINEDIR="${PORT_WINE_PATH}/data/dist/${PW_WINE_USE}"
        export WINE="${WINEDIR}/bin/wine"
        export WINELOADER="${WINEDIR}/bin/wine"
        export WINESERVER="${WINEDIR}/bin/wineserver"
        if [[ -d "${WINEDIR}/files" && ! -d "${WINEDIR}/dist" ]] ; then
            for clear_dist_files in $(ls "${WINEDIR}" | sed -e "s/^files$//g" | sed -e "s/^version$//g") ; do
                rm -fr "${WINEDIR}/$clear_dist_files"
            done
            mv -f "${WINEDIR}/files"/* "${WINEDIR}/"
            rm -fr "${WINEDIR}/files"
        elif [[ ! -d "${WINEDIR}/files" && -d "${WINEDIR}/dist" ]] ; then
            for clear_dist_files in $(ls "${WINEDIR}" | sed -e "s/^dist$//g" | sed -e "s/^version$//g") ; do
                rm -fr "${WINEDIR}/$clear_dist_files"
            done
            mv -f "${WINEDIR}/dist"/* "${WINEDIR}/"
            rm -fr "${WINEDIR}/dist"
        elif [[ -f "${WINEDIR}/proton_dist.tar" ]] ; then
            unpack "${WINEDIR}/proton_dist.tar" "${WINEDIR}/"
            for clear_dist_files in $(ls "${WINEDIR}" | sed -e "s/^bin$//g" | sed -e "s/^lib$//g" | sed -e "s/^lib64$//g" | sed -e "s/^share$//g" | sed -e "s/^version$//g") ; do
                rm -fr "${WINEDIR}/$clear_dist_files"
            done
        fi
        if [[ -d "${WINEDIR}" ]] ; then
            [[ ! -f "${WINEDIR}/version" ]] && echo "${PW_WINE_USE}" > "${WINEDIR}/version"

            if [[ ! -d "${WINEDIR}/lib64/" ]] && [[ -d "${WINEDIR}/lib/wine/x86_64-unix" ]] ; then
                create_new_dir "${WINEDIR}/lib64/wine"
                mv -f "${WINEDIR}/lib/wine/x86_64-unix" "${WINEDIR}/lib64/wine/"
                mv -f "${WINEDIR}/lib/wine/x86_64-windows" "${WINEDIR}/lib64/wine/"
            fi

            for mono_gecko_chk in "mono" "gecko" ; do
                if check_symlink "${WINEDIR}/share/wine/${mono_gecko_chk}" ; then
                    print_info "${WINEDIR}/share/wine/${mono_gecko_chk} is symlink. OK."
                elif [[ -d "${WINEDIR}/share/wine/${mono_gecko_chk}" ]] ; then
                    pw_start_progress_bar_cover_block "${COVERS_PATH}/loading_${LANGUAGE_GIF}.gif"
                    try_copy_dir "${WINEDIR}/share/wine/${mono_gecko_chk}" "${PORT_WINE_TMP_PATH}"
                    try_remove_dir "${WINEDIR}/share/wine/${mono_gecko_chk}"
                    try_force_link_dir "${PORT_WINE_TMP_PATH}/${mono_gecko_chk}" "${WINEDIR}"/share/wine/
                    print_info "Copy ${WINEDIR}/share/wine/${mono_gecko_chk} to tmp and create symlink to ${WINEDIR}/share/wine/. OK."
                    pw_stop_progress_bar
                else
                    try_remove_dir "${WINEDIR}/share/wine/${mono_gecko_chk}"
                    try_force_link_dir "${PORT_WINE_TMP_PATH}/${mono_gecko_chk}" "${WINEDIR}"/share/wine
                    print_warning "${WINEDIR}/share/wine/${mono_gecko_chk} is broken symlink. Repair... OK."
                fi
            done

            if ! grep 'Global,"{41FCC608-8496-4DEF-B43E-7D9BD675A6FF}",0x10001,0x00000001' "${WINEDIR}/share/wine/wine.inf" &>/dev/null ; then
                echo 'HKLM,Software\NVIDIA Corporation\Global,"{41FCC608-8496-4DEF-B43E-7D9BD675A6FF}",0x10001,0x00000001' >> "${WINEDIR}/share/wine/wine.inf"
                echo 'HKLM,System\ControlSet001\Services\nvlddmkm,"{41FCC608-8496-4DEF-B43E-7D9BD675A6FF}",0x10001,0x00000001' >> "${WINEDIR}/share/wine/wine.inf"
                sed -i '/Steam.exe/d' "${WINEDIR}/share/wine/wine.inf"
                sed -i '/\\Valve\\Steam/d' "${WINEDIR}/share/wine/wine.inf"
                sed -i '/winemenubuilder/d' "${WINEDIR}/share/wine/wine.inf"
                rm -f "${WINEDIR}"/lib*/*steam* &>/dev/null
                rm -f "${WINEDIR}"/lib*/wine/*/*steam* &>/dev/null
                rm -f "${WINEDIR}"/lib*/wine/*-windows/winemenubuilder.exe &>/dev/null
            fi
        fi

        export WINEDLLPATH="${WINEDIR}/lib64/wine:${WINEDIR}/lib/wine"
        if [[ -d "${PATH_TO_GAME}" ]] ; then
            export WINEDLLPATH+=":${PATH_TO_GAME}"
        fi
    fi

    export WINE_LIBRARY_PATH="${WINEDIR}/lib64:${WINEDIR}/lib"
    export MEDIACONV_BLANK_VIDEO_FILE="${WINEDIR}"/share/media/blank.mkv
    export MEDIACONV_BLANK_AUDIO_FILE="${WINEDIR}"/share/media/blank.ptna
    return 0
}

pw_init_runtime () {
    check_flatpak && export PW_USE_RUNTIME="0"
    if [[ "$PW_USE_RUNTIME" != "1" ]] \
    || [[ "$PW_WINE_USE" == "USE_SYSTEM_WINE" ]]
    then
        export PW_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PW_PLUGINS_PATH}/portable/lib/lib64:${PW_PLUGINS_PATH}/portable/lib/lib32"
        export PW_VK_LAYER_PATH="${PW_PLUGINS_PATH}/portable/share/vulkan/implicit_layer.d"
        if [[ -z "$PW_TERM" ]] ; then
            export PW_TERM="env LD_LIBRARY_PATH=\"${PW_LD_LIBRARY_PATH}\" ${PW_PLUGINS_PATH}/portable/bin/xterm -bg black -fg white -e"
        fi
        export pw_runtime="env"
        return 0
    fi

    if grep -i "altlinux" "/etc/os-release" &>/dev/null ; then
        export LIBGL_DRIVERS_PATH="/usr/lib/X11/modules/dri:/usr/lib64/X11/modules/dri"
        if [[ -f "/usr/share/vulkan/icd.d/nvidia_icd.json" ]] ; then
            VK_ADD_DRIVER_FILES="$(realpath /usr/share/vulkan/icd.d/nvidia_icd.json)"
            export VK_ADD_DRIVER_FILES
        fi
    elif grep -i -E '(ROSA|RED OS)' "/etc/os-release" &>/dev/null ; then
        export LOCPATH="/run/host/usr/share/locale/"
    fi

    PW_PV_OVERRIDES="/usr/lib/pressure-vessel/overrides/lib"

    export PW_LD_LIBRARY_PATH="\
${PW_PLUGINS_PATH}/portable/lib/lib64:\
${PW_PLUGINS_PATH}/portable/lib/lib32:\
${PW_PV_OVERRIDES}/x86_64-linux-gnu/aliases:\
${PW_PV_OVERRIDES}/i386-linux-gnu/aliases:\
/overrides/lib/x86_64-linux-gnu:\
/overrides/lib/i386-linux-gnu:\
/lib/x86_64-linux-gnu:\
/lib/i386-linux-gnu"

    if [[ -n "${PATH}" ]]
    then export PW_PATH="${PATH}:${PW_PLUGINS_PATH}/portable/bin"
    else export PW_PATH="${PW_PLUGINS_PATH}/portable/bin"
    fi

    if [[ -n "${PW_SANDBOX_HOME_PATH}" && -d "${PW_SANDBOX_HOME_PATH}" ]] ; then
        export pw_runtime="${PW_WINELIB}/pressure-vessel/bin/pressure-vessel-unruntime \
        --unshare-home \
        --home=${PW_SANDBOX_HOME_PATH} \
        --remove-game-overlay \
        --share-pid \
        ${PW_ADD_TO_ARGS_IN_RUNTIME} -- \
        env PATH=$PW_PATH "
    else
        export pw_runtime="${PW_WINELIB}/pressure-vessel/bin/pressure-vessel-unruntime \
        --share-home \
        --remove-game-overlay \
        --share-pid \
        ${PW_ADD_TO_ARGS_IN_RUNTIME} -- \
        env PATH=$PW_PATH "
    fi

    if [[ "$PW_USE_SYSTEM_VK_LAYERS" == "1" ]] ; then
        export PRESSURE_VESSEL_IMPORT_VULKAN_LAYERS=1
        unset PW_VK_LAYER_PATH
    else
        export PRESSURE_VESSEL_IMPORT_VULKAN_LAYERS=0
        export PW_VK_LAYER_PATH="${PW_PLUGINS_PATH}/portable/share/vulkan/implicit_layer.d"
    fi

    # export PRESSURE_VESSEL_GRAPHICS_PROVIDER="/"

    unset PRESSURE_VESSEL_RUNTIME_ARCHIVE
    export PRESSURE_VESSEL_COPY_RUNTIME=1
    export PRESSURE_VESSEL_GC_LEGACY_RUNTIMES=1
    export PRESSURE_VESSEL_RUNTIME=runtime
    export PRESSURE_VESSEL_RUNTIME_BASE="${PW_WINELIB}"
    export PRESSURE_VESSEL_VARIABLE_DIR="${PW_WINELIB}/var"
    export PRESSURE_VESSEL_PREFIX="${PW_WINELIB}/pressure-vessel"
    export FONTCONFIG_PATH=''

    unset PRESSURE_VESSEL_FILESYSTEMS_RO PRESSURE_VESSEL_FILESYSTEMS_RW
    for PWRTMRO in ${PW_RT_MOUNT_RO[*]} ; do
        if [[ -n "${PRESSURE_VESSEL_FILESYSTEMS_RO}" ]]
        then export PRESSURE_VESSEL_FILESYSTEMS_RO="${PRESSURE_VESSEL_FILESYSTEMS_RO}:${PWRTMRO}"
        else export PRESSURE_VESSEL_FILESYSTEMS_RO="${PWRTMRO}"
        fi
    done
    for PWRTMRW in ${PW_RT_MOUNT_RW[*]} ; do
        if [[ -n "${PRESSURE_VESSEL_FILESYSTEMS_RW}" ]]
        then export PRESSURE_VESSEL_FILESYSTEMS_RW="${PRESSURE_VESSEL_FILESYSTEMS_RW}:${PWRTMRW}"
        else export PRESSURE_VESSEL_FILESYSTEMS_RW="${PWRTMRW}"
        fi
    done

    export PW_TERM="env LD_LIBRARY_PATH=\"${PW_LD_LIBRARY_PATH}\" ${PW_PLUGINS_PATH}/portable/bin/xterm -bg black -fg white -e"

    print_info "RUNTIME is enabled"
}

pw_mangohud_check () {
    if [[ "${PW_MANGOHUD}" == "1" ]] \
    && ! check_gamescope_session
    then
        if [[ "$PW_USE_SYSTEM_VK_LAYERS" != "1" ]] ; then
            sed -i 's/: "VK_LAYER/: "PW_VK_LAYER/' "${PW_PLUGINS_PATH}/portable/share/vulkan/implicit_layer.d"/MangoHud*.json
            var_pw_vk_istance_layers_config_update "PW_VK_LAYER_MANGOHUD_overlay64:PW_VK_LAYER_MANGOHUD_overlay32"
            print_info "Portable MangoHud is enabled"
        else
            print_info "System MangoHud is enabled"
            export PW_MANGOHUD_SLR='MANGOHUD=1'
        fi
        MANGOHUD_LIB_NAME="libMangoHud.so"
        if [[ "${PW_VULKAN_USE}" = "0" ]] ; then
            MANGOHUD_LIB_NAME="libMangoHud_dlsym.so:libMangoHud_opengl.so:${MANGOHUD_LIB_NAME}"
        fi
        if [[ -n "${PW_LD_PRELOAD}" ]]
        then export PW_LD_PRELOAD="${PW_LD_PRELOAD}:${MANGOHUD_LIB_NAME}"
        else export PW_LD_PRELOAD="${MANGOHUD_LIB_NAME}"
        fi
    else
        export PW_MANGOHUD_SLR=''
        print_info "MangoHud is disabled"
    fi
    return 0
}

pw_vkbasalt_check () {
    if [[ "${PW_VKBASALT}" == "1" ]] ; then
        if [[ "$PW_USE_SYSTEM_VK_LAYERS" != "1" ]] ; then
            sed -i 's/: "VK_LAYER/: "PW_VK_LAYER/' "${PW_PLUGINS_PATH}/portable/share/vulkan/implicit_layer.d"/vkBasalt*.json
            var_pw_vk_istance_layers_config_update "PW_VK_LAYER_VKBASALT_post_processing64:PW_VK_LAYER_VKBASALT_post_processing32"
            print_info "Portable vkBasalt is enabled"
        else
            print_info "System vkBasalt is enabled"
            export ENABLE_VKBASALT="1"
        fi
        export VKBASALT_CONFIG_FILE="${PORT_WINE_PATH}/data/vkBasalt.conf"
        if ! grep "${PW_PLUGINS_PATH}/reshade" "${VKBASALT_CONFIG_FILE}" &>/dev/null
        then sed -ri "s|= .*/reshade|= \"${PW_PLUGINS_PATH}\"/reshade|g" "${VKBASALT_CONFIG_FILE}"
        fi
        if [[ -n "${PW_VKBASALT_EFFECTS}" ]] && [[ -n "${PW_VKBASALT_FFX_CAS}" ]] ; then
            sed -ri "s/effects = .*/effects = ${PW_VKBASALT_EFFECTS}/g" "${VKBASALT_CONFIG_FILE}"
            sed -ri "s/casSharpness .*/casSharpness = ${PW_VKBASALT_FFX_CAS}/g" "${VKBASALT_CONFIG_FILE}"
        fi
    else
        export DISABLE_VKBASALT="1"
        print_info "vkBasalt is disabled"
    fi
    return 0
}

regdlloverrides () {
    PW_DLL_EXE=$(echo $@ | awk -F: '{print $1}')
    PW_DLL_LIB=$(echo $@ | awk -F: '{print $2}' | awk -F= '{print $1}')
    PW_DLL_SET=$(echo $@ | awk -F= '{print $NF}')
    case "${PW_DLL_SET}" in
        "n,b") PW_DLL_IN_REG="native,builtin" ;;
        "b,n") PW_DLL_IN_REG="builtin,native" ;;
          "n") PW_DLL_IN_REG="native" ;;
          "b") PW_DLL_IN_REG="builtin" ;;
            *) PW_DLL_IN_REG="" ;;
    esac
    grep 'HKCU,Software\\Wine\\AppDefaults\\'"${PW_DLL_EXE}"'\\DllOverrides,'\"${PW_DLL_LIB}\",0x2,\"${PW_DLL_IN_REG}\" "${WINEDIR}/share/wine/wine.inf"
    if [[ "$?" != "0" ]] ; then
        grep "ProtonOverrides" "${WINEDIR}/share/wine/wine.inf"
        if [[ "$?" == "0" ]] ; then
            sed -i "/\[ProtonOverrides\]/a HKCU,Software\\\Wine\\\AppDefaults\\\\${PW_DLL_EXE}\\\DllOverrides,\"${PW_DLL_LIB}\",0x2,\"${PW_DLL_IN_REG}\"" "${WINEDIR}/share/wine/wine.inf"
        else
            sed -i "/\[SteamClient.ntamd64\]/a HKCU,Software\\\Wine\\\AppDefaults\\\\${PW_DLL_EXE}\\\DllOverrides,\"${PW_DLL_LIB}\",0x2,\"${PW_DLL_IN_REG}\"" "${WINEDIR}/share/wine/wine.inf"
        fi
    fi
}

wait_wineserver () {
    while ls -l /proc/*/exe >/dev/null 2>&1 | grep -ie PortProton | grep -E 'wine(64)?-preloader|wineserver'
    do
        sleep 1
    done
    "$WINESERVER" -w
    return 0
}
export -f wait_wineserver

kill_portwine () {
    if [[ "${PW_WINE_USE}" != "USE_SYSTEM_WINE" ]] ; then
        check_flatpak
        if [[ "$ALPINE_FP" == "1" ]] ; then
            wine_pids=$(ls -l /proc/*/exe >/dev/null 2>&1 | grep -ie PortProton | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')
            bwrap_pids=$(pgrep -f wrap | grep PortProton | head -n 1)
        else
            wine_pids=$(ls -l /proc/*/exe 2>/dev/null | grep -ie PortProton | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')
            bwrap_pids="$(pgrep -a wrap | grep PortProton | head -n 1 | awk '{print $1}')"
        fi
    else
        wine_pids=$(ls -l /proc/*/exe 2>/dev/null | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')
        unset bwrap_pids
    fi

    for pw_kill_pids in ${bwrap_pids} ${wine_pids}; do
        if ps cax | grep "${pw_kill_pids}" ; then
            kill -n 9 "${pw_kill_pids}" &>/dev/null
        fi
    done

    return 0
}
export -f kill_portwine

pw_kill_autostart () {
    if [[ -z "${2}" ]]
    then SWAIT=3
    else SWAIT="${2}"
    fi
    sleep 5
    while true ; do
        if  [[ -z "$(ps aux | grep -m 1 -i "$1" | grep -v grep | awk '{print $2}')" ]] \
        && [[ -n "$(ps aux | grep wrap | grep -v grep | grep -i "PortProton" | head -n 1)" ]]
        then
            echo -e "PID $1 not found"
            sleep "${SWAIT}"
        else
            sleep "${SWAIT}"
            if [[ "$3" == please ]]
            then kill -s SIGTERM $(ps aux | grep -m 1 -i "$1" | grep -v grep | awk '{print $2}')
            else kill_portwine
            fi
            break
        fi
    done

    if [[ -n "$(ls "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/ | grep -m 1 ".tmp")" ]] ; then
        rm -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/*.tmp
    fi

    return 0
}
export -f pw_kill_autostart

pw_exit_tray () {
    if [[ "$XDG_SESSION_TYPE" == "tty" ]] ; then
        if [[ -n "$(pgrep -a yad_gui_pp | grep "\--notification" | awk '{print $1}')" ]] ; then
            kill -s SIGUSR1 "$(pgrep -a yad_gui_pp | grep "\--notification" | awk '{print $1}')"
        fi
    else
        if [[ -n "$(pgrep -a tray_gui_pp)" ]] ; then
            kill -s SIGUSR1 $(pgrep -a tray_gui_pp) 2>/dev/null
        fi
    fi
    if [[ -n "$(pgrep -a yad_gui_pp)" ]] ; then
        kill -s SIGUSR1 $(pgrep -a yad_gui_pp) 2>/dev/null
    fi
}
export -f pw_exit_tray

stop_portwine () {
    [[ "$int_xneur" == "1" ]] && xneur &

    if [[ "$PW_USE_US_LAYOUT" == "1" ]] \
    && ! check_wayland_session \
    && command -v setxkbmap &>/dev/null
    then
        setxkbmap
    fi

    if ! check_wayland_session \
    && [[ "$(xrandr | sed -rn 's/^.*primary.* ([0-9]+x[0-9]+).*$/\1/p')" != "$PW_SCREEN_RESOLUTION" ]]
    then
        xrandr --output "$PW_SCREEN_PRIMARY" --mode "$PW_SCREEN_RESOLUTION"
    fi

    if [[ "${PW_DISABLE_COMPOSITING}" == "1" ]] \
    && ! check_gamescope_session
    then
        if [[ "${DESKTOP_SESSION}" =~ "plasma" ]] ; then
            qdbus org.kde.KWin /Compositor resume
        elif [[ "${DESKTOP_SESSION}" =~ "mate" ]] ; then
            gsettings set org.mate.Marco.general compositing-manager true
        elif [[ "${DESKTOP_SESSION}" =~ "xfce" ]] ; then
            xfconf-query -c xfwm4 -p /general/use_compositing -s true
        elif [[ "${DESKTOP_SESSION}" =~ "cinnamon" ]] ; then
            gsettings set org.cinnamon.muffin unredirect-fullscreen-windows false
        elif [[ "${DESKTOP_SESSION}" =~ "deepin" ]] ; then
            dbus-send --session --dest=com.deepin.WMSwitcher --type=method_call /com/deepin/WMSwitcher com.deepin.WMSwitcher.RequestSwitchWM
        fi
    fi

    pw_stop_progress_bar
    try_remove_file "${PORT_SCRIPTS_PATH}/0"
    try_remove_file "${PORT_SCRIPTS_PATH}/1"
    kill_portwine
    try_remove_dir "${PW_WINELIB}/var"
    find "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/" -maxdepth 1 -type f -name "*.tmp" -delete
    pw_exit_tray
    pw_auto_create_shortcut
    add_in_stop_portwine

    if [[ $PW_LOG != 1 ]] ; then
        debug_timer --end -s "PW_TIME_IN_GAME"
        PW_TIME_IN_GAME=$(( PW_TIME_IN_GAME / 1000 )) # в секундах
        search_desktop_file
    fi

    case "$1" in
        --restart)
            restart_pp ;;
        *) 
            unset SKIP_CHECK_UPDATES
            exit 0 ;;
    esac
}
export -f stop_portwine

pw_download_libs () {
    if [[ ! -f "${PW_WINELIB}/runtime/files/bin/vkcube" ]] \
    || [[ ! -f "${PW_WINELIB}/pressure-vessel/bin/pressure-vessel-wrap" ]]
    then
        print_info "Download and install libraries..."
        if try_download "github.com/Castro-Fidel/PortWINE/releases/download/libs${PW_LIBS_VER}/libs${PW_LIBS_VER}.tar.xz" \
                        "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" ; then
            if unpack "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}/" ; then
                try_remove_file "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz"
                if ls "${PORT_WINE_TMP_PATH}" | grep libs_v | grep -v libs"${PW_LIBS_VER}" ; then
                    for RM_LIBS in $(ls "${PORT_WINE_TMP_PATH}" | grep libs_v | grep -v libs"${PW_LIBS_VER}")
                    do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_LIBS}"
                    done
                fi
            else
                try_remove_dir "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}"
                try_remove_file "${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}.tar.xz"
                if yad_error_download
                then pw_download_libs
                else
                    export PW_LIBS_VER="_v$((${PW_LIBS_VER//_v/} - 1))"
                    export PW_WINELIB="${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}"
                fi
            fi
        else
            if yad_error_download
            then pw_download_libs
            else
                export PW_LIBS_VER="_v$((${PW_LIBS_VER//_v/} - 1))"
                export PW_WINELIB="${PORT_WINE_TMP_PATH}/libs${PW_LIBS_VER}"
            fi
        fi
    fi
    return 0
}

pw_check_and_download_wine () {
    [[ ! -d "${PORT_WINE_PATH}/data/dist/" ]] && create_new_dir "${PORT_WINE_PATH}/data/dist"
    if [[ "${PW_WINE_USE}" == "GET-OTHER-WINE" ]] ; then
        gui_proton_downloader
    fi
    if [[ "$PW_WINE_USE" == PROTON_LG ]]
    then export PW_WINE_USE="${PW_PROTON_LG_VER}"
    elif [[ "$PW_WINE_USE" == WINE_*_LG ]] || [[ "$PW_WINE_USE" == WINE_LG ]]
    then export PW_WINE_USE="${PW_WINE_LG_VER}"
    fi
    if [[ ! -d "${PORT_WINE_PATH}/data/dist/${PW_WINE_USE}" ]] ; then
        print_info "Download and install ${PW_WINE_USE}..."
        if try_download "github.com/Castro-Fidel/wine_builds/releases/download/${PW_WINE_USE}/${PW_WINE_USE}.tar.xz" \
                        "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}.tar.xz" ; then
            if unpack "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}.tar.xz" "${PORT_WINE_PATH}/data/dist/" ; then
                echo "${PW_WINE_USE}" > "${PORT_WINE_PATH}/data/dist/${PW_WINE_USE}/version"
                try_remove_file "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}.tar.xz"
                try_remove_dir "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}"
            else
                try_remove_file "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}.tar.xz"
                try_remove_dir "${PORT_WINE_PATH}/data/tmp/${PW_WINE_USE}"
                try_remove_dir "${PORT_WINE_PATH}/data/dist/${PW_WINE_USE}"

                yad_error_download && pw_check_and_download_wine || exit 1
            fi
        else
            yad_error_download && pw_check_and_download_wine || exit 1
        fi
    fi
    return 0
}

pw_check_and_download_dxvk_and_vkd3d () {
    # Download stable and git version DXVK
    for DXVK_VAR_VER in "${DXVK_STABLE_VER}" "${DXVK_GIT_VER}" "${DXVK_LEGACY_VER}" ; do
        if [[ ! -d "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}" ]] ; then
            print_info "Download and install DXVK v.${DXVK_VAR_VER}"
            if try_download "https://github.com/Castro-Fidel/vulkan/releases/download/dxvk-${DXVK_VAR_VER}/dxvk-${DXVK_VAR_VER}.tar.xz" \
                                      "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.xz" ; then
                if unpack "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.xz" "${PW_VULKAN_DIR}" ; then
                    try_remove_file "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.xz"
                else
                    try_remove_file "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.xz"
                    try_remove_dir "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}"

                    yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
                fi
            elif try_download "https://github.com/doitsujin/dxvk/releases/download/v${DXVK_VAR_VER}/dxvk-${DXVK_VAR_VER}.tar.gz" \
                                       "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.gz"  no_mirror ; then
                if unpack "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.gz" "${PW_VULKAN_DIR}" ; then
                    try_remove_file "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.gz"
                else
                    try_remove_file "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}.tar.gz"
                    try_remove_dir "${PW_VULKAN_DIR}/dxvk-${DXVK_VAR_VER}"

                    yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
                fi
            else
                yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
            fi
        fi
    done

    # Download stable and git version VKD3D
    for VKD3D_VAR_VER in "${VKD3D_STABLE_VER}" "${VKD3D_GIT_VER}" ; do
        if [[ ! -d "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}" ]] ; then
            print_info "Download and install VKD3D-PROTON v.${VKD3D_VAR_VER}"
            if try_download "https://github.com/Castro-Fidel/vulkan/releases/download/vkd3d-proton-${VKD3D_VAR_VER}/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz" \
                                      "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz" ; then
                if unpack "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz" "${PW_VULKAN_DIR}" ; then
                    try_remove_file "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz"
                else
                    try_remove_file "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz"
                    try_remove_dir "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}"

                    yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
                fi
            elif try_download "https://github.com/HansKristian-Work/vkd3d-proton/releases/download/v${VKD3D_VAR_VER}/vkd3d-proton-${VKD3D_VAR_VER}.tar.zst" \
                                        "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.zst" no_mirror ; then
                if unpack "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.zst" "${PW_VULKAN_DIR}" ; then
                    try_remove_file "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.zst"
                else
                    try_remove_file "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.zst"
                    try_remove_dir "${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_VAR_VER}"

                    yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
                fi
            else
                yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
            fi
        fi
    done

    # Download DGVOODOO2
    if [[ ! -f "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}/dgVoodoo.conf" ]] ; then
        print_info "Download and install DGVOODOO2 v.${DGV2_VER}"
        if try_download "https://github.com/Castro-Fidel/vulkan/releases/download/dgvoodoo2-${DGV2_VER}/dgvoodoo2-${DGV2_VER}.tar.xz" \
        "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}.tar.xz"
        then
            if unpack "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}.tar.xz" "${PW_VULKAN_DIR}" ; then
                try_remove_file "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}.tar.xz"
            else
                try_remove_file "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}.tar.xz"
                try_remove_dir "${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}"

                yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
            fi
        else
            yad_error_download && pw_check_and_download_dxvk_and_vkd3d || exit 1
        fi
    fi

    return 0
}

pw_check_and_download_plugins () {
    if [[ ! -f "${PW_PLUGINS_PATH}/portable/lib/lib64/libvkbasalt.so" ]] ; then
        print_info "Download and install plugins${PW_PLUGINS_VER}..."
        if command -v yad &>/dev/null ; then
            if try_download "github.com/Castro-Fidel/wine_builds/releases/download/plugins${PW_PLUGINS_VER}/plugins${PW_PLUGINS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" ; then
                if unpack "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}" ; then
                    try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz"
                    # TODO: drop clear prefix, and add update prefix from new plugins
                    pw_clear_pfx
                    if ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}"
                    then
                        for RM_PLUGINS in $(ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}")
                        do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}"
                        done
                    fi
                else
                    try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz"
                    try_remove_dir "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}"
                    if yad_error_download
                    then pw_check_and_download_plugins
                    else
                        export PW_PLUGINS_VER="_v$((${PW_PLUGINS_VER//_v/} - 1))"
                        export PW_PLUGINS_PATH="${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}"
                    fi
                fi
            else
                if yad_error_download
                then pw_check_and_download_plugins
                else
                    export PW_PLUGINS_VER="_v$((${PW_PLUGINS_VER//_v/} - 1))"
                    export PW_PLUGINS_PATH="${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}"
                fi
            fi
        else
            pw_notify_send -i info \
            "${translations[Please wait for update PortProton]}"
            if try_download "github.com/Castro-Fidel/wine_builds/releases/download/plugins${PW_PLUGINS_VER}/plugins${PW_PLUGINS_VER}.tar.xz" \
                                   "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" silent ; then
                if unpack "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz" "${PORT_WINE_TMP_PATH}" ; then
                    try_remove_file "${PORT_WINE_TMP_PATH}/plugins${PW_PLUGINS_VER}.tar.xz"
                    # TODO: drop clear prefix, and add update prefix from new plugins
                    pw_clear_pfx
                    if ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}"
                    then
                        for RM_PLUGINS in $(ls "${PORT_WINE_TMP_PATH}" | grep plugins_v | grep -v "plugins${PW_PLUGINS_VER}")
                        do try_remove_dir "${PORT_WINE_TMP_PATH}/${RM_PLUGINS}"
                        done
                    fi
                else
                    print_error "Failed updating PortProton!"
                    pw_notify_send -i error \
                    "${translations[Failed updating PortProton!]}"
                fi
            fi
        fi
    fi
    if command -v 7z &>/dev/null
    then export pw_7z="7z"
    else export pw_7z="${PW_PLUGINS_PATH}/portable/lib/p7zip/7z"
    fi
    return 0
}

check_dirs_and_files_in_pfx () {
        create_new_dir "${WINEPREFIX}/dosdevices"
        create_new_dir "${WINEPREFIX}/drive_c/windows/syswow64/"
        create_new_dir "${WINEPREFIX}/drive_c/windows/system32/"
        create_new_dir "${WINEPREFIX}/drive_c/tmp/.private/$USER/"
        create_new_dir "${WINEPREFIX}/drive_c/tmp/.private/steamuser/"

        [[ ! -d "${WINEPREFIX}/dosdevices/c:" ]] && try_force_link_dir "${WINEPREFIX}/drive_c/" "${WINEPREFIX}/dosdevices/c:"
        [[ ! -d "${WINEPREFIX}/dosdevices/z:" ]] && try_force_link_dir "/" "${WINEPREFIX}/dosdevices/z:"
        [[ ! -d "${WINEPREFIX}/dosdevices/h:" ]] && try_force_link_dir "$HOME" "${WINEPREFIX}/dosdevices/h:"

        if [[ ! -d "${WINEPREFIX}/dosdevices/s:" ]] \
        && [[ -d "$HOME/.local/share/Steam/steamapps/common/" ]]
        then
            try_force_link_dir "$HOME/.local/share/Steam/steamapps/common/" "${WINEPREFIX}/dosdevices/s:"
        fi

        create_new_dir "${WINEPREFIX}/drive_c/windows/Fonts/"
        LN_FONTS="arialbd.ttf courbd.ttf georgia.ttf micross.ttf msyh.ttf simsun.ttc arial.ttf cour.ttf malgun.ttf msgothic.ttc nirmala.ttf times.ttf"
        for link_font in $LN_FONTS ; do
            if [[ ! -f "${WINEPREFIX}/drive_c/windows/Fonts/${link_font}" ]] ; then
                try_force_link_file "${WINEDIR}/share/fonts/${link_font}" "${WINEPREFIX}/drive_c/windows/Fonts/${link_font}"
            fi
        done

        create_new_dir "${WINEPREFIX}/drive_c/users/steamuser"
        if [[ ! -d "${WINEPREFIX}/drive_c/users/${USER}" ]]
        then try_force_link_dir "${WINEPREFIX}/drive_c/users/steamuser" "${WINEPREFIX}/drive_c/users/${USER}"
        fi

        create_new_dir "${WINEPREFIX}/drive_c/users/Public/Documents/Steam"
        create_new_dir "${WINEPREFIX}/drive_c/users/steamuser/Documents/Steam"
        if [[ ! -d "${WINEPREFIX}/drive_c/users/steamuser/My Documents" ]]
        then try_force_link_dir "${WINEPREFIX}/drive_c/users/steamuser/Documents" "${WINEPREFIX}/drive_c/users/steamuser/My Documents"
        fi

        create_new_dir "${WINEPREFIX}/drive_c/users/steamuser/AppData/Roaming"
        if [[ ! -d "${WINEPREFIX}/drive_c/users/steamuser/Application Data" ]]
        then try_force_link_dir "${WINEPREFIX}/drive_c/users/steamuser/AppData/Roaming" "${WINEPREFIX}/drive_c/users/steamuser/Application Data"
        fi

        create_new_dir "${WINEPREFIX}/drive_c/users/steamuser/AppData/Local"
        create_new_dir "${WINEPREFIX}/drive_c/users/steamuser/Local Settings"
        if [[ ! -d "${WINEPREFIX}/drive_c/users/steamuser/Local Settings/Application Data" ]]
        then try_force_link_dir "${WINEPREFIX}/drive_c/users/steamuser/AppData/Local" "${WINEPREFIX}/drive_c/users/steamuser/Local Settings/Application Data"
        fi

        DRIVES=(d e f g i j k l m n o p q r t u v w x y)
        DEF_MOUNT_DIRS=('/media' '/mnt' '/run/media')
        MOUNT_DIRS=($(find "${DEF_MOUNT_DIRS[@]}" -maxdepth 1 -mindepth 1  -type d 2>/dev/null | sort -u))
        find -L "$WINEPREFIX/dosdevices" -maxdepth 1 -type l -exec rm -rf {} \; 2>/dev/null ;

        for drive_dir in "${MOUNT_DIRS[@]}" ; do
            if  mountpoint -q "$drive_dir" ; then
                if ! realpath "${WINEPREFIX}/dosdevices"/*: | grep -w "$drive_dir"$ &>/dev/null ; then
                    drive_num=0
                    while [[ "$drive_num" -lt "${#DRIVES[@]}" ]] ; do
                        drive_path="${WINEPREFIX}/dosdevices/${DRIVES[$drive_num]}:"
                        mount_point=$(df -P "$drive_dir" | awk 'NR==2 {print $1}')
                        mount_name=$(lsblk -no pkname "$mount_point" 2>/dev/null)

                        if [[ ! -L "$drive_path" ]] ; then
                            if [[ $(<"/sys/class/block/$mount_name/removable") != "1" ]] 2>/dev/null ; then
                                if [[ ! "$mount_point" =~ "mmc" ]] ; then
                                    ln -sf "$drive_dir" "$drive_path"
                                    print_info "Mounted ${drive_dir} to ${drive_path}"
                                    break
                                else
                                    ((drive_num++))
                                fi
                            else
                                ((drive_num++))
                            fi
                        else
                            ((drive_num++))
                        fi
                    done
                fi
            fi
        done
    }

check_nvidia_rtx () {
    if [[ -n $(echo "$LSPCI_VGA" | grep -i "nvidia") ]] ; then
        # Turing (without nvidia 16XX)
        [[ "$LSPCI_VGA" == *TU[0-9]* ]] && [[ "$LSPCI_VGA" != *TU11[6-7]* ]] && return 0
        # Ampere
        [[ "$LSPCI_VGA" == *GA[0-9]* ]] && return 0
        # Ada_Lovelace
        [[ "$LSPCI_VGA" == *AD[0-9]* ]] || [[ "$LSPCI_VGA" == *2[6-8][0-9]* ]] && return 0
    fi
    return 1
}

pw_init_db () {
    if [[ -f "${portwine_exe}" ]] ; then
        PORTWINE_DB="$(basename "${portwine_exe%.[Ee][Xx][Ee]}")"
        export PORTWINE_DB
        if echo "${PORTWINE_DB}" | grep -i "_vo_\|_gv_" &>/dev/null ; then
            print_warning "Force use gamesvoice.ppdb file!"
            PORTWINE_DB_FILE="${PORT_SCRIPTS_PATH}/portwine_db/gamesvoice.ppdb"
            # shellcheck source=/dev/null
            source "${PORTWINE_DB_FILE}"
        elif [[ -f "${portwine_exe}".ppdb ]] ; then
            PORTWINE_DB_FILE="${portwine_exe}".ppdb
            # shellcheck source=/dev/null
            source "${PORTWINE_DB_FILE}"
            if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then
                if [[ -z $(ls "${PORT_WINE_PATH}/prefixes/" | grep -e ^"${PW_PREFIX_NAME}"$) ]] \
                || [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]]
                then
                    PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
                    edit_db_from_gui PW_PREFIX_NAME
                fi
            fi
        else
            IFS=$'\n'
            PW_FIND_DB_FILE=$(grep -ilw "#${PORTWINE_DB}.exe" "${PORT_SCRIPTS_PATH}/portwine_db"/* | sed s/".exe"/""/gi)
            if [[ $(echo "$PW_FIND_DB_FILE" | wc -l) -gt 1 ]] ; then
                unset ADD_CB_DBFILE
                for PW_CHECK_DB_FILE in $PW_FIND_DB_FILE ; do
                    if [[ -z "${ADD_CB_DBFILE}" ]] ; then
                        ADD_CB_DBFILE="$(echo "${PW_CHECK_DB_FILE}" | awk -F'/' '{print $NF}')"
                    else
                        ADD_CB_DBFILE="$(echo "${PW_CHECK_DB_FILE}" | awk -F'/' '{print $NF}')!${ADD_CB_DBFILE}"
                    fi
                done
                PORTWINE_DB_FILE="${PORT_SCRIPTS_PATH}/portwine_db"/$("${pw_yad}" --text-align=center \
                --text "${translations[More than one DB file found for the application being launched.\\nSelect the required one, or delete the extra DB file before the next run.\\n]}" --borders="${YAD_BORDERS}" --form \
                --title "Database file selection..." --window-icon="$PW_GUI_ICON_PATH/portproton.svg"  --form --separator="" \
                --field="DB FILE: :CB" "${ADD_CB_DBFILE}" 2>/dev/null)
                if [[ "$?" == "1" || "$?" == "252" ]] ; then exit 0 ; fi
            elif [[ $(echo "$PW_FIND_DB_FILE" | wc -l) -eq 1 ]] ; then
                PORTWINE_DB_FILE="${PW_FIND_DB_FILE}"
            fi
            IFS="$orig_IFS"

            if [[ -f "${PW_FIND_DB_FILE}" ]] ; then
                # shellcheck source=/dev/null
                source "${PORTWINE_DB_FILE}"
            fi

            if [[ -f "${PW_FIND_DB_FILE}" ]] \
            && [[ "${PW_DISABLED_CREATE_DB}" != 1 ]]
            then
                try_copy_file "${PW_FIND_DB_FILE}" "${portwine_exe}".ppdb
                PORTWINE_DB_FILE="${portwine_exe}".ppdb
                if echo "${portwine_exe}" | grep "/prefixes/" &>/dev/null ; then
                    if [[ -z $(ls "${PORT_WINE_PATH}/prefixes/" | grep -e ^"${PW_PREFIX_NAME}"$) ]] \
                    || [[ -z $(grep -e ^"export PW_PREFIX_NAME=" "${PORTWINE_DB_FILE}" 2>/dev/null) ]]
                    then
                        PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
                        edit_db_from_gui PW_PREFIX_NAME
                    fi
                fi
            fi
        fi

        if [[ -f "${PORTWINE_DB_FILE}" ]] ; then
            # shellcheck source=/dev/null
            source "${PORTWINE_DB_FILE}"
            init_wine_ver &&
            print_info "Use $PORTWINE_DB_FILE db file."
        else
            if [[ "${PW_DISABLED_CREATE_DB}" != 1 ]] ; then
                if [[ -n "${PORTWINE_DB}" ]] ; then
                    PORTWINE_DB_FILE=$(grep -il "#${PORTWINE_DB}.exe" "${PORT_SCRIPTS_PATH}/portwine_db"/*)
                    export PORTWINE_DB_FILE
                    if [[ -z "${PORTWINE_DB_FILE}" ]] ; then
                        {
                            echo "#!/usr/bin/env bash"
                            echo "#Author: ${USER}"
                            echo "#${PORTWINE_DB}.exe"
                            echo "#Rating=1-5"
                        } > "${portwine_exe}".ppdb
                        export PORTWINE_DB_FILE="${portwine_exe}".ppdb
                    fi
                    if [[ "${portwine_exe}" =~ "/data/prefixes/" ]] && \
                    [[ ! "${portwine_exe}" =~ "/data/prefixes/DEFAULT/" ]]
                    then
                        PW_PREFIX_NAME=$(echo "${portwine_exe}" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
                    fi
                    # shellcheck source=/dev/null
                    source "${PORTWINE_DB_FILE}"
                fi
                edit_db_from_gui PW_VULKAN_USE PW_WINE_USE PW_PREFIX_NAME
            fi
        fi

        if [[ -z "${PATH_TO_GAME}" ]] || [[ ! -d "${PATH_TO_GAME}" ]] ; then
            PATH_TO_GAME="$( cd "$( dirname "${portwine_exe}" )" >/dev/null 2>&1 && pwd )"
            export PATH_TO_GAME
        fi

        if [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] && [[ -n "${WINE_CPU_TOPOLOGY}" ]] ; then
            export PW_WINE_CPU_TOPOLOGY="${WINE_CPU_TOPOLOGY}"
        fi
        if ls "${PATH_TO_GAME}"/*_Data/Resources/ 2>/dev/null | grep "unity" &>/dev/null \
        && [[ "${PW_WINE_CPU_TOPOLOGY}" == "disabled" ]] \
        && [[ $(grep -c ^"processor" /proc/cpuinfo) -gt "8" ]]
        then
            export PW_WINE_CPU_TOPOLOGY="8:0,1,2,3,4,5,6,7"
            print_info "Automatic added fix for unity games: WINE_CPU_TOPOLOGY=8:0,1,2,3,4,5,6,7"
        fi
    fi

    [[ "${START_FROM_STEAM}" == 1 ]] && export PW_GUI_DISABLED_CS=1
    [[ "${START_FROM_PP_GUI}" == 1 ]] && export PW_GUI_DISABLED_CS=0 && unset START_FROM_PP_GUI

    return 0
}

# GUI UPDATE SCRIPTS
pw_port_update () {
    case "$BRANCH" in
        master|stable)
            BRANCH_VERSION_UPDATE="SCRIPTS_STABLE_VERSION"
            BRANCH="master"
            ;;
         devel|beta)
            BRANCH_VERSION_UPDATE="SCRIPTS_NEXT_VERSION"
            BRANCH="devel"
            ;;
    esac

    if [[ ! -f "${PORT_WINE_TMP_PATH}/scripts_ver" ]] ; then
        echo "2024" > "${PORT_WINE_TMP_PATH}/scripts_ver"
    fi

    URL_ETERFUND="https://gitlab.eterfund.ru/Castro-Fidel/PortWINE/raw/${BRANCH}/data_from_portwine/scripts/var"
    URL_GITHUB="https://raw.githubusercontent.com/Castro-Fidel/PortWINE/${BRANCH}/data_from_portwine/scripts/var"
    URL_PP_GITEA="https://git.linux-gaming.ru/CastroFidel/PortWINE/raw/branch/${BRANCH}/data_from_portwine/scripts/var"

    pw_check_update () {
        debug_timer --start -s "UPDATE_ETERFUND"
        if ! timeout 2 curl -f -s --list-only "$URL_ETERFUND" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
        then
            print_warning "https://gitlab.eterfund.ru/ broken. Skip it..."
            UPDATE_SKIP_ETERFUND="1"
        fi
        debug_timer --end -s "UPDATE_ETERFUND"

        debug_timer --start -s "UPDATE_GITHUB"
        if ! timeout 2 curl -f -s --list-only "$URL_GITHUB" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
        then
            print_warning "https://raw.githubusercontent.com/ broken. Skip it..."
            UPDATE_SKIP_GITHUB="1"
        fi
        debug_timer --end -s "UPDATE_GITHUB"

        debug_timer --start -s "UPDATE_PP_GITEA"
        if ! timeout 2 curl -f -s --list-only "$URL_PP_GITEA" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
        then
            print_warning "https://git.linux-gaming.ru/ broken. Skip it..."
            UPDATE_SKIP_PP_GITEA="1"
        fi
        debug_timer --end -s "UPDATE_PP_GITEA"

        if [[ "$UPDATE_SKIP_ETERFUND" == "1" ]] \
        && [[ "$UPDATE_SKIP_GITHUB" == "1" ]] \
        && [[ "$UPDATE_SKIP_PP_GITEA" == "1" ]] ; then
            print_error "Unable to determine the version on the server. Skip it..."
            return 1
        fi

        PW_UPDATE_ALL_LIST=($UPDATE_ETERFUND $UPDATE_GITHUB $UPDATE_PP_GITEA)

        UPDATE_MIN=${PW_UPDATE_ALL_LIST[0]}
        for i in "${!PW_UPDATE_ALL_LIST[@]}"; do
        if (( ${PW_UPDATE_ALL_LIST[$i]} < UPDATE_MIN )) ; then
            UPDATE_MIN=${PW_UPDATE_ALL_LIST[$i]}
        fi
        done

        UPDATE_DAYS=$(date +%-j)
        UPDATE_MINUTES=$(($(date +%-H) * 60 + $(date +%-M)))
        if [[ "$UPDATE_ETERFUND" == "$UPDATE_MIN" ]] ; then
            print_info "Selected https://gitlab.eterfund.ru/"
            echo "$UPDATE_DAYS $UPDATE_MINUTES UPDATE_ETERFUND $UPDATE_MINUTES" > "${PORT_WINE_TMP_PATH}/update_skip_mirror"
            UPDATE_URL_MIRROR="UPDATE_ETERFUND"
        elif [[ "$UPDATE_GITHUB" == "$UPDATE_MIN" ]] ; then
            print_info "Selected https://raw.githubusercontent.com/"
            echo "$UPDATE_DAYS $UPDATE_MINUTES UPDATE_GITHUB $UPDATE_MINUTES" > "${PORT_WINE_TMP_PATH}/update_skip_mirror"
            UPDATE_URL_MIRROR="UPDATE_GITHUB"
        elif [[ "$UPDATE_PP_GITEA" == "$UPDATE_MIN" ]] ; then
            print_info "Selected https://git.linux-gaming.ru/"
            echo "$UPDATE_DAYS $UPDATE_MINUTES UPDATE_PP_GITEA $UPDATE_MINUTES" > "${PORT_WINE_TMP_PATH}/update_skip_mirror"
            UPDATE_URL_MIRROR="UPDATE_PP_GITEA"
        fi
        PW_FORCE_UPDATE="1"
    }

    [[ ! -f "${PORT_WINE_TMP_PATH}/scripts_update_notifier" ]] && echo "1" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
    scripts_update_not=$(<"${PORT_WINE_TMP_PATH}/scripts_update_notifier")

    if [[ ! -f "${PORT_WINE_TMP_PATH}/update_skip_mirror" ]] ; then
        pw_check_update
    else
        read -r -a CHECK_UPDATE_MIRROR <"${PORT_WINE_TMP_PATH}/update_skip_mirror"
        UPDATE_SKIP_DAYS="${CHECK_UPDATE_MIRROR[0]}"
        UPDATE_DATE_MIRROR="${CHECK_UPDATE_MIRROR[1]}"
        UPDATE_SKIP_DATE="${CHECK_UPDATE_MIRROR[3]}"
        UPDATE_DAYS=$(date +%-j)
        UPDATE_MINUTES=$(($(date +%-H) * 60 + $(date +%-M)))
        if [[ "${scripts_update_not}" != "0" ]] ; then
            if (( $((UPDATE_DATE_MIRROR + 360)) <= UPDATE_MINUTES )) \
            || [[ "$UPDATE_SKIP_DAYS" != "$UPDATE_DAYS" ]] \
            || [[ "$PW_FORCE_UPDATE" == "1" ]] ; then
                pw_check_update
            fi
        else
            if [[ "$UPDATE_SKIP_DAYS" != "$UPDATE_DAYS" ]] ; then
                pw_check_update
            else
                return 0
            fi
        fi
    fi

    if (( $((UPDATE_SKIP_DATE + $(((RANDOM%11)+25)) )) <= UPDATE_MINUTES )) \
    || [[ "$PW_FORCE_UPDATE" == "1" ]] \
    || [[ "${scripts_update_not}" == "2" ]] ; then
        if [[ "${scripts_update_not}" == "2" ]] ; then
            echo "1" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
        fi
        print_info "Check update..."
        if [[ -z "$UPDATE_URL_MIRROR" ]] ; then
            UPDATE_URL_MIRROR="${CHECK_UPDATE_MIRROR[2]}"
            sed -i 's/[0-9]*$/'"$UPDATE_MINUTES"'/' "${PORT_WINE_TMP_PATH}/update_skip_mirror"
        fi
        case "$UPDATE_URL_MIRROR" in
            UPDATE_ETERFUND)
                if [[ ! -f "${PORT_WINE_TMP_PATH}/curent_var_ver" ]] \
                && ! timeout 2 curl -f -s --list-only "$URL_ETERFUND" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
                then
                    pw_check_update
                fi
                URL_FOR_CHANGELOG="https://gitlab.eterfund.ru/Castro-Fidel/PortWINE/raw/${BRANCH}/data_from_portwine"
                URL_TO_PW_BRANCH="https://gitlab.eterfund.ru/Castro-Fidel/PortWINE/-/archive/${BRANCH}/PortWINE-${BRANCH}.tar.gz"
                ;;
            UPDATE_GITHUB)
                if [[ ! -f "${PORT_WINE_TMP_PATH}/curent_var_ver" ]] \
                && ! timeout 2 curl -f -s --list-only "$URL_GITHUB" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
                then
                    pw_check_update
                fi
                URL_FOR_CHANGELOG="https://raw.githubusercontent.com/Castro-Fidel/PortWINE/${BRANCH}/data_from_portwine"
                URL_TO_PW_BRANCH="https://github.com/Castro-Fidel/PortWINE/archive/refs/heads/${BRANCH}.tar.gz"
                ;;
            UPDATE_PP_GITEA)
                if [[ ! -f "${PORT_WINE_TMP_PATH}/curent_var_ver" ]] \
                && ! timeout 2 curl -f -s --list-only "$URL_PP_GITEA" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
                then
                    pw_check_update
                fi
                URL_FOR_CHANGELOG="https://git.linux-gaming.ru/CastroFidel/PortWINE/raw/branch/${BRANCH}/data_from_portwine"
                URL_TO_PW_BRANCH="https://git.linux-gaming.ru/CastroFidel/PortWINE/archive/${BRANCH}.tar.gz"
                UPDATE_PP_GITEA_FIX=1
                ;;
        esac
    else
        return 0
    fi

    scripts_current_ver=$(grep "$BRANCH_VERSION_UPDATE" "${PORT_WINE_TMP_PATH}/curent_var_ver" | awk -F "=" '{print $2}')
    if [[ ! -f "${PORT_WINE_TMP_PATH}/update_remind_later" ]] ; then
        echo "$scripts_current_ver" > "${PORT_WINE_TMP_PATH}/update_remind_later"
    else
        PW_REMIND_LATER=$(<"${PORT_WINE_TMP_PATH}/update_remind_later")
        if [[ $PW_REMIND_LATER != "$scripts_current_ver" ]] ; then
            echo "2" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
            echo "$scripts_current_ver" > "${PORT_WINE_TMP_PATH}/update_remind_later"
            scripts_update_not=$(<"${PORT_WINE_TMP_PATH}/scripts_update_notifier")
        fi
    fi

    if [[ "${scripts_update_not}" == [12] ]] ; then
        [[ "$LANGUAGE" == ru ]] && local PW_CHANGELOG_FILE="changelog_ru" || local PW_CHANGELOG_FILE="changelog_en"
        print_info "Scripts version in git = ${scripts_current_ver}"
        print_info "Scripts version local = ${scripts_install_ver}\n"
        if [[ -n "${scripts_current_ver}" ]] && [[ "${scripts_current_ver}" -gt "${scripts_install_ver}" ]] ; then
            echo "2" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
            if [[ -f "${PW_GUI_THEMES_PATH}/gui/yad_gui_pp" ]]
            then export pw_yad="${PW_GUI_THEMES_PATH}/gui/yad_gui_pp"
            elif command -v yad &>/dev/null
            then local pw_yad="yad"
            else local pw_yad="not_found"
            fi
            if [[ "${pw_yad}" == "not_found" ]] \
            || [[ "$PW_CHANGE_BRANCH" == "1" ]] ; then
                YAD_STATUS=20
                unset PW_CHANGE_BRANCH
            else
                curl -s --list-only "${URL_FOR_CHANGELOG}/${PW_CHANGELOG_FILE}" > "${PORT_WINE_TMP_PATH}/curent_var_ver"
                sed -i "/Scripts version ${scripts_install_ver}/,$ d" "${PORT_WINE_TMP_PATH}/curent_var_ver"

                "${pw_yad}" --title "${translations[Update scripts:]} v.(${scripts_install_ver}${BRANCH_VERSION})" \
                --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --width=1280 --height=720 --text-info --wrap --scroll \
                --button="${translations[DO NOT REMIND ME]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":16 \
                --button="${translations[REMIND ME LATER]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":18 \
                --button="${translations[UPDATING NOW]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":20 < "${PORT_WINE_TMP_PATH}/curent_var_ver" 2>/dev/null
                YAD_STATUS="$?"

                # --button="${translations[EXIT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":252 \
            fi
            try_remove_file "${PORT_WINE_TMP_PATH}/curent_var_ver"
            case $YAD_STATUS in
                1|252)
                    exit 0 ;;
                16)
                    echo "0" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier" ;;
                18)
                    : ;;
                20)
                    echo "######################################################"
                    print_info "Update scripts..."
                    if [[ $UPDATE_PP_GITEA_FIX == 1 ]] ; then
                        unset UPDATE_PP_GITEA_FIX
                        PW_NAME_ARCHIVE="portwine"
                    else
                        PW_NAME_ARCHIVE="PortWINE-${BRANCH}"
                    fi
                    try_remove_file "${PORT_WINE_TMP_PATH}/PortWINE-${BRANCH}.tar.gz"
                    if try_download "${URL_TO_PW_BRANCH}" "${PORT_WINE_TMP_PATH}/PortWINE-${BRANCH}.tar.gz" no_mirror ; then
                        if unpack "${PORT_WINE_TMP_PATH}/PortWINE-${BRANCH}.tar.gz" "${PORT_WINE_TMP_PATH}"
                        then
                            create_new_dir "${PORT_WINE_TMP_PATH}/scripts_backup"
                            cd "${PORT_WINE_PATH}/data/" || fatal
                            tar -czpf "${PORT_WINE_TMP_PATH}/scripts_backup/scripts_v.${scripts_install_ver}.tar.gz" \
                            ./scripts ./img/gui ./locales ./themes ./changelog* ./dxvk.conf ./vkBasalt.conf ./tmp/scripts_ver
                            try_remove_dir "${PORT_WINE_PATH}/data/scripts/"
                            cp -fr "${PORT_WINE_TMP_PATH}/$PW_NAME_ARCHIVE/data_from_portwine/"* "${PORT_WINE_PATH}/data/"
                            try_remove_file "${PORT_WINE_TMP_PATH}/PortWINE-${BRANCH}.tar.gz"
                            try_remove_dir "${PORT_WINE_TMP_PATH}/$PW_NAME_ARCHIVE/"
                            echo "${scripts_current_ver}" > "${PORT_WINE_TMP_PATH}/scripts_ver"
                            unset SKIP_CHECK_UPDATES
                            echo "Restarting PP after update..."
                            restart_pp
                        fi
                    else
                        yad_error_download && pw_port_update || exit 1
                    fi ;;
            esac
        fi
    fi
    return 0
}

pw_check_command () {
    local S_CMD="${1//" "*/}"
    local F_CMD="$1"

    [[ -z "$TIMEOUT_CMD" ]] && TIMEOUT_CMD="3"

    if command -v "$S_CMD" &>/dev/null ; then
        if ! timeout "$TIMEOUT_CMD" $F_CMD &> "${PW_TMPFS_PATH}/$S_CMD.tmp" ; then
            print_error "$S_CMD - broken!"
            unset TIMEOUT_CMD
            return 1
        else
            print_info "$S_CMD - found"
            unset TIMEOUT_CMD
            return 0
        fi
    else
        print_warning "$S_CMD - not found!"
        unset TIMEOUT_CMD
        return 1
    fi
}
export -f pw_check_command

pw_get_tmp_files () {
    for f_cmd in "gamescope --help" "lspci -k" "xrandr --current" "locale -a"
    do pw_check_command "$f_cmd"
    done

    TIMEOUT_CMD="5"
    if ! pw_check_command vulkaninfo ; then
        print_warning "use portable vulkaninfo"
        "$PW_PLUGINS_PATH"/portable/bin/x86_64-linux-gnu-vulkaninfo &> "${PW_TMPFS_PATH}/vulkaninfo.tmp"
    fi
}

pw_skip_get_info () {
    if [[ "${SKIP_CHECK_UPDATES_NEW}" != "1" ]] ; then
        background_pid --end "pw_get_tmp_files" "1"

        if [[ -f "${PW_TMPFS_PATH}/gamescope.tmp" ]] ; then
            export GAMESCOPE_INSTALLED="1"
        fi

        if [[ -f "${PW_TMPFS_PATH}/vulkaninfo.tmp" ]] ; then
            VULKAN_DRIVER_NAME="$(grep -e 'driverName' "${PW_TMPFS_PATH}/vulkaninfo.tmp" | awk '{print$3}' | head -1)"
            GET_GPU_NAMES=$(awk -F '=' '/deviceName/{print $2}' "${PW_TMPFS_PATH}/vulkaninfo.tmp" | sed '/llvm/d'| sort -u | sed 's/^ //' | paste -sd '!')
            export VULKAN_DRIVER_NAME GET_GPU_NAMES
        fi

        if [[ -f "${PW_TMPFS_PATH}/lspci.tmp" ]] ; then
            LSPCI_VGA="$(grep -e 'VGA|3D' "${PW_TMPFS_PATH}/lspci.tmp" | tr -d '\n')"
            export LSPCI_VGA
        fi

        if check_nvidia_rtx ; then
            check_variables PW_USE_NVAPI_AND_DLSS "1"
            check_variables PW_USE_FAKE_DLSS "0"
            check_variables PW_USE_RAY_TRACING "1"
        fi

        if [[ -f "${PW_TMPFS_PATH}/xrandr.tmp" ]] ; then
            PW_SCREEN_RESOLUTION="$(<"${PW_TMPFS_PATH}/xrandr.tmp" sed -rn 's/^.*primary.* ([0-9]+x[0-9]+).*$/\1/p')"
            PW_SCREEN_PRIMARY="$(grep -e 'primary' "${PW_TMPFS_PATH}/xrandr.tmp" | awk '{print $1}')"
            export PW_SCREEN_PRIMARY PW_SCREEN_RESOLUTION
        fi

        if [[ -f "${PW_TMPFS_PATH}/locale.tmp" ]] ; then
            GET_LOCALE_LIST="ru_RU.utf en_US.utf zh_CN.utf ja_JP.utf ko_KR.utf"
            unset LOCALE_LIST
            for LOCALE in $GET_LOCALE_LIST ; do
                if [[ $(<"${PW_TMPFS_PATH}/locale.tmp") =~ $LOCALE ]] ; then
                    if [[ -n "$LOCALE_LIST" ]]
                    then LOCALE_LIST+="!$LOCALE"
                    else LOCALE_LIST="$LOCALE"
                    fi
                fi
            done
            export LOCALE_LIST
        fi

        logical_cores=$(grep -c ^"processor" /proc/cpuinfo)
        if [[ "${logical_cores}" -le "4" ]] ; then
            GET_LOGICAL_CORE="1!$(seq -s! 1 $(( logical_cores - 1 )))"
        else
            GET_LOGICAL_CORE="1!2!$(seq -s! 4 4 $(( logical_cores - 1 )))"
        fi
        export GET_LOGICAL_CORE

        export SKIP_CHECK_UPDATES_NEW="1"
    fi
}

update_winetricks () {
    W_TRX_URL="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"
    W_TRX_EXT_VER="$(curl -s --list-only ${W_TRX_URL} | grep -i 'WINETRICKS_VERSION=' | sed 's/WINETRICKS_VERSION=//')"
    print_info "Version winetricks on server: ${W_TRX_EXT_VER}"
    W_TRX_INT_VER="$(grep -i 'WINETRICKS_VERSION=' "${PORT_WINE_TMP_PATH}/winetricks" | sed 's/WINETRICKS_VERSION=//')"
    print_info "Version winetricks in port: ${W_TRX_INT_VER}"
    if [[ ! -f "${PORT_WINE_TMP_PATH}/winetricks" && -n "$W_TRX_EXT_VER" ]] \
    || [[ "$W_TRX_INT_VER" != "$W_TRX_EXT_VER" && -n "$W_TRX_EXT_VER" ]]
    then
        try_remove_file "${PORT_WINE_TMP_PATH}/winetricks"
        if try_download "${W_TRX_URL}" "${PORT_WINE_TMP_PATH}/winetricks" no_mirror ; then
            W_TRX_INT_VER="$(grep -i 'WINETRICKS_VERSION=' "${PORT_WINE_TMP_PATH}/winetricks" | sed 's/WINETRICKS_VERSION=//')"
            print_info "Winetricks version in port has been updated (${W_TRX_INT_VER})"
            chmod u+x "${PORT_WINE_TMP_PATH}/winetricks"
        fi
    fi
    if  [[ -f "${PORT_WINE_TMP_PATH}/winetricks" ]] ; then
        sed -i 's/w_metadata vcrun2015 dlls \\/w_metadata !dont_use_2015! dlls \\/' "${PORT_WINE_TMP_PATH}/winetricks"
        sed -i 's/w_metadata vcrun2017 dlls \\/w_metadata !dont_use_2017! dlls \\/' "${PORT_WINE_TMP_PATH}/winetricks"
        sed -i 's/w_metadata vcrun2019 dlls \\/w_metadata !dont_use_2019! dlls \\/' "${PORT_WINE_TMP_PATH}/winetricks"
        sed -i 's/w_set_winver win2k3/w_set_winver win7/' "${PORT_WINE_TMP_PATH}/winetricks"
    fi
    return 0
}

edit_db_from_gui () {
    if [[ "${PW_DISABLED_CREATE_DB}" == "1" ]] ; then
        print_warning "Skipped edit_db_from_gui"
        return 0
    fi

    print_info "edit_db_from_gui PORTWINE_DB_FILE=$PORTWINE_DB_FILE"
    if [[ -n "$PORTWINE_DB_FILE" ]] \
    && [[ -f "$PORTWINE_DB_FILE" ]]
    then
        for mod_db in $@ ; do
            proxy_mod_db="${!mod_db}"
            if [[ $proxy_mod_db =~ (${translations[Disabled]}|${translations[Disable]}) ]] ; then
                proxy_mod_db=disabled
            elif [[ $proxy_mod_db =~ (${translations[Enabled]}|${translations[Enable]}) ]] ; then
                proxy_mod_db=enabled
            fi
            if [[ $(<"${PORTWINE_DB_FILE}") =~ export\ ${mod_db}= ]]
            then sed -i "s|export ${mod_db}=.*|export ${mod_db}=\"$proxy_mod_db\"|g" "${PORTWINE_DB_FILE}"
            else echo "export ${mod_db}=\"$proxy_mod_db\"" >> "${PORTWINE_DB_FILE}"
            fi            
        done
    fi
    return 0
}

edit_user_conf_from_gui () {
    for mod_db in $@ ; do
        proxy_mod_db="${!mod_db}"
        if [[ $proxy_mod_db =~ (${translations[Disabled]}|${translations[Disable]}) ]] ; then
            proxy_mod_db=disabled
        elif [[ $proxy_mod_db =~ (${translations[Enabled]}|${translations[Enable]}) ]] ; then
            proxy_mod_db=enabled
        fi
        if ! grep "export ${mod_db}=" "${USER_CONF}" &>/dev/null
        then echo "export ${mod_db}=\"$proxy_mod_db\"" >> "${USER_CONF}"
        elif grep "export ${mod_db}=" "${USER_CONF}" | grep -v "#" &>/dev/null
        then
            if [[ "$(grep "export ${mod_db}=" "${USER_CONF}" | grep -v "#")" != "export ${mod_db}=\"$proxy_mod_db\"" ]]
            then sed -ri "s/^export ${mod_db}=.*/export ${mod_db}=\"$proxy_mod_db\"/" "${USER_CONF}"
            fi
        elif [[ "$(grep "export ${mod_db}=" "${USER_CONF}")" != "export ${mod_db}=$proxy_mod_db" ]]
        then sed -ri "s/.*export ${mod_db}=.*/export ${mod_db}=\"$proxy_mod_db\"/g" "${USER_CONF}"
        fi
    done
    return 0
}

pw_create_gui_png () {
    basename_portwine_exe="$(basename "${portwine_exe}")"
    if echo "$basename_portwine_exe" | grep -ie 'setup\|install\|\.msi$' &>/dev/null ; then
        export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/setup.png"
        export name_desktop_png="setup"
        return 0
    elif echo "$basename_portwine_exe" | grep -ie '\.reg$' &>/dev/null ; then
        export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/reg.png"
        export name_desktop_png="reg"
        return 0
    elif echo "$basename_portwine_exe"| grep -ie '\.bat$' &>/dev/null ; then
        export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/bat.png"
        export name_desktop_png="bat"
        return 0
    fi
    if [[ -z "$PORTPROTON_NAME" ]] \
    || [[ -z "$FILE_DESCRIPTION" ]] \
    || [[ -z "$ENTRY_POINT" ]] \
    || [[ "$PW_NO_RESTART_PPDB" == "1" ]]
    then
        if [[ -n "${PORTWINE_CREATE_SHORTCUT_NAME}" ]] ; then
            PORTPROTON_NAME="${PORTWINE_CREATE_SHORTCUT_NAME}"
        else
            if command -v exiftool &>/dev/null ; then
                if timeout 3 exiftool "$portwine_exe" &> "${PW_TMPFS_PATH}/exiftool.tmp" ; then
                    PW_PRODUCTNAME=$(sed -n 's/^Product Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
                    FILE_DESCRIPTION=$(sed -n 's/^File Description\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
                    ENTRY_POINT=$(sed -n 's/^Entry Point\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
                else
                    print_error "exiftool - broken!"
                fi
            else
                print_warning "use portable exiftool"
                env PERL5LIB="${PW_PLUGINS_PATH}/portable/lib/perl5" "${PW_PLUGINS_PATH}/portable/bin/exiftool" "$portwine_exe" &> "${PW_TMPFS_PATH}/exiftool.tmp"
                PW_PRODUCTNAME=$(sed -n 's/^Product Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
                FILE_DESCRIPTION=$(sed -n 's/^File Description\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
                ENTRY_POINT=$(sed -n 's/^Entry Point\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
            fi

            if [[ "$PW_PRODUCTNAME" =~ (Launcher|RU) ]]
            then
                PW_PRODUCTNAME="${PW_PRODUCTNAME//(Launcher|RU)/}"
            fi

            if [[ -n "$PW_PRODUCTNAME" ]] \
            && [[ ! "$PW_PRODUCTNAME" =~ Bootstrap ]]
            then
                PORTPROTON_NAME="$PW_PRODUCTNAME"
            else
                PORTPROTON_NAME="$(basename "${portwine_exe%.[Ee][Xx][Ee]}")"
            fi
        fi

        PORTPROTON_NAME="$(echo "${PORTPROTON_NAME}" | sed "s/\`//g" | sed "s/\"//g" | sed "s/'//g" | sed "s/\!//g")"
        export PORTPROTON_NAME
        edit_db_from_gui PORTPROTON_NAME FILE_DESCRIPTION ENTRY_POINT
    fi

    resize_png "$portwine_exe" "${PORTPROTON_NAME}" "128"

    PORTPROTON_NAME_PNG="${PORTPROTON_NAME// /_}"
    if [[ -z "${PW_ICON_FOR_YAD}" ]] ; then
        if [[ -n "$(file "${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png" | grep "${PW_RESIZE_TO} x ${PW_RESIZE_TO}")" ]] ; then
            export PW_ICON_FOR_YAD="${PORT_WINE_PATH}/data/img/${PORTPROTON_NAME_PNG}.png"
        else
            export PW_ICON_FOR_YAD="${PW_GUI_ICON_PATH}/port_proton.png"
        fi
    fi
}

pw_find_exe () {
    unset PW_FIND_TIME
    case "$1" in
        "news") PW_FIND_TIME="-cmin -180" ;;
    esac

    PW_EXCLUDE_EXE_FIND='(windows|explorer|anticheat|programdata|redist|setup|.ppdb|unin|error|crash|handler|install|/jre/|steam|uploader|eac|netframe)'
    PW_PATH_FOR_FIND="${PORT_WINE_PATH}/data/prefixes/"

    pw_start_progress_bar_block "${translations[Searching for .exe files... Please wait.]}"
    find "${PW_PATH_FOR_FIND}" -type f -name '*.exe' ${PW_FIND_TIME} | grep -viE ${PW_EXCLUDE_EXE_FIND} | \
    awk -F"/prefixes/" '{print $2}' > "${PW_TMPFS_PATH}/tmp_yad_find_exe"
    pw_stop_progress_bar

    unset FIND_TO_GUI
    while read line; do
        FIND_TO_GUI+="${line}%"
    done < "${PW_TMPFS_PATH}/tmp_yad_find_exe"

    IFS="%"
    PW_SET_FIND_EXE="$("${pw_yad}" --height="500" --width="800" --list --text-align=center \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "${translations[Create shortcut for...]}" \
    --text="\n${translations[Choose the .exe file for which you need to create a shortcut and click OK.\\n]}" \
    --column="${translations[Choose path to .exe file:]}" ${FIND_TO_GUI} \
    --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1 \
    --button="${translations[OK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null)"
    YAD_STATUS="$?"

    IFS="$orig_IFS"
    if [[ "$YAD_STATUS" == "1" || "$YAD_STATUS" == "252" ]] ; then
        print_info "Restarting..."
        restart_pp
    fi

    if [[ -n "${PW_SET_FIND_EXE}" ]] ; then
        portwine_exe="${PW_PATH_FOR_FIND}$(echo "${PW_SET_FIND_EXE}" | awk -F'|' '{print $1}')"
        portwine_create_shortcut
    fi
}

pw_create_unique_exe () {
    BASEDIR_GAME="$(dirname "$portwine_exe")"
    if [[ -d "$BASEDIR_GAME" ]] ; then
        pushd "$BASEDIR_GAME" || fatal
        BASENAME_GAME_EXE="$(basename "$portwine_exe")"
        if [[ -n "$1" ]] ; then
            BASENAME_GAME="$(basename "$1" .exe).exe"
            ln -sf "$BASENAME_GAME_EXE" "$BASENAME_GAME"
            export portwine_exe="$BASEDIR_GAME/$BASENAME_GAME"
        elif [[ -n "$PORTWINE_CREATE_SHORTCUT_NAME" ]] ; then
            ln -sf "$BASENAME_GAME_EXE" "$PORTWINE_CREATE_SHORTCUT_NAME.exe"
            export portwine_exe="$BASEDIR_GAME/$PORTWINE_CREATE_SHORTCUT_NAME.exe"
        else
            print_warning "There are no arguments for creating a symbolic link! Skip it..."
        fi
        popd || fatal
    fi
}

start_portwine () {
    pw_skip_get_info
    if [[ "${PW_LOCALE_SELECT}" != "disabled" ]] && [[ -n "${PW_LOCALE_SELECT}" ]] ; then
        export LC_ALL="${PW_LOCALE_SELECT}"
        if [[ "${PW_USE_RUNTIME}" == "1" ]] && [[ "${HOST_LC_ALL}" != "${LC_ALL}" ]] ; then
            export HOST_LC_ALL="${LC_ALL}"
        fi
    else
        export PW_LOCALE_SELECT="disabled"
    fi

    WINEPREFIX="$(readlink -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}")"
    export WINEPREFIX

    pw_get_pfx () {
        case "${PW_PREFIX_NAME}" in
            PROGRAMS) local FILE_NAME_PFX="progpfx${PROGPFX_VER}" ;;
              DOTNET) local FILE_NAME_PFX="dotpfx${DOTPFX_VER}" ;;
                   *) return 0 ;;
        esac

        local PFX_URL="github.com/Castro-Fidel/PortWINE/releases/download/${FILE_NAME_PFX}/${FILE_NAME_PFX}.tar.xz"
        local PFX_TMP="${PORT_WINE_PATH}/data/tmp/pfx"
        create_new_dir "${PFX_TMP}"

        # TODO: drop this fix legacy file .dotnet later
        if [[ -f "${WINEPREFIX}/.dotnet${DOTPFX_VER}" ]] ; then
            touch "${WINEPREFIX}/.${FILE_NAME_PFX}"
            try_remove_file "${WINEPREFIX}/.dotnet${DOTPFX_VER}"
        fi

        if [[ ! -f "${WINEPREFIX}/.${FILE_NAME_PFX}" ]] ; then
            print_info "Download and install ${FILE_NAME_PFX} pfx..."
            if [[ ! -f "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz" ]] ; then
                if try_download "${PFX_URL}" "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz" ; then
                    if unpack "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz" "${PORT_WINE_PATH}/data/prefixes/"
                    then touch "${WINEPREFIX}/.${FILE_NAME_PFX}"
                    fi
                else
                    try_remove_file "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz"
                    yad_error_download && exit 1
                fi
            else
                if unpack "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz" "${PORT_WINE_PATH}/data/prefixes/"
                then touch "${WINEPREFIX}/.${FILE_NAME_PFX}"
                else
                    try_remove_file "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz"
                    yad_error_download && exit 1 
                fi
            fi
        fi
        return 0
    }

    pw_get_pfx

    var_winedlloverride_update "${PW_MUST_WINEDLLOVERRIDES}"
    pw_list_install_dll_in_prefix
    if [[ "${PW_WINE_USE}" != "USE_SYSTEM_WINE" ]]
    then pw_check_and_download_wine "${PW_WINE_USE}"
    fi
    init_wine_ver

    if [[ "$PW_USE_OBS_VKCAPTURE" == "1" ]] ; then
        export OBS_VKCAPTURE="1"
        export PW_USE_SYSTEM_VK_LAYERS="1"
        print_warning "System mangohud, vkBasalt, obs-vk capture and other applications using vulkan layers are forcibly used."
    fi

    pw_init_runtime

    if [[ "${PW_USE_GSTREAMER}" == "1" ]] ; then
        if [[ -d "${WINEDIR}/lib64/gstreamer-1.0" ]] \
        && ! check_flatpak
        then
            export GST_PLUGIN_SYSTEM_PATH_1_0="${WINEDIR}/lib64/gstreamer-1.0:${WINEDIR}/lib/gstreamer-1.0"
        fi
        export GST_GL_WINDOW="surfaceless"
        create_new_dir "${PORT_WINE_TMP_PATH}"/gstreamer_tmp/
        export WINE_GST_REGISTRY_DIR="${PORT_WINE_TMP_PATH}"/gstreamer_tmp/
        export MEDIACONV_AUDIO_DUMP_FILE="${PORT_WINE_TMP_PATH}"/gstreamer_tmp/audiov2.foz
        export MEDIACONV_AUDIO_TRANSCODED_FILE="${PORT_WINE_TMP_PATH}"/gstreamer_tmp/transcoded_audio.foz
        export MEDIACONV_VIDEO_DUMP_FILE="${PORT_WINE_TMP_PATH}"/gstreamer_tmp/video.foz
        export MEDIACONV_VIDEO_TRANSCODED_FILE="${PORT_WINE_TMP_PATH}"/gstreamer_tmp/transcoded_video.foz
    else
        var_winedlloverride_update "winegstreamer="
    fi

    check_variables VKD3D_DEBUG none
    check_variables DXVK_LOG_LEVEL none
    check_variables VK_LOADER_DEBUG none
    check_variables VKBASALT_LOG_LEVEL none
    check_variables DXVK_NVAPI_LOG_LEVEL none
    if [[ "${PW_LOG}" == 1 ]] \
    || [[ -n "$PW_DEBUG" ]]
    then
        export WINEDEBUG="fixme-all,err+loaddll,err+dll,err+file,err+reg"
        export WINE_MONO_TRACE="E:System.NotImplementedException"
        export VKBASALT_LOG_LEVEL="error"
    else
        export WINEDEBUG="-all"
        unset WINE_MONO_TRACE
    fi

    pw_wineboot () {
        LIST_NATIVE_WINE_DLL_LINKS="winevulkan ir50_32 amd_ags_x64 wined3d vulkan-1"
        for change_wine_dll in $LIST_NATIVE_WINE_DLL_LINKS ; do
            try_force_link_file "${WINEDIR}/lib64/wine/x86_64-windows/${change_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/system32/${change_wine_dll}.dll"
            try_force_link_file "${WINEDIR}/lib/wine/i386-windows/${change_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${change_wine_dll}.dll"
        done

        LIST_NATIVE_WINE_DLL_COPY="atl100 ntdll shell32"
        for change_wine_dll in $LIST_NATIVE_WINE_DLL_COPY ; do
            try_copy_file "${WINEDIR}/lib64/wine/x86_64-windows/${change_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/system32/${change_wine_dll}.dll"
            try_copy_file "${WINEDIR}/lib/wine/i386-windows/${change_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${change_wine_dll}.dll"
        done

        print_info "Used wineboot $@ for prefix: ${PW_PREFIX_NAME}"
        ${pw_runtime} GST_PLUGIN_SYSTEM_PATH_1_0="" LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" \
        WINEDEBUG="fixme-all,err+loaddll,err+dll,err+file,err+reg" \
        "${WINELOADER}" wineboot $@ &>>"${PW_TMPFS_PATH}/update_pfx_log"
        wait_wineserver
        print_info "The prefix has been updated."
    }

    if [[ ! -d "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/drive_c/windows ]] \
    || [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/userdef.reg ]] \
    || [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/system.reg ]] \
    || [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"/user.reg ]]
    then
        pw_clear_pfx
        check_dirs_and_files_in_pfx
        if [[ "${PW_PREFIX_NAME}" == "DEFAULT" ]] ; then
            pw_update_pfx_cover_gui
            unpack "${PW_PLUGINS_PATH}/default_pfx.tar.xz" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/" silent
            pw_wineboot -r
        elif [[ "${PW_CHECK_AUTOINSTALL}" == 1 ]] \
        && [[ "${DISABLE_CP_DEFPFX}" != 1 ]] ; then
            pw_update_pfx_cover_gui
            unpack "${PW_PLUGINS_PATH}/default_pfx.tar.xz" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/" silent
            pw_wineboot -r
        elif [[ "${PW_CHECK_AUTOINSTALL}" == 1 ]] \
        && [[ "${DISABLE_CP_DEFPFX}" == 1 ]] ; then
            pw_update_pfx_cover_gui
            unpack "${PW_PLUGINS_PATH}/blank_pfx.tar.xz" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/" silent
            pw_wineboot -i
        elif yad_question "${translations[Do you want to installing recommended libraries in the new prefix:]} ${PW_PREFIX_NAME}" ; then
            pw_update_pfx_cover_gui
            unpack "${PW_PLUGINS_PATH}/default_pfx.tar.xz" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/" silent
            pw_wineboot -r
        else
            pw_update_pfx_cover_gui
            unpack "${PW_PLUGINS_PATH}/blank_pfx.tar.xz" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/" silent
            pw_wineboot -i
        fi
    else
        check_dirs_and_files_in_pfx
        if [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.wine_ver" ]] \
        || [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c/windows/system32/shell32.dll" ]] \
        || ! grep "${PW_WINE_USE}" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.wine_ver" &>/dev/null
        then
            pw_update_pfx_cover_gui
            pw_wineboot -r
        fi
    fi
    rm -f "${PORT_WINE_PATH}"/data/prefixes/*/drive_c/users/*/Desktop/*.lnk

    echo "${PW_WINE_USE}" > "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.wine_ver"

    ULIMIT_HN=$(ulimit -Hn)
    if [[ $ULIMIT_HN -lt 524288 ]] ; then
        print_warning "ESYNC dont work! (ulimit -Hn $ULIMIT_HN < 524288)"
        export WINEESYNC="0"
    elif [[ "${PW_NO_ESYNC}" == 1 ]]
    then export WINEESYNC="0"
    else export WINEESYNC="1"
    fi

    if [[ "${PW_NO_FSYNC}" == 1 ]] ; then
        export WINEFSYNC="0"
        export WINEFSYNC_FUTEX2="0"
    else
        export WINEFSYNC="1"
        export WINEFSYNC_FUTEX2="1"
        export WINEFSYNC_SPINCOUNT=100
    fi

    if [[ "${PW_FORCE_LARGE_ADDRESS_AWARE}" == 1 ]]
    then export WINE_LARGE_ADDRESS_AWARE="1"
    else export WINE_LARGE_ADDRESS_AWARE="0"
    fi

    if [[ "${PW_OLD_GL_STRING}" == 1 ]] ; then
        export MESA_EXTENSION_MAX_YEAR="2003" #mesa override
        export __GL_ExtensionStringVersion="17700" #nvidia override
    fi

    if [[ "${PW_NO_WRITE_WATCH}" == 1 ]] ; then
        export WINE_DISABLE_WRITE_WATCH="1"
    fi

    if [[ "${PW_VULKAN_NO_ASYNC}" == 1 ]] ; then
        export RADV_DEBUG+="llvm "
        var_vkd3d_config_update single_queue
    fi

    enabled_fake_nvidia_videocard ()
    {
        case "$1" in
            old)
                sed -i /'dxgi.customDeviceDesc =/c # dxgi.customDeviceDesc =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customDeviceId =/c dxgi.customDeviceId = 222F' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customVendorId =/c dxgi.customVendorId = 10de' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideAmdGpu =/c # dxgi.hideAmdGpu =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideNvidiaGpu =/c # dxgi.hideNvidiaGpu =' "${DXVK_CONFIG_FILE}"
                unset WINE_HIDE_NVIDIA_GPU WINE_HIDE_AMD_GPU
                unset DXVK_NVAPI_DRIVER_VERSION DXVK_NVAPI_ALLOW_OTHER_DRIVERS
                ;;

            new)
                sed -i /'dxgi.customDeviceDesc =/c dxgi.customDeviceDesc = "NVIDIA GeForce RTX 4090"' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customDeviceId =/c dxgi.customDeviceId = 2684' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customVendorId =/c dxgi.customVendorId = 10de' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideAmdGpu =/c dxgi.hideAmdGpu = True' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideNvidiaGpu =/c dxgi.hideNvidiaGpu = False' "${DXVK_CONFIG_FILE}"
                export WINE_HIDE_NVIDIA_GPU="0"
                export WINE_HIDE_AMD_GPU="1"
                export DXVK_NVAPI_DRIVER_VERSION="53713"
                export DXVK_NVAPI_ALLOW_OTHER_DRIVERS="1"
                export WINEHAGS="1"
                ;;
                
            *)
                sed -i /'dxgi.customDeviceDesc =/c # dxgi.customDeviceDesc =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customDeviceId =/c # dxgi.customDeviceId =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.customVendorId =/c # dxgi.customVendorId =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideAmdGpu =/c # dxgi.hideAmdGpu =' "${DXVK_CONFIG_FILE}"
                sed -i /'dxgi.hideNvidiaGpu =/c # dxgi.hideNvidiaGpu =' "${DXVK_CONFIG_FILE}"
                unset WINE_HIDE_NVIDIA_GPU WINE_HIDE_AMD_GPU
                unset DXVK_NVAPI_DRIVER_VERSION DXVK_NVAPI_ALLOW_OTHER_DRIVERS
                ;;
        esac
    }

    # NVAPI, DLSS AND FAKE DLSS
    if [[ "${PW_USE_FAKE_DLSS_3}" == "1" ]] ; then
        FAKE_DLSS_3_FILES="amd_fidelityfx_dx12.dll amd_fidelityfx_vk.dll dlss-enabler.dll dlss-enabler-upscaler.dll 
        dlssg_to_fsr3_amd_is_better-3.0.dll dlssg_to_fsr3_amd_is_better.dll libxess.dll nvapi64-proxy.dll winmm.dll
        _nvngx.dll nvngx-wrapper.dll nvngx.ini"
        DXVK_ENABLE_NVAPI="1"
        for cp_fdlls3 in $FAKE_DLSS_3_FILES ; do
            try_copy_file_with_checksums "${PW_PLUGINS_PATH}/fake_dlss_3/$cp_fdlls3" "${WINEPREFIX}/drive_c/windows/system32/$cp_fdlls3"
            [[ "$cp_fdlls3" == *.dll ]] && var_winedlloverride_update "${cp_fdlls3//.dll}=n"
        done
        try_remove_file "${WINEPREFIX}/drive_c/windows/system32/nvngx.dll"
        # try_copy_file_with_checksums "${PW_PLUGINS_PATH}/fake_dlss/${PW_FAKE_DLSS_VER}/nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/nvngx.dll"
        enabled_fake_nvidia_videocard new
    elif [[ "${PW_USE_FAKE_DLSS}" == "1" ]] ; then
        DXVK_ENABLE_NVAPI="1"
        try_remove_file "${WINEPREFIX}/drive_c/windows/system32/_nvngx.dll"
        try_copy_file_with_checksums "${PW_PLUGINS_PATH}/fake_dlss/${PW_FAKE_DLSS_VER}/nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/nvngx.dll"
        try_copy_file_with_checksums "${PW_PLUGINS_PATH}/fake_dlss/${PW_FAKE_DLSS_VER}/nvngx.ini" "${WINEPREFIX}/drive_c/windows/system32/nvngx.ini"
        enabled_fake_nvidia_videocard old
        var_winedlloverride_update "nvapi,nvapi64,nvngx=n;_nvngx=;nvcuda=b"
    elif [[ "${PW_USE_NVAPI_AND_DLSS}" == 1 ]] ; then
        DXVK_ENABLE_NVAPI="1"
        try_remove_file "${WINEPREFIX}/drive_c/windows/system32/nvngx.ini"
        FIND_NVNGX="$(dirname $(find /usr/* -type f -name "nvngx.dll" 2>/dev/null | head -n 1 | awk '{print $1}'))"
        if [[ -n "$FIND_NVNGX" ]] ; then
            try_copy_file_with_checksums "${FIND_NVNGX}/nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/nvngx.dll"
            try_copy_file_with_checksums "${FIND_NVNGX}/_nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/_nvngx.dll"
        else
            try_copy_file_with_checksums "${PW_PLUGINS_PATH}/nvngx/nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/nvngx.dll"
            try_copy_file_with_checksums "${PW_PLUGINS_PATH}/nvngx/_nvngx.dll" "${WINEPREFIX}/drive_c/windows/system32/_nvngx.dll"
        fi
        enabled_fake_nvidia_videocard 0
        var_winedlloverride_update "nvngx,_nvngx,nvapi,nvapi64=n;nvcuda=b"
    else
        DXVK_ENABLE_NVAPI="0"
        for rm_dll in "nvngx.ini" "nvngx.dll" "_nvngx.dll" ; do
            try_remove_file "${WINEPREFIX}/drive_c/windows/system32/$rm_dll"
        done
        enabled_fake_nvidia_videocard 0
        var_winedlloverride_update "nvngx,_nvngx="
    fi
    export DXVK_ENABLE_NVAPI

    if [[ "${PW_HEAP_DELAY_FREE}" == 1 ]]
    then export WINE_HEAP_DELAY_FREE="1"
    else export WINE_HEAP_DELAY_FREE="0"
    fi

    if [[ "${PW_WINE_ALLOW_XIM}" == 1 ]]
    then export WINE_ALLOW_XIM="1"
    else export WINE_ALLOW_XIM="0"
    fi

    if [[ "${PW_FIX_VIDEO_IN_GAME}" == 1 ]]
    then export WINE_DO_NOT_CREATE_DXGI_DEVICE_MANAGER="1"
    else export WINE_DO_NOT_CREATE_DXGI_DEVICE_MANAGER="0"
    fi

    [[ "${PW_MANGOHUD_USER_CONF}" == 1 ]] && unset MANGOHUD_CONFIG
    [[ "${PW_VKBASALT_USER_CONF}" == 1 ]] && unset PW_VKBASALT_EFFECTS PW_VKBASALT_FFX_CAS

    if [[ "${PW_USE_DXR11}" == 1 ]] \
    || [[ "${PW_USE_DXR10}" == 1 ]] \
    || [[ "${PW_USE_RAY_TRACING}" == 1 ]]
    then
        var_vkd3d_config_update dxr
        var_radv_perftest_config_update rt
    else
        var_vkd3d_config_update nodxr
    fi

    if [[ "${PW_GPU_USE}" != "disabled" ]] ; then
        export DXVK_FILTER_DEVICE_NAME="${PW_GPU_USE}"
        export VKD3D_FILTER_DEVICE_NAME="${PW_GPU_USE}"
    fi

    export int_xneur=0
    if command -v xneur &>/dev/null \
    && pgrep xneur
    then
        killall xneur
        export int_xneur=1
    fi

    if check_gamescope_session ; then
        export PW_GAMEMODERUN_SLR=""
    elif [[ "$PW_USE_GAMEMODE" = "1" ]] \
    && [[ -n "$DBUS_SESSION_BUS_ADDRESS" ]]
    then
        if command -v systemctl &>/dev/null \
        && (systemctl is-active --quiet ananicy.service \
        || systemctl is-active --quiet ananicy-cpp.service)
        then
            export GAMEMODERUN=0
            export PW_GAMEMODERUN_SLR=""
            if command -v powerprofilesctl &>/dev/null ; then
                if powerprofilesctl list | grep -q 'performance:' ; then
                    export PW_POWERPROFILECTL_SLR="powerprofilesctl launch -p performance --"
                    print_info "Gamemode replaced by powerprofilectl to avoid conflict with ananicy."
                else
                    export PW_POWERPROFILECTL_SLR=""
                fi
            fi
        elif check_flatpak ; then
            export GAMEMODERUN=1
            PW_GAMEMODERUN_SLR="gamemoderun"
            print_info "Gamemode will be launched."
        elif command -v gamemoded &>/dev/null ; then
            export GAMEMODERUN=1
            PW_GAMEMODERUN_SLR="gamemoderun"
            systemctl enable --now --user gamemoded &>/dev/null
            print_info "Gamemode will be launched."
        elif [[ "$PW_USE_RUNTIME" == 1 ]] ; then
            export GAMEMODERUN=1
            if ! pidof gamemoded &>/dev/null ; then
                GAMEMODEAUTO_NAME="libgamemodeauto.so.0"
                if [[ -n "${PW_LD_PRELOAD}" ]]; then
                    export PW_LD_PRELOAD="${PW_LD_PRELOAD}:${GAMEMODEAUTO_NAME}"
                else
                    export PW_LD_PRELOAD="${GAMEMODEAUTO_NAME}"
                fi

                env LD_LIBRARY_PATH="${PW_PLUGINS_PATH}/portable/lib/lib64:${PW_PLUGINS_PATH}/portable/lib/lib32" \
                    "${PW_PLUGINS_PATH}/portable/bin/gamemoded" &>/dev/null &

                print_info "Gamemode will be launched."
                sleep 0.1
            fi
        else
            export GAMEMODERUN=0
            export PW_GAMEMODERUN_SLR=""
            print_info "Gamemode is not installed or disabled in vars script or db file: PW_USE_GAMEMODE=$PW_USE_GAMEMODE"
        fi
    else
        export GAMEMODERUN=0
        export PW_GAMEMODERUN_SLR=""
    fi

    if command -v systemd-inhibit &>/dev/null \
    && [[ "$GAMEMODERUN" != "1" ]]
    then
        PW_INHIBIT_SLR="systemd-inhibit --mode=block --who=ru.linux_gaming.PortProton --why=${PW_NAME_DESKTOP_PROXY// /_}"
        print_info "Screensaver will be inhibit"
    fi
    pw_other_fixes

    # enabled BattleEye_Runtime and EasyAntiCheat_Runtime
    if [[ "${PW_USE_EAC_AND_BE}" == 1 ]] ; then
        export PROTON_BATTLEYE_RUNTIME="${PW_PLUGINS_PATH}/BattlEye_Runtime"
        export PROTON_EAC_RUNTIME="${PW_PLUGINS_PATH}/EasyAntiCheat_Runtime"
        var_winedlloverride_update "beclient,beclient_x64=b,n"
    else
        unset PROTON_BATTLEYE_RUNTIME PROTON_EAC_RUNTIME
    fi

    if [[ "${PW_REDUCE_PULSE_LATENCY}" == 1 ]] ; then
        export PULSE_LATENCY_MSEC=60
        # export PIPEWIRE_LATENCY=128/48000
    else
        unset PULSE_LATENCY_MSEC
    fi

    if [[ "$PW_USE_US_LAYOUT" == "1" ]] \
    && ! check_wayland_session \
    && command -v setxkbmap &>/dev/null
    then
        setxkbmap -model pc101 us -print | xkbcomp - $DISPLAY &>/dev/null
    else
        export PW_USE_US_LAYOUT="0"
    fi

    D3D_EXTRAS_LIBS="d3dcompiler_33 d3dcompiler_34 d3dcompiler_35 d3dcompiler_36 d3dcompiler_37
    d3dcompiler_38 d3dcompiler_39 d3dcompiler_40 d3dcompiler_41 d3dcompiler_42 d3dcompiler_43 d3dcompiler_46
    d3dcompiler_47 d3dx10_33 d3dx10_34 d3dx10_35 d3dx10_36 d3dx10_37 d3dx10_38 d3dx10_39 d3dx10_40 d3dx10_41
    d3dx10_42 d3dx10_43 d3dx10 d3dx11_42 d3dx11_43 d3dx9_24 d3dx9_25 d3dx9_26 d3dx9_27 d3dx9_28 d3dx9_29 d3dx9_30
    d3dx9_31 d3dx9_32 d3dx9_33 d3dx9_34 d3dx9_35 d3dx9_36 d3dx9_37 d3dx9_38 d3dx9_39 d3dx9_40 d3dx9_41 d3dx9_42 d3dx9_43"
    if [[ "${PW_USE_D3D_EXTRAS}" == 1 ]] ; then
        if [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ]] \
        || [[ -z "$(grep d3dx9 "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log")" ]]
        then
            echo "d3dx9" >> "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
        fi
        # try link d3d extras libs
        PATH_TO_D3DEXTRAS="${PW_PLUGINS_PATH}/d3d_extras"
        for d3d_extras_from_plugins in $D3D_EXTRAS_LIBS ; do
            try_force_link_file "${PATH_TO_D3DEXTRAS}/x64/${d3d_extras_from_plugins}.dll" "${WINEPREFIX}/drive_c/windows/system32/${d3d_extras_from_plugins}.dll"
            try_force_link_file "${PATH_TO_D3DEXTRAS}/x32/${d3d_extras_from_plugins}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${d3d_extras_from_plugins}.dll"
            var_winedlloverride_update "${d3d_extras_from_plugins}=n"
            if [[ -z "$(grep "${d3d_extras_from_plugins}" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log")" ]] ; then
                echo "${d3d_extras_from_plugins}" >> "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
            fi
        done
    else
        for d3d_extras_from_plugins in $D3D_EXTRAS_LIBS ; do
            try_force_link_file "${WINEDIR}/lib/wine/i386-windows/${d3d_extras_from_plugins}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${d3d_extras_from_plugins}.dll"
            try_force_link_file "${WINEDIR}/lib64/wine/x86_64-windows/${d3d_extras_from_plugins}.dll" "${WINEPREFIX}/drive_c/windows/system32/${d3d_extras_from_plugins}.dll"
        done
    fi

    # fix physx
    PHYSX_PATH="${WINEPREFIX}/drive_c/Program Files (x86)/NVIDIA Corporation/PhysX/Common"
    for physx_dll in PhysXDevice PhysXLoader PhysXUpdateLoader ; do
        try_force_link_file "${PHYSX_PATH}/${physx_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${physx_dll}.dll"
        try_force_link_file "${PHYSX_PATH}/${physx_dll}64.dll" "${WINEPREFIX}/drive_c/windows/system32/${physx_dll}64.dll"
    done
    try_force_link_file "${PHYSX_PATH}/cudart32_65.dll" "${WINEPREFIX}/drive_c/windows/syswow64/cudart32_65.dll"
    try_force_link_file "${PHYSX_PATH}/cudart64_65.dll" "${WINEPREFIX}/drive_c/windows/system32/cudart64_65.dll"

    # 3D API
    unset CP_VKD3D_FILES CP_DXVK_FILES CP_DGV2_FILES CP_WINE_FILES
    unset CP_GALLIUM_NINE_FILES PATH_TO_DXVK_FILES PATH_TO_VKD3D_FILES
    case "${PW_VULKAN_USE}" in
        0)
            # WINED3D OPENGL
            print_info "Use WINED3D OpenGL"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_VKD3D_FILES="libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12 d3d12core d3d11 d3d10core d3d10_1 d3d10 d3d9 d3d8 dxgi"
            export __GL_YIELD="NOTHING"
            export mesa_glthread="true"
            export WINE_D3D_CONFIG="renderer=gl"
            export PW_VKBASALT="0"
            ;;
        1)
            # STABLE DXVK AND VKD3D
            print_info "DXVK v.${DXVK_STABLE_VER} in use"
            print_info "VKD3D-PROTON v.${VKD3D_STABLE_VER} in use"
            PATH_TO_DXVK_FILES="${PW_VULKAN_DIR}/dxvk-${DXVK_STABLE_VER}"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_STABLE_VER}"
            CP_DXVK_FILES="d3d11 d3d10core d3d10_1 d3d10 d3d9 dxgi" # openvr_api_dxvk
            CP_VKD3D_FILES="d3d12 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12core d3d8"
            ;;
        2)
            # NEWEST DXVK AND VKD3D
            print_info "DXVK v.${DXVK_GIT_VER} in use"
            print_info "VKD3D-PROTON v.${VKD3D_GIT_VER} in use"
            PATH_TO_DXVK_FILES="${PW_VULKAN_DIR}/dxvk-${DXVK_GIT_VER}"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_DXVK_FILES="d3d11 d3d10core d3d9 d3d8 dxgi" # openvr_api_dxvk
            CP_VKD3D_FILES="d3d12 d3d12core libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d10_1 d3d10"
            ;;
        3)
            # GALLIUM NINE
            print_info "Use GALLIUM-NINE (Native DX9 on MESA drivers)"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_GALLIUM_NINE_FILES="d3d9"
            CP_VKD3D_FILES="libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12 d3d12core d3d11 d3d10core d3d10_1 d3d10 d3d8 dxgi"
            export __GL_YIELD="NOTHING"
            export mesa_glthread="true"
            export WINE_D3D_CONFIG="renderer=gl"
            export PW_VKBASALT="0"
            export PW_MANGOHUD="0"
            export PW_WINE_FULLSCREEN_FSR="0"
            ;;
        4)
            # GALLIUM ZINK
            print_info "Use GALLIUM-ZINK (OpenGL on MESA vulkan drivers)"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_VKD3D_FILES="libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12 d3d12core d3d11 d3d10core d3d10_1 d3d10 d3d9 d3d8 dxgi"
            export __GL_YIELD="NOTHING"
            export mesa_glthread="true"
            export WINE_D3D_CONFIG="renderer=gl"
            export  __GLX_VENDOR_LIBRARY_NAME="mesa"
            export MESA_LOADER_DRIVER_OVERRIDE="zink"
            export GALLIUM_DRIVER="zink"
            if ! check_wayland_session \
            && ! check_gamescope_session \
            && [[ "${PW_GAMESCOPE}" != "1" ]]
            then
                export LIBGL_KOPPER_DRI2="1"
            fi
            if [[ -d /sys/bus/pci/drivers/nouveau ]] ; then
                export NOUVEAU_USE_ZINK="1"
            fi
            ;;
        5)
            # LEGACY DXVK
            print_info "DXVK v.${DXVK_LEGACY_VER} in use"
            PATH_TO_DXVK_FILES="${PW_VULKAN_DIR}/dxvk-${DXVK_LEGACY_VER}"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_DXVK_FILES="d3d11 d3d10core d3d10_1 d3d10 d3d9 dxgi"
            CP_VKD3D_FILES="libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12 d3d12core d3d8"
            ;;
        6)
            # WINED3D VULKAN (DAMAVAND)
            print_info "Use DAMAVAND (DirectX to wined3d vulkan)"
            PATH_TO_VKD3D_FILES="${PW_VULKAN_DIR}/vkd3d-proton-${VKD3D_GIT_VER}"
            CP_VKD3D_FILES="libvkd3d-1 libvkd3d-shader-1"
            CP_WINE_FILES="d3d12 d3d12core d3d11 d3d10core d3d10_1 d3d10 d3d9 d3d8 dxgi"
            export WINE_D3D_CONFIG="renderer=vulkan"
            ;;
    esac

    # DGVOODOO2 enable:
    if [[ "${PW_DGVOODOO2}" == "1" ]] ; then
        print_info "Try create symlink DGVOODOO2 files..."
        PATH_TO_DGV2_FILES="${PW_VULKAN_DIR}/dgvoodoo2-${DGV2_VER}"
        CP_DGV2_FILES="d3d9 d3d8 d3dimm ddraw glide3x glide2x glide"
        try_copy_file "${PATH_TO_DGV2_FILES}/dgVoodoo.conf" "${WINEPREFIX}/drive_c/windows/syswow64/"
        DGV2CONF="${WINEPREFIX}/drive_c/windows/syswow64/dgVoodoo.conf"
        if [[ "${PW_DGV2_DISABLE_D3D}" == "1" ]] ; then
            rm_from_var CP_DGV2_FILES "d3d9 d3d8"
        else
            try_force_link_file "${PATH_TO_DGV2_FILES}/x64/d3d9.dll" "${WINEPREFIX}/drive_c/windows/system32/d3d9.dll"
            try_remove_file "${WINEPREFIX}/drive_c/windows/system32/dgVoodoo.conf"
            try_force_link_file "${DGV2CONF}" "${WINEPREFIX}/drive_c/windows/system32/dgVoodoo.conf"
            case "${PW_VULKAN_USE}" in
                0)
                    rm_from_var CP_WINE_FILES "d3d9 d3d8"
                    ;;
                1)
                    rm_from_var CP_DXVK_FILES "d3d9"
                    rm_from_var CP_WINE_FILES "d3d8"
                    ;;
                2)
                    rm_from_var CP_DXVK_FILES "d3d9 d3d8"
                    ;;
                3)
                    rm_from_var CP_GALLIUM_NINE_FILES "d3d9"
                    rm_from_var CP_WINE_FILES "d3d8"
                    ;;
                4)
                    rm_from_var CP_WINE_FILES "d3d9 d3d8"
                    ;;
                5)
                    rm_from_var CP_DXVK_FILES "d3d9"
                    rm_from_var CP_WINE_FILES "d3d8"
                    ;;
                6)
                    rm_from_var CP_WINE_FILES "d3d9 d3d8"
                    ;;
            esac
        fi

        if [[ "${PW_DGV2_GLIDE_NAPALM}" == "1" ]] ; then
            rm_from_var CP_DGV2_FILES "glide3x"
            try_force_link_file "${PATH_TO_DGV2_FILES}/x32/glide3x-napalm.dll" "${WINEPREFIX}/drive_c/windows/syswow64/glide3x.dll"
            var_winedlloverride_update "glide3x=n"
        fi

        for wine_dgv2_dll in $CP_DGV2_FILES ; do
            try_force_link_file "${PATH_TO_DGV2_FILES}/x32/${wine_dgv2_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${wine_dgv2_dll}.dll"
            var_winedlloverride_update "${wine_dgv2_dll}=n"
        done
        # DGVOODOO2 settings:
        if [[ "${PW_DGV2_USE_DX12}" == "1" ]] ; then
            if [[ "${PW_VULKAN_USE}" == "1" ]] || [[ "${PW_VULKAN_USE}" == "2" ]]
            then sed -i "s/OutputAPI = d3d11_fl11_0/OutputAPI = d3d12_fl12_0/" "$DGV2CONF"
            fi
        fi

        if [[ "${PW_DGV2_ENABLE_CRT}" == "1" ]] ; then
            sed -i "s/ScalingMode = unspecified/ScalingMode = stretched_ar_crt/" "$DGV2CONF"
        else
            if [[ "${PW_DGV2_RESAMPLING}" != "disabled" ]] ; then
                sed -i "s/ScalingMode = unspecified/ScalingMode = stretched_ar/" "$DGV2CONF"
            elif [[ "${PW_DGV2_DISPLAY_ROI}" != "disabled" ]] ; then
                sed -i "s/ScalingMode = unspecified/ScalingMode = stretched_ar/" "$DGV2CONF"
            elif [[ "${PW_DGV2_CURSOR_SCALE}" != "0" ]] ; then
                sed -i "s/ScalingMode = unspecified/ScalingMode = stretched_ar/" "$DGV2CONF"
            else
                sed -i "s/ScalingMode = unspecified/ScalingMode = stretched/" "$DGV2CONF"
            fi
        fi

        [[ "${PW_DGV2_FREE_MOUSE}" == "1" ]] && sed -i "s/FreeMouse = false/FreeMouse = true/" "$DGV2CONF"
        [[ "${PW_DGV2_FASTMEMORY}" == "1" ]] && sed -i "s/FastVideoMemoryAccess = false/FastVideoMemoryAccess = true/" "$DGV2CONF"
        [[ "${PW_DGV2_FORCE_VSYNC}" == "1" ]] && sed -i "s/ForceVerticalSync = false/ForceVerticalSync = true/" "$DGV2CONF"
        [[ "${PW_DGV2_DISABLE_MIPMAPPING}" == "1" ]] && sed -i "s/DisableMipmapping = false/DisableMipmapping = true/g" "$DGV2CONF"
        [[ "${PW_DGV2_GLIDE_GAMMA_RAMP}" != "1" ]] && sed -i "s/EnableGlideGammaRamp = true/EnableGlideGammaRamp = false/" "$DGV2CONF"
        [[ "${PW_DGV2_BLIT_STRETCH}" == "1" ]] && sed -i "s/BilinearBlitStretch = false/BilinearBlitStretch = true/" "$DGV2CONF"
        [[ "${PW_DGV2_PHONG_SHADING}" == "1" ]] && sed -i "s/PhongShadingWhenPossible = false/PhongShadingWhenPossible = true/" "$DGV2CONF"
        [[ "${PW_DGV2_16_BIT_DEPTH_BUFFER}" == "1" ]] && sed -i "s/16BitDepthBuffer = false/16BitDepthBuffer = true/" "$DGV2CONF"
        [[ "${PW_DGV2_3DFX_SPLASH_SCREEN}" == "1" ]] && sed -i "s/3DfxSplashScreen = false/3DfxSplashScreen = true/" "$DGV2CONF"
        [[ "${PW_DGV2_3DFX_WATERMARK}" == "1" ]] && sed -i "s/3DfxWatermark = false/3DfxWatermark = true/" "$DGV2CONF"
        [[ "${PW_DGV2_FILTER_POINT_SAMPLED}" == "1" ]] && sed -i "s/KeepFilterIfPointSampled = false/KeepFilterIfPointSampled = true/" "$DGV2CONF"
        [[ "${PW_DGV2_DGVOODOO_WATERMARK}" == "1" ]] && sed -i "s/dgVoodooWatermark = false/dgVoodooWatermark = true/" "$DGV2CONF"
        [[ "${PW_DGV2_EMULATING_PCI_ACCESS}" == "1" ]] && sed -i "s/ForceEmulatingTruePCIAccess = false/ForceEmulatingTruePCIAccess = true/" "$DGV2CONF"
        [[ "${PW_DGV2_INACTIVE_APP_STATE}" == "1" ]] && sed -i "s/EnableInactiveAppState = false/EnableInactiveAppState = true/" "$DGV2CONF"
        [[ "${PW_DGV2_DISPLAY_ROI}" != "disabled" ]] && sed -i "s/DisplayROI =/DisplayROI = ${PW_DGV2_DISPLAY_ROI}, pos:centered/" "$DGV2CONF"
        [[ "${PW_DGV2_FPS_LIMIT}" != "disabled" ]] && sed -i "s/FPSLimit = 0/FPSLimit = ${PW_DGV2_FPS_LIMIT}/" "$DGV2CONF"
        [[ "${PW_DGV2_BIT_DEPTH}" != "disabled" ]] && sed -i "s/DesktopBitDepth =/DesktopBitDepth = ${PW_DGV2_BIT_DEPTH}/" "$DGV2CONF"
        [[ "${PW_DGV2_CURSOR_SCALE}" != "0" ]] && sed -i "s/CursorScaleFactor = 0/CursorScaleFactor = ${PW_DGV2_CURSOR_SCALE}/" "$DGV2CONF"
        [[ "${PW_DGV2_BRIGHTNESS}" != "100" ]] && sed -i "s/Brightness = 100/Brightness = ${PW_DGV2_BRIGHTNESS}/" "$DGV2CONF"
        [[ "${PW_DGV2_COLOR}" != "100" ]] && sed -i "s/Color = 100/Color = ${PW_DGV2_COLOR}/" "$DGV2CONF"
        [[ "${PW_DGV2_CONTRAST}" != "100" ]] && sed -i "s/Contrast = 100/Contrast = ${PW_DGV2_CONTRAST}/" "$DGV2CONF"

        if [[ "${PW_DGV2_FILTERING}" != "disabled" ]] ; then
            case "$PW_DGV2_FILTERING" in
                "Point sampled") sed -i "s/\<Filtering = appdriven\>/Filtering = pointsampled/" "$DGV2CONF" ;;
                Bilinear) sed -i "s/\<Filtering = appdriven\>/Filtering = bilinear/" "$DGV2CONF" ;;
                "Linear mip") sed -i "s/\<Filtering = appdriven\>/Filtering = linearmip/" "$DGV2CONF" ;;
                Trilinear) sed -i "s/\<Filtering = appdriven\>/Filtering = trilinear/" "$DGV2CONF" ;;
                "Anisotropic 2x") sed -i "s/\<Filtering = appdriven\>/Filtering = 2/" "$DGV2CONF" ;;
                "Anisotropic 4x") sed -i "s/\<Filtering = appdriven\>/Filtering = 4/" "$DGV2CONF" ;;
                "Anisotropic 8x") sed -i "s/\<Filtering = appdriven\>/Filtering = 8/" "$DGV2CONF" ;;
                "Anisotropic 16x") sed -i "s/\<Filtering = appdriven\>/Filtering = 16/" "$DGV2CONF" ;;
            esac
            case "$PW_DGV2_FILTERING" in
                "Point sampled")
                    sed -i "s/TMUFiltering = appdriven/TMUFiltering = pointsampled/" "$DGV2CONF" ;;
                Bilinear|"Linear mip"|Trilinear|"Anisotropic 2x"|"Anisotropic 4x"|"Anisotropic 8x"|"Anisotropic 16x")
                    sed -i "s/TMUFiltering = appdriven/TMUFiltering = bilinear/" "$DGV2CONF" ;;
            esac
        fi

        if [[ "${PW_DGV2_ANTIALIASING}" != "disabled" ]] && [[ "${PW_DGV2_GLIDE_NAPALM}" != "1" ]] ; then
            sed -i "s/Antialiasing = appdriven/Antialiasing = ${PW_DGV2_ANTIALIASING}/g" "$DGV2CONF"
        elif [[ "${PW_DGV2_ANTIALIASING}" != "disabled" ]] && [[ "${PW_DGV2_GLIDE_NAPALM}" == "1" ]] ; then
            sed -i "86s/Antialiasing = appdriven/Antialiasing = ${PW_DGV2_ANTIALIASING}/" "$DGV2CONF"
        fi

        if [[ "${PW_DGV2_VRAM}" != "disabled" ]] ; then
            if [[ "${PW_DGV2_VIDEOCARD}" == "dgVoodoo2 SVGA 3D" ]] ; then
                if [[ "${PW_DGV2_VRAM}" -le "128" ]] ; then
                    sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
                else
                    sed -i "s/VRAM = 256/VRAM = 64/" "$DGV2CONF"
                fi
            fi
            [[ "${PW_DGV2_VIDEOCARD}" == "Geforce 4 Ti 4800" ]] && [[ "${PW_DGV2_VRAM}" -ge "64" ]] && [[ "${PW_DGV2_VRAM}" -le "256" ]] \
                && sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
            [[ "${PW_DGV2_VIDEOCARD}" == "ATI Radeon 8500" ]] && [[ "${PW_DGV2_VRAM}" -ge "64" ]] && [[ "${PW_DGV2_VRAM}" -le "256" ]] \
                && sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
            [[ "${PW_DGV2_VIDEOCARD}" == "Matrox Parhelia-512" ]] && [[ "${PW_DGV2_VRAM}" -ge "128" ]] && [[ "${PW_DGV2_VRAM}" -le "256" ]] \
                && sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
            [[ "${PW_DGV2_VIDEOCARD}" == "GeForce FX 5700 Ultra" ]] && [[ "${PW_DGV2_VRAM}" -ge "64" ]] && [[ "${PW_DGV2_VRAM}" -le "256" ]] \
                && sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
            if [[ "${PW_DGV2_VIDEOCARD}" == "GeForce 9800 GT" ]] ; then
                if [[ "${PW_DGV2_VRAM}" -ge "512" ]] && [[ "${PW_DGV2_VRAM}" -le "1024" ]] ; then
                    sed -i "s/VRAM = 256/VRAM = ${PW_DGV2_VRAM}/" "$DGV2CONF"
                else
                    sed -i "s/VRAM = 256/VRAM = 512/" "$DGV2CONF"
                fi
            fi
        else
            [[ "${PW_DGV2_VIDEOCARD}" == "dgVoodoo2 SVGA 3D" ]] && sed -i "s/VRAM = 256/VRAM = 64/" "$DGV2CONF"
            [[ "${PW_DGV2_VIDEOCARD}" == "GeForce 9800 GT" ]] && sed -i "s/VRAM = 256/VRAM = 512/" "$DGV2CONF"
        fi

        if [[ "$PW_DGV2_RESOLUTION" != "disabled" ]] ; then
            case "$PW_DGV2_RESOLUTION" in
                "2x app resolution")
                    sed -i "s/Resolution = unforced/Resolution = 2x/g" "$DGV2CONF" ;;
                "3x app resolution")
                    sed -i "s/Resolution = unforced/Resolution = 3x/g" "$DGV2CONF" ;;
                "4x app resolution")
                    sed -i "s/Resolution = unforced/Resolution = 4x/g" "$DGV2CONF" ;;
                *)
                    H_RES_DGV2="${PW_DGV2_RESOLUTION:0:4}"
                    V_RES_DGV2="${PW_DGV2_RESOLUTION:5:9}"
                    sed -i "s/Resolution = unforced/Resolution = h:$H_RES_DGV2, v:$V_RES_DGV2/g" "$DGV2CONF" ;;
            esac
        fi

        if [[ "$PW_DGV2_RESAMPLING" != "disabled" ]] ; then
            case "$PW_DGV2_RESAMPLING" in
                "Point sampled") sed -i "s/Resampling = bilinear/Resampling = pointsampled/" "$DGV2CONF" ;;
                Lanczos-2) sed -i "s/Resampling = bilinear/Resampling = lanczos-2" "$DGV2CONF" ;;
                Bicubic) sed -i "s/Resampling = bilinear/Resampling = bicubic" "$DGV2CONF" ;;
                Lanczos-3) sed -i "s/Resampling = bilinear/Resampling = lanczos-3" "$DGV2CONF" ;;
            esac
        fi

        if [[ $PW_DGV2_VIDEOCARD != "dgVoodoo2 Virtual 3D" ]] ; then
            case "$PW_DGV2_VIDEOCARD" in
                "dgVoodoo2 SVGA 3D") sed -i "s/VideoCard = internal3D/VideoCard = svga/" "$DGV2CONF" ;;
                "Geforce 4 Ti 4800") sed -i "s/VideoCard = internal3D/VideoCard = geforce_ti_4800/" "$DGV2CONF" ;;
                "ATI Radeon 8500") sed -i "s/VideoCard = internal3D/VideoCard = ati_radeon_8500/" "$DGV2CONF" ;;
                "Matrox Parhelia-512") sed -i "s/VideoCard = internal3D/VideoCard = matrox_parhelia-512/" "$DGV2CONF" ;;
                "GeForce FX 5700 Ultra") sed -i "s/VideoCard = internal3D/VideoCard = geforce_fx_5700_ultra/" "$DGV2CONF" ;;
                "GeForce 9800 GT") sed -i "s/VideoCard = internal3D/VideoCard = geforce_9800_gt/" "$DGV2CONF" ;;
            esac
            if [[ "${PW_DGV2_VIDEOCARD}" == "Voodoo Graphics" ]] ; then
                sed -i "s/VideoCard = voodoo_2/VideoCard = voodoo_graphics/" "$DGV2CONF"
                sed -i "s/NumberOfTMUs = 2/NumberOfTMUs = 1/" "$DGV2CONF"
                if [[ "${PW_DGV2_ONBOARD_RAM}" == "1" ]]
                then sed -i "s/OnboardRAM = 8/OnboardRAM = 4/" "$DGV2CONF"
                else sed -i "s/OnboardRAM = 8/OnboardRAM = 2/" "$DGV2CONF"
                fi
            fi
            if [[ "${PW_DGV2_VIDEOCARD}" == "Voodoo Rush" ]] ; then
                sed -i "s/VideoCard = voodoo_2/VideoCard = voodoo_rush/" "$DGV2CONF"
                sed -i "s/NumberOfTMUs = 2/NumberOfTMUs = 1/" "$DGV2CONF"
                if [[ "${PW_DGV2_ONBOARD_RAM}" == "1" ]]
                then sed -i "s/OnboardRAM = 8/OnboardRAM = 4/" "$DGV2CONF"
                else sed -i "s/OnboardRAM = 8/OnboardRAM = 2/" "$DGV2CONF"
                fi
            fi
            if [[ "${PW_DGV2_VIDEOCARD}" == "Voodoo 2" ]] && [[ "${PW_DGV2_ONBOARD_RAM}" == "1" ]] ; then
                sed -i "s/OnboardRAM = 8/OnboardRAM = 12/" "$DGV2CONF"
            fi
            if [[ "${PW_DGV2_VIDEOCARD}" == "Voodoo Banshee" ]] ; then
                sed -i "s/VideoCard = voodoo_2/VideoCard = voodoo_banshee/" "$DGV2CONF"
                sed -i "s/NumberOfTMUs = 2/NumberOfTMUs = 1/" "$DGV2CONF"
                if [[ "${PW_DGV2_ONBOARD_RAM}" == "1" ]] ; then
                    sed -i "s/OnboardRAM = 8/OnboardRAM = 16/" "$DGV2CONF"
                fi
            fi
        fi
    else
        for rm_dgv2_dll in d3dimm glide glide2x glide3x ; do
            try_remove_file "${WINEPREFIX}/drive_c/windows/syswow64/${rm_dgv2_dll}.dll"
        done
        add_to_var CP_WINE_FILES "ddraw"
    fi

    # force use dxgi.dll from wine
    if [[ "${PW_USE_WINE_DXGI}" == "1" ]] ; then
        rm_from_var CP_DXVK_FILES "dxgi"
        add_to_var CP_WINE_FILES "dxgi"
    fi

    print_info "Try create symlink WINE files..."
    for copy_wine_dll in $CP_WINE_FILES ; do
        try_force_link_file "${WINEDIR}/lib64/wine/x86_64-windows/${copy_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/system32/${copy_wine_dll}.dll"
        try_force_link_file "${WINEDIR}/lib/wine/i386-windows/${copy_wine_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${copy_wine_dll}.dll"
    done

    if [[ -n "$CP_DXVK_FILES" ]] ; then
        print_info "Try create symlink DXVK files..."
        for wine_dxvk_dll in $CP_DXVK_FILES ; do
            if [[ -f "${PATH_TO_DXVK_FILES}/x64/${wine_dxvk_dll}.dll" ]] ; then
                try_force_link_file "${PATH_TO_DXVK_FILES}/x32/${wine_dxvk_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${wine_dxvk_dll}.dll"
                try_force_link_file "${PATH_TO_DXVK_FILES}/x64/${wine_dxvk_dll}.dll" "${WINEPREFIX}/drive_c/windows/system32/${wine_dxvk_dll}.dll"
                var_winedlloverride_update "${wine_dxvk_dll}=n"
            fi
        done
        create_new_dir "${PATH_TO_DXVK_FILES}/dxvk_cache"
        export DXVK_STATE_CACHE_PATH="${PATH_TO_DXVK_FILES}"/dxvk_cache
        export DXVK_STATE_CACHE="1"
    fi

    if [[ "$DXVK_ENABLE_NVAPI" == "1" ]] ; then
        print_info "Try create symlink NVAPI files..."
        try_force_link_file "${PATH_TO_DXVK_FILES}/x32/nvapi.dll" "${WINEPREFIX}/drive_c/windows/syswow64/nvapi.dll"
        try_force_link_file "${PATH_TO_DXVK_FILES}/x64/nvapi64.dll" "${WINEPREFIX}/drive_c/windows/system32/nvapi64.dll"
    fi

    if [[ -n "$CP_VKD3D_FILES" ]] ; then
        print_info "Try create symlink VKD3D files..."
        for wine_vkd3d_dll in $CP_VKD3D_FILES ; do
            if [[ -f "${PATH_TO_VKD3D_FILES}/x64/${wine_vkd3d_dll}.dll" ]] ; then
                try_force_link_file "${PATH_TO_VKD3D_FILES}/x86/${wine_vkd3d_dll}.dll" "${WINEPREFIX}/drive_c/windows/syswow64/${wine_vkd3d_dll}.dll"
                try_force_link_file "${PATH_TO_VKD3D_FILES}/x64/${wine_vkd3d_dll}.dll" "${WINEPREFIX}/drive_c/windows/system32/${wine_vkd3d_dll}.dll"
                var_winedlloverride_update "${wine_vkd3d_dll}=n"
            fi
        done
        create_new_dir "${PATH_TO_VKD3D_FILES}/vkd3d_cache"
        export VKD3D_SHADER_CACHE_PATH="${PATH_TO_VKD3D_FILES}/vkd3d_cache"
    fi

    if [[ "$CP_GALLIUM_NINE_FILES" == "d3d9" ]] ; then
        print_info "Try create symlink GALLIUM_NINE files..."
        PATH_TO_GALLIUM_NINE_FILES="${PW_PLUGINS_PATH}/gallium_nine_v.${PW_GALLIUM_NINE_VER}"
        try_force_link_file "${PATH_TO_GALLIUM_NINE_FILES}/lib32/d3d9-nine.dll.so" "${WINEPREFIX}/drive_c/windows/syswow64/d3d9.dll"
        try_force_link_file "${PATH_TO_GALLIUM_NINE_FILES}/lib64/d3d9-nine.dll.so" "${WINEPREFIX}/drive_c/windows/system32/d3d9.dll"
        unset FIND_D3D_MODULE D3D_MODULE_PATH
        if ! check_flatpak ; then
            FIND_D3D_MODULE=$(dirname $(find /usr/ -maxdepth 4 -type f -name "d3dadapter9.so.*") 2>/dev/null)
            if [[ -n "$FIND_D3D_MODULE" ]] ; then
                IFS=$'\n'
                for D3D_MP in $FIND_D3D_MODULE ; do
                    if [[ -n "$D3D_MODULE_PATH" ]]
                    then export D3D_MODULE_PATH="$D3D_MODULE_PATH:/run/host${D3D_MP}"
                    else export D3D_MODULE_PATH="/run/host${D3D_MP}"
                    fi
                done
                IFS="$orig_IFS"
                print_info "D3D_MODULE_PATH=${D3D_MODULE_PATH}"
            else
                pw_stop_progress_bar
                yad_error "${translations[d3dadapter9.so.1.0.0 - Not found in the system.\\nInstall the missing package: <b>d3dadapter9</b>]}"
                stop_portwine
            fi
        else
            export D3D_MODULE_PATH="/app/lib/i386-linux-gnu/GL/default/lib/d3d:/usr/lib/x86_64-linux-gnu/GL/default/lib/d3d"
            print_info "D3D_MODULE_PATH=${D3D_MODULE_PATH}"
        fi
        var_winedlloverride_update "d3d9=n"
    fi

    if [[ ! -d "${WINEPREFIX}/drive_c/vrclient/bin" ]] ; then
        create_new_dir "${WINEPREFIX}/drive_c/vrclient/bin"
        try_force_link_file "${WINEDIR}"/lib/wine/i386-windows/vrclient.dll "${WINEPREFIX}/drive_c/vrclient/bin/vrclient.dll"
        try_force_link_file "${WINEDIR}"/lib64/wine/x86_64-windows/vrclient_x64.dll "${WINEPREFIX}/drive_c/vrclient/bin/vrclient_x64.dll"
    fi

    if [[ "${PW_USE_SHADER_CACHE}" == "1" ]] ; then
        create_new_dir "${PW_VULKAN_DIR}/gl_shader_cache"
        export __GL_SHADER_DISK_CACHE="1"
        export __GL_SHADER_DISK_CACHE_PATH="${PW_VULKAN_DIR}/gl_shader_cache"
        export __GL_SHADER_DISK_CACHE_SIZE="50000000000"
        export __GL_SHADER_DISK_CACHE_SKIP_CLEANUP="1"
    else
        export __GL_SHADER_DISK_CACHE="0"
        export DXVK_STATE_CACHE="disable"
        export VKD3D_SHADER_CACHE_PATH="0"
    fi

    if [[ "${PW_WINE_FULLSCREEN_FSR}" == "1" ]] \
    && ! check_gamescope_session
    then
        export WINE_FULLSCREEN_FSR="1"
        export WINE_FULLSCREEN_FSR_STRENGTH="2"
        export WINE_FULLSCREEN_INTEGER_SCALING="0"
    else
        export WINE_FULLSCREEN_FSR="0"
        unset WINE_FULLSCREEN_FAKE_CURRENT_RES WINE_FULLSCREEN_FSR_STRENGTH WINE_FULLSCREEN_INTEGER_SCALING
    fi

    if [[ "${PW_WINE_CPU_TOPOLOGY}" != "disabled" ]] ; then
        export WINE_CPU_TOPOLOGY="${PW_WINE_CPU_TOPOLOGY}"
    fi

    if [[ "${PW_MESA_GL_VERSION_OVERRIDE}" != "disabled" ]] ; then
        export MESA_GL_VERSION_OVERRIDE="${PW_MESA_GL_VERSION_OVERRIDE}"
        if [[ $PW_MESA_GL_VERSION_OVERRIDE = 3.2COMPAT ]] ; then
            export MESA_GLSL_VERSION_OVERRIDE="150"
        else
            MESA_GLSL_VERSION_OVERRIDE="${PW_MESA_GL_VERSION_OVERRIDE//./}"
            export MESA_GLSL_VERSION_OVERRIDE="${MESA_GLSL_VERSION_OVERRIDE//COMPAT/}0"
        fi
    fi

    if [[ "${PW_VKD3D_FEATURE_LEVEL}" != "disabled" ]] ; then
        export VKD3D_FEATURE_LEVEL="${PW_VKD3D_FEATURE_LEVEL}"
    fi

    if [[ "${PW_MESA_VK_WSI_PRESENT_MODE}" != "disabled" ]] ; then
        export MESA_VK_WSI_PRESENT_MODE="${PW_MESA_VK_WSI_PRESENT_MODE}"
        case "$PW_MESA_VK_WSI_PRESENT_MODE" in
            immediate|mailbox)
                export vblank_mode=0
                export __GL_SYNC_TO_VBLANK=0 ;;
            relaxed|fifo)
                export vblank_mode=1
                export __GL_SYNC_TO_VBLANK=1 ;;
        esac
    fi

    #run_winetricks_from_db
    if [[ -n "${PW_MUST_HAVE_DLL}" ]]
    then export PW_DLL_INSTALL="$(echo "${PW_MUST_HAVE_DLL} ${PW_DLL_INSTALL}" | awk '{ for(i=1;i<=NF;i++){a[$i]++} }END{ for(i in a){printf("%s ",i)} }' )"
    fi

    if [[ -n "${PW_DLL_INSTALL}" ]] ; then
        export PW_DLL_NEED_INSTALL=""
        export USE_WT_FROM_DB=0
        if [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ]] ; then
            touch "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
        fi
        for need_install_dll_to_pfx in ${PW_DLL_INSTALL} ; do
            if [[ "${need_install_dll_to_pfx}" == vcrun201[5-9] ]] \
            || [[ "${need_install_dll_to_pfx}" == vcrun2022 ]] ; then
                need_install_dll_to_pfx="vcrun2022"
                sed -i '/vcrun2015/d' "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
                sed -i '/vcrun2017/d' "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
                sed -i '/vcrun2019/d' "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
            fi
            grep "${need_install_dll_to_pfx}" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" &>/dev/null
            if [[ "$?" == "1" ]] ; then
                if [[ -z "${PW_DLL_NEED_INSTALL}" ]]
                then export PW_DLL_NEED_INSTALL="${need_install_dll_to_pfx}"
                else export PW_DLL_NEED_INSTALL="${need_install_dll_to_pfx} ${PW_DLL_NEED_INSTALL}"
                fi
                export USE_WT_FROM_DB=1
            fi
        done
        if [[ "${USE_WT_FROM_DB}" == "1" ]] ; then
            pw_update_pfx_cover_gui
            update_winetricks
            echo "START WINETRICKS..." >> "${PW_TMPFS_PATH}/update_pfx_log"
            echo "Try to install DLL in prefix: ${PW_DLL_NEED_INSTALL}" >> "${PW_TMPFS_PATH}/update_pfx_log"
            print_info "Try to install DLL in prefix: ${PW_DLL_NEED_INSTALL}"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${PORT_WINE_TMP_PATH}/winetricks" -q -r -f ${PW_DLL_NEED_INSTALL} | tee -a "${PW_TMPFS_PATH}/update_pfx_log"
            wait_wineserver
            kill_portwine
        fi
    fi

    if [[ -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg" ]] \
    && [[ -z $(grep "Windows $PW_WINDOWS_VER" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg") ]]
    then
        if [[ -n "${PW_WINDOWS_VER}" ]] \
        && [[ $(echo "$PW_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]]
        then
            export PW_WINDOWS_VER="xp64"
        fi
        ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
        "${WINELOADER}" winecfg -v $(echo "win${PW_WINDOWS_VER}" | sed 's/.*/\L&/')
        wait_wineserver
        kill_portwine
        echo "Set to win${PW_WINDOWS_VER}"
    fi

    if [[ "${portwine_exe}" == *-Shipping.exe ]] ; then
        echo "Disable EAC"
        [[ -z "${LAUNCH_PARAMETERS}" ]] && export LAUNCH_PARAMETERS+=" -eac-nop-loaded "
    fi

    HIDRAW_VAR="$(grep "DisableHidraw" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg")"
    SDL_VAR="$(grep "Enable SDL" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg")"
    if [[ "${PW_DINPUT_PROTOCOL}" == "1" ]] ; then
        if [[ "$HIDRAW_VAR" ]] \
        && [[ "$SDL_VAR" ]]
        then
            if [[ "${HIDRAW_VAR: -1}" != "0" ]] ; then
                sed -i "s/${HIDRAW_VAR}/${HIDRAW_VAR%?}0/" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg"
            fi

            if [[ "${SDL_VAR: -1}" != "0" ]] ; then
                sed -i "s/${SDL_VAR}/${SDL_VAR%?}0/" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg"
            fi
        else
            print_info "Added DisableHidraw = 0 to reg file"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus" /v "DisableHidraw" /t REG_DWORD /d 0 /f
            print_info "Added Enable SDL = 0 to reg file"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus" /v "Enable SDL" /t REG_DWORD /d 0 /f
        fi
    else
        # var_winedlloverride_update "xinput1_1,xinput1_2,xinput1_3,xinput9_1_0=b"

        if [[ "$HIDRAW_VAR" ]] \
        && [[ "$SDL_VAR" ]]
        then
            if [[ "${HIDRAW_VAR: -1}" != "1" ]] ; then
                sed -i "s/${HIDRAW_VAR}/${HIDRAW_VAR%?}1/" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg"
            fi

            if [[ "${SDL_VAR: -1}" != "1" ]] ; then
                sed -i "s/${SDL_VAR}/${SDL_VAR%?}1/" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/system.reg"
            fi
        else
            print_info "Added DisableHidraw = 1 to reg file"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus" /v "DisableHidraw" /t REG_DWORD /d 1 /f
            print_info "Added Enable SDL = 1 to reg file"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus" /v "Enable SDL" /t REG_DWORD /d 1 /f
        fi
    fi

    WINE_WAYLAND_VAR="$(grep "x11,wayland" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg")"
    if [[ "${PW_USE_NATIVE_WAYLAND}" == "1" ]] ; then
        if [[ ! "$WINE_WAYLAND_VAR" ]] ; then
            print_info "Enable experimental Wayland support"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg add "HKEY_CURRENT_USER\Software\Wine\Drivers" /v "Graphics" /t REG_SZ /d "x11,wayland" /f
        fi
        export PW_DISPLAY="env DISPLAY="
        export PW_USE_RUNTIME="0"
    else
        unset PW_DISPLAY
        if [[ "$WINE_WAYLAND_VAR" ]] ; then
            print_info "Disable experimental Wayland support"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${WINELOADER}" reg delete "HKEY_CURRENT_USER\Software\Wine\Drivers" /v Graphics /f
        fi
    fi

    if [[ "${PW_SOUND_DRIVER_USE}" != "disabled" ]] \
    && grep -v "\"Audio\"=\"$PW_SOUND_DRIVER_USE\"" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg" &>/dev/null
    then
        if grep "\"Audio\"=" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg" &>/dev/null ; then
            sed -i 's/"Audio"=".*"/"Audio"="'${PW_SOUND_DRIVER_USE}'"/' "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg"
        else
            echo -e '\n[Software\\Wine\\Drivers]\n"Audio"="'${PW_SOUND_DRIVER_USE}'"' >> "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg"
        fi
        kill_portwine
    elif [[ "${PW_SOUND_DRIVER_USE}" == "disabled" ]] \
    && grep -v "\"Audio\"=" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg" &>/dev/null
    then
        sed -i '/\[Software\\Wine\\Drivers\]/d' "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg" &>/dev/null
        sed -i "/\"Audio\"=/d" "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/user.reg" &>/dev/null
    fi

    pw_stop_progress_bar
    if ! check_start_from_steam ; then
        pw_tray_icon
        sleep 0.5
    fi

    if [[ "${PW_CHECK_AUTOINSTALL}" != "1" ]] ; then
            pw_start_progress_bar_cover "${COVERS_PATH}/loading_${LANGUAGE_GIF}.gif"
    fi
    add_in_start_portwine

    if [[ -f "${PATH_TO_GAME}/dxvk.conf" ]] ; then
        export DXVK_CONFIG_FILE="${PATH_TO_GAME}/dxvk.conf"
    fi

    for chk_lang_and_uname in "steam_emu.ini" "steam_api.ini" "steam_api64.ini" "SteamConfig.ini" ; do
        if [[ -f "${PATH_TO_GAME}/${chk_lang_and_uname}" ]] ; then
            sed -i "/^Language/c\Language=${FULL_LN}" "${PATH_TO_GAME}/${chk_lang_and_uname}"
            sed -i "/^UserName/c\UserName=${USER}" "${PATH_TO_GAME}/${chk_lang_and_uname}"
            sed -i "/^PlayerName/c\PlayerName=${USER}" "${PATH_TO_GAME}/${chk_lang_and_uname}"
        fi
    done

    if [[ "${PW_DISABLE_COMPOSITING}" == "1" ]] \
    && ! check_gamescope_session
    then
        if [[ "${DESKTOP_SESSION}" =~ "plasma" ]] ; then
            qdbus org.kde.KWin /Compositor suspend
        elif [[ "${DESKTOP_SESSION}" =~ "mate" ]] ; then
            gsettings set org.mate.Marco.general compositing-manager false
        elif [[ "${DESKTOP_SESSION}" =~ "xfce" ]] ; then
            xfconf-query -c xfwm4 -p /general/use_compositing -s false
        elif [[ "${DESKTOP_SESSION}" =~ "cinnamon" ]] ; then
            gsettings set org.cinnamon.muffin unredirect-fullscreen-windows true
        elif [[ "${DESKTOP_SESSION}" =~ "deepin" ]] ; then
            dbus-send --session --dest=com.deepin.WMSwitcher --type=method_call /com/deepin/WMSwitcher com.deepin.WMSwitcher.RequestSwitchWM
        fi
    fi

    # GAMESCOPE enable:
    if [[ "${PW_GAMESCOPE}" == "1" && "${GAMESCOPE_INSTALLED}" == "1" ]] \
    || check_gamescope_session
    then
        export vk_xwayland_wait_ready="false"
        if [[ -d /sys/bus/pci/drivers/amdgpu ]] ; then
            export RADV_DEBUG+="nodcc "
            export AMD_DEBUG="nodcc"
            if [[ ! $(<"${PW_TMPFS_PATH}/vulkaninfo.tmp") =~ VK_EXT_image_drm_format_modifier ]] ; then
                export R600_DEBUG="nodcc"
                grep -e '--backend' "${PW_TMPFS_PATH}/gamescope.tmp" &>/dev/null && PW_GS_BACKEND_SDL="1"
            fi
        fi
        if [[ -d /sys/bus/pci/drivers/i915 ]] ; then
            export INTEL_DEBUG="norbc"
        fi
    fi
    if [[ "${PW_GAMESCOPE}" == "1" && "${GAMESCOPE_INSTALLED}" == "1" ]] \
    && ! check_gamescope_session
    then
        if [[ "${PW_GPU_USE}" != "disabled" ]] ; then
            PW_vendorID="$(grep -B3 "${PW_GPU_USE}" "${PW_TMPFS_PATH}/vulkaninfo.tmp" | grep vendorID | sort -u | awk -F'0x' '{print $2}')"
            PW_deviceID="$(grep -B3 "${PW_GPU_USE}" "${PW_TMPFS_PATH}/vulkaninfo.tmp" | grep deviceID | sort -u | awk -F'0x' '{print $2}')"
            PW_ID_VIDEO=" --prefer-vk-device ${PW_vendorID}:${PW_deviceID}"
        else
            PW_ID_VIDEO=""
        fi

        #checkbox
        unset PW_GAMESCOPE_ARGS_NEW
        [[ "${PW_GS_FULLSCREEN}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" -f"
        [[ "${PW_GS_FORCE_FULLSCREEN}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --force-windows-fullscreen"
        [[ "${PW_GS_BORDERLESS_WINDOW}" == "1" ]] &&  PW_GAMESCOPE_ARGS_NEW+=" -b"
        [[ "${PW_GS_FORCE_GRAB_CURSOR}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --force-grab-cursor"
        [[ "${PW_GS_FORCE_GRAB_KEYBOARD}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" -g"

        if [[ "${PW_GS_HDR_ENABLE}" == "1" ]] ; then
            PW_GAMESCOPE_ARGS_NEW+=" --hdr-enabled"
            export DXVK_HDR="1"
        fi

        [[ "${PW_GS_ENABLE_GAMESCOPE_WSI}" == "1" ]] && export ENABLE_GAMESCOPE_WSI="1"

        [[ "${PW_GS_HDR_ITM_ENABLE}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-itm-enable"
        [[ "${PW_GS_SDR_GAMMUT_WIDENESS}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --sdr-gamut-wideness"
        [[ "${PW_GS_FORCE_COMPOSITION}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --force-composition"
        [[ "${PW_GS_HDR_FORCE_SUPPORT}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-debug-force-support"
        [[ "${PW_GS_HDR_FORCE_OUTPUT}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-debug-force-output"
        [[ "${PW_GS_HDR_FORCE_HEATMAP}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-debug-heatmap"
        [[ "${PW_GS_EXPOSE_WAYLAND}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --expose-wayland"
        [[ "${PW_GS_REALTIME_SCHEDULING}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --rt"

        if [[ "${PW_GS_MANGOAPP}" == "1" ]] ; then
            PW_GAMESCOPE_ARGS_NEW+=" --mangoapp"
            export PW_MANGOHUD="0"
        fi

        [[ "${PW_GS_BACKEND_SDL}" == "1" ]] && PW_GAMESCOPE_ARGS_NEW+=" --backend sdl"
        [[ "${PW_GS_SDL_VIDEODRIVER_X11}" == "1" ]] && export SDL_VIDEODRIVER="x11"

        #combobox
        if [[ "${PW_GS_SHOW_RESOLUTION}" != "disabled" ]] ; then
            PWGSRESSW1="${PW_GS_SHOW_RESOLUTION%x*}"
            PWGSRESSW="${PWGSRESSW1%%-*}"
            PWGSRESSH1="${PW_GS_SHOW_RESOLUTION#*x}"
            PWGSRESSH="${PWGSRESSH1%%-*}"
            PW_GAMESCOPE_ARGS_NEW+=" -W ${PWGSRESSW} -H ${PWGSRESSH}"

            if [[ "${PW_GS_INTERNAL_RESOLUTION}" != "0.0" ]] ; then
                GS_RES_W=${PW_GS_SHOW_RESOLUTION:0:4}
                GS_RES_H=${PW_GS_SHOW_RESOLUTION:5:8}
                PWGSRESIW=$(echo "${GS_RES_W}" "${PW_GS_INTERNAL_RESOLUTION}" | awk '{print $1*$2}')
                PWGSRESIH=$(echo "${GS_RES_H}" "${PW_GS_INTERNAL_RESOLUTION}" | awk '{print $1*$2}')
                PW_GAMESCOPE_ARGS_NEW+=" -w ${PWGSRESIW} -h ${PWGSRESIH}"
            fi
        fi

        [[ "${PW_GS_FRAME_LIMIT}" != "disabled" ]] && PW_GAMESCOPE_ARGS_NEW+=" -r ${PW_GS_FRAME_LIMIT}"
        [[ "${PW_GS_MAX_SCALE_FACTOR}" != "0.0" ]] && PW_GAMESCOPE_ARGS_NEW+=" -m ${PW_GS_MAX_SCALE_FACTOR}"
        [[ "${PW_GS_SCALER_MODE}" != "disabled" ]] && PW_GAMESCOPE_ARGS_NEW+=" -S ${PW_GS_SCALER_MODE}"

        if [[ "${PW_GS_FILTER_MODE}" != "disabled" ]] ; then
            export PW_WINE_FULLSCREEN_FSR="0"
            if [[ "${PW_GS_FILTER_MODE_OLD}" != "true" ]] ; then
                PW_GAMESCOPE_ARGS_NEW+=" -F ${PW_GS_FILTER_MODE}"
            else
                if [[ "${PW_GS_FILTER_MODE}" == "fsr" ]] ; then
                    PW_GAMESCOPE_ARGS_NEW+=" -U"
                elif [[ "${PW_GS_FILTER_MODE}" == "nis" ]] ; then
                    PW_GAMESCOPE_ARGS_NEW+=" -Y"
                fi
            fi
            PW_GAMESCOPE_ARGS_NEW+=" --sharpness ${PW_GS_UPSCALE_SHARPNESS}"
        fi

        [[ "${PW_GS_MOUSE_SENSITIVITY}" != "0.0" ]] && PW_GAMESCOPE_ARGS_NEW+=" -s ${PW_GS_MOUSE_SENSITIVITY}"
        [[ "${PW_GS_SDR_CONTENT_NITS}" != "400" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-sdr-content-nits ${PW_GS_SDR_CONTENT_NITS}"
        [[ "${PW_GS_ITM_SDR_NITS}" != "0" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-itm-sdr-nits ${PW_GS_ITM_SDR_NITS}"
        [[ "${PW_GS_ITM_TARGET_NITS}" != "0" ]] && PW_GAMESCOPE_ARGS_NEW+=" --hdr-itm-target-nits ${PW_GS_ITM_TARGET_NITS}"

        edit_db_from_gui PW_GAMESCOPE_ARGS_NEW
        export PW_RUN_GAMESCOPE="gamescope${PW_ID_VIDEO}${PW_GAMESCOPE_ARGS_NEW} --"
    fi

    pw_mangohud_check
    pw_vkbasalt_check
}

pw_run () {
    unset GDK_BACKEND
    if [[ -n "${PATH_TO_GAME}" ]] \
    && [[ -d "${PATH_TO_GAME}" ]]
    then
        cd "${PATH_TO_GAME}" || :
    elif [[ -f "$portwine_exe" ]]
    then
        PATH_TO_GAME="$( cd "$( dirname "${portwine_exe}" )" >/dev/null 2>&1 && pwd )"
        cd "${PATH_TO_GAME}" || :
    else
        cd "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c" || :
    fi
    PW_LOG_TO_FILE="${PORT_WINE_PATH}/PortProton.log"
    PW_LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}:${WINE_LIBRARY_PATH}"
    print_var "WINEDIR" "WINEPREFIX" "WINEDLLOVERRIDES" "PATH_TO_GAME" "PW_WINE_USE" "PW_VULKAN_USE" "VULKAN_DRIVER_NAME"
    print_var "VKD3D_CONFIG" "PW_LD_LIBRARY_PATH" "PATH" "WINEESYNC" "WINEFSYNC" "WINEFSYNC_FUTEX2"
    print_var "WINEDLLPATH" "WINE_CPU_TOPOLOGY" "PW_RUN_GAMESCOPE" "LD_LIBRARY_PATH"
    pw_stop_progress_bar
    if [[ "$PW_USE_RUNTIME" == 1 ]] \
    && [[ "$PW_WINE_USE" != "USE_SYSTEM_WINE" ]]
    then
        if [[ "${PW_LOG}" == 1 ]] ; then
            echo "WINEDLLOVERRIDES=${WINEDLLOVERRIDES}" >> "${PW_LOG_TO_FILE}"
            echo "------------------------------------" >> "${PW_LOG_TO_FILE}"
            [[ -f "${PW_TMPFS_PATH}/update_pfx_log" ]] && cat "${PW_TMPFS_PATH}/update_pfx_log" >> "${PW_LOG_TO_FILE}"
            echo "-" >> "${PW_LOG_TO_FILE}"
            echo "Log WINE:" >> "${PW_LOG_TO_FILE}"
            echo ""
            print_info "Log from RUNTIME and WINE:"
            ${PW_RUN_GAMESCOPE} \
            ${PW_POWERPROFILECTL_SLR} \
            ${PW_INHIBIT_SLR}\
            ${pw_runtime} \
            LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" \
            LD_PRELOAD="${PW_LD_PRELOAD}" \
            VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
            VK_INSTANCE_LAYERS=${PW_VK_INSTANCE_LAYERS} \
            ${PW_GAMEMODERUN_SLR} \
            ${PW_MANGOHUD_SLR} \
            ${PW_DISPLAY} \
            "${WINELOADER}" "$@" ${LAUNCH_PARAMETERS[@]} &>>"${PW_LOG_TO_FILE}"
        else
            if [[ "$PW_USE_TERMINAL" == 1 ]] ; then
                PW_ADD_TO_ARGS_IN_RUNTIME="--xterm"
                pw_init_runtime
            fi
            echo ""
            echo "Log WINE:" > "${PW_LOG_TO_FILE}"
            ${PW_RUN_GAMESCOPE} \
            ${PW_POWERPROFILECTL_SLR} \
            ${PW_INHIBIT_SLR}\
            ${pw_runtime} \
            LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" \
            LD_PRELOAD="${PW_LD_PRELOAD}" \
            VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
            VK_INSTANCE_LAYERS="${PW_VK_INSTANCE_LAYERS}" \
            ${PW_GAMEMODERUN_SLR} \
            ${PW_MANGOHUD_SLR} \
            ${PW_DISPLAY} \
            "${WINELOADER}" "$@" ${LAUNCH_PARAMETERS[@]} &>>"${PW_LOG_TO_FILE}"
            print_info "Update prefix log:"
            [[ -f "${PW_TMPFS_PATH}/update_pfx_log" ]] && cat "${PW_TMPFS_PATH}/update_pfx_log"
            echo
            print_info "Log from RUNTIME and WINE:"
            awk '! a[$0]++' "${PW_LOG_TO_FILE}"
            echo
        fi
    else
        if [[ "${PW_LOG}" == 1 ]] ; then
            echo "WINEDLLOVERRIDES=${WINEDLLOVERRIDES}" >> "${PW_LOG_TO_FILE}"
            echo "------------------------------------" >> "${PW_LOG_TO_FILE}"
            [[ -f "${PW_TMPFS_PATH}/update_pfx_log" ]] && cat "${PW_TMPFS_PATH}/update_pfx_log" >> "${PW_LOG_TO_FILE}"
            echo "-" >> "${PW_LOG_TO_FILE}"
            echo "Log WINE:" >> "${PW_LOG_TO_FILE}"
            echo ""
            print_info "Log WINE:"
            env FAKE_VAR= \
            LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" \
            LD_PRELOAD="${PW_LD_PRELOAD}" \
            VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
            VK_INSTANCE_LAYERS="${PW_VK_INSTANCE_LAYERS}" \
            ${PW_RUN_GAMESCOPE} \
            ${PW_GAMEMODERUN_SLR} \
            ${PW_POWERPROFILECTL_SLR} \
            ${PW_MANGOHUD_SLR} \
            ${PW_DISPLAY} \
            ${PW_INHIBIT_SLR}\
            "${WINELOADER}" "$@" ${LAUNCH_PARAMETERS[@]} &>>"${PW_LOG_TO_FILE}"
            wait_wineserver
        else
            print_info "Update prefix log:"
            [[ -f "${PW_TMPFS_PATH}/update_pfx_log" ]] && cat "${PW_TMPFS_PATH}/update_pfx_log"
            echo ""
            echo "Log WINE:" > "${PW_LOG_TO_FILE}"
            print_info "Log WINE:"
            env FAKE_VAR= \
            LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" \
            LD_PRELOAD="${PW_LD_PRELOAD}" \
            VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
            VK_INSTANCE_LAYERS="${PW_VK_INSTANCE_LAYERS}" \
            ${PW_RUN_GAMESCOPE} \
            ${PW_GAMEMODERUN_SLR} \
            ${PW_POWERPROFILECTL_SLR} \
            ${PW_MANGOHUD_SLR} \
            ${PW_DISPLAY} \
            ${PW_INHIBIT_SLR}\
            "${WINELOADER}" "$@" ${LAUNCH_PARAMETERS[@]}
            wait_wineserver
        fi
    fi
}
export -f pw_run

pw_yad_set_form () {
    if [[ $(<"${PW_TMPFS_PATH}/tmp_yad_form") != "" ]] ; then
        pw_skip_get_info
        PW_YAD_SET=$(head -n 1 "${PW_TMPFS_PATH}/tmp_yad_form" | awk '{print $1}')
        export PW_YAD_SET
    fi
}

pw_yad_form_vulkan () {
    if [[ "$(<"${PW_TMPFS_PATH}/tmp_yad_form_vulkan")" != "" ]] ; then
        if [[ -n "${KEY_START}" ]] ; then
            YAD_FORM_VULKAN=$(sed 's/$/\;/' "${PW_TMPFS_PATH}/tmp_yad_form_vulkan")
            VULKAN_MOD=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $1}')
            PW_WINE_VER=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $2}')
            PW_PREFIX_NAME=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $3}' | sed -e s/[[:blank:]]/_/g)
        else
            YAD_FORM_VULKAN=$(<"${PW_TMPFS_PATH}/tmp_yad_form_vulkan")
            VULKAN_MOD=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $1}')
            PW_PREFIX_NAME=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $2}' | sed -e s/[[:blank:]]/_/g)
            PW_WINE_VER=$(echo "${YAD_FORM_VULKAN}" | grep \;\; | awk -F";" '{print $3}')
        fi
        if [[ -z "${PW_PREFIX_NAME}" ]] \
        || [[ -n "$(echo "${PW_PREFIX_NAME}" | grep -E '^_.*' )" ]]
        then
            PW_PREFIX_NAME="DEFAULT"
        else
            PW_PREFIX_NAME="${PW_PREFIX_NAME^^}"
        fi
        export PW_PREFIX_NAME PW_WINE_VER VULKAN_MOD
    fi
}

portwine_launch () {
    start_portwine
    unset PW_VD_TMP
    if [[ "${PW_VIRTUAL_DESKTOP}" == "1" ]] ; then
        PW_VD_TMP=(explorer "/desktop=PortProton,${PW_SCREEN_RESOLUTION}")
    fi

    [[ $PW_LOG != 1 ]] && debug_timer --start -s "PW_TIME_IN_GAME"
    case "$portwine_exe" in
        *.[Ee][Xx][Ee])
            pw_run ${PW_VD_TMP[@]} ${WINE_WIN_START} "$portwine_exe"
        ;;
        *.[Bb][Aa][Tt])
            PW_USE_TERMINAL=1
            pw_run ${PW_VD_TMP[@]} "$portwine_exe"
        ;;
        *.[Mm][Ss][Ii])
            pw_run ${PW_VD_TMP[@]} msiexec /i "$portwine_exe"
        ;;
        *.[Rr][Ee][Gg])
            pw_run ${PW_VD_TMP[@]} regedit "$portwine_exe"
        ;;
        *)
            pw_run ${PW_VD_TMP[@]} winefile
        ;;
    esac
}

pw_winecfg () {
    start_portwine
    export GST_PLUGIN_SYSTEM_PATH_1_0=""
    pw_run winecfg
    stop_portwine --restart
}

pw_winefile () {
    start_portwine
    pw_run winefile
    stop_portwine --restart
}

pw_winecmd () {
    start_portwine
    cd "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/drive_c" || fatal
    if check_flatpak ; then
        $PW_TERM "pw_run cmd"
    else
        export PW_USE_TERMINAL=1
        pw_run cmd
    fi
    stop_portwine --restart
}

pw_winereg () {
    start_portwine
    export GST_PLUGIN_SYSTEM_PATH_1_0=""
    pw_run regedit
    stop_portwine --restart
}

pw_start_cont_xterm () {
    cd "$HOME" || :
    unset PW_SANDBOX_HOME_PATH
    pw_init_runtime
    ${pw_runtime} \
    LD_PRELOAD="${PW_LD_PRELOAD}" \
    VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
    VK_INSTANCE_LAYERS="${PW_VK_INSTANCE_LAYERS}" \
    ${PW_GAMEMODERUN_SLR} \
    ${PW_MANGOHUD_SLR} \
    ${PW_TERM} bash
    restart_pp
}

# GUI INFO
yad_info () {
    print_info "$@"
    if [[ ! -f "${pw_yad}" ]] ; then
        local pw_yad="yad"
        command -v "${pw_yad}" &>/dev/null || fatal "yad not found"
    fi
    "${pw_yad}" --no-wrap --text "$@" --width=400 --height=150 --borders=15 --title "INFO" \
    --gui-type-layout="${YAD_INFO_GUI_TYPE_LAYOUT}" \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --image="$PW_GUI_ICON_PATH/info.svg" \
    --text-align=center --fixed \
    --button="${translations[OK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png" 2>/dev/null
}
export -f yad_info

# GUI ERROR
yad_error () {
    print_error "$@"
    if [[ ! -f "${pw_yad}" ]] ; then
        local pw_yad="yad"
        command -v "${pw_yad}" &>/dev/null || fatal "yad not found"
    fi
    "${pw_yad}" --no-wrap --text "$@" --width=400 --height=150 --borders=15 --title "ERROR" \
    --gui-type-layout="${YAD_INFO_GUI_TYPE_LAYOUT}" \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --image="$PW_GUI_ICON_PATH/error.svg" \
    --text-align=center --fixed \
    --button="${translations[EXIT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png" 2>/dev/null
}
export -f yad_error

yad_error_download () {
    if [[ ! -f "${pw_yad}" ]] ; then
        local pw_yad="yad"
        command -v "${pw_yad}" &>/dev/null || fatal "yad not found"
    fi
    "${pw_yad}" --text "${translations[You will need to check internet connection,and\\npress Repeat for repeat download]}" \
    --width=400 --borders=15 --title "${translations[Error]}" \
    --gui-type-layout="${YAD_INFO_GUI_TYPE_LAYOUT}" \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --image="$PW_GUI_ICON_PATH/download.svg" \
    --no-wrap --text-align=center \
    --button="${translations[SKIP]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1 \
    --button="${translations[REPEAT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null
    [[ "$?" != 0 ]] && return 1 || return 0
}

# GUI QUESTIONS
yad_question () {
    if [[ ! -f "${pw_yad}" ]] ; then
        local pw_yad="yad"
        command -v "${pw_yad}" &>/dev/null || fatal "yad not found"
    fi
    "${pw_yad}" --text "${1}" --width=400 --height=150 --borders=15 --title "${translations[Choices]}" \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --image="$PW_GUI_ICON_PATH/question.svg" \
    --gui-type-layout="${YAD_INFO_GUI_TYPE_LAYOUT}" \
    --no-wrap --text-align=center --fixed \
    --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1 \
    --button="${translations[OK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null
    [[ "$?" != 0 ]] && return 1 || return 0
}

pw_start_progress_bar_cover () {
    if check_gamescope_session ; then
        PW_GIF_FILE="${COVERS_PATH}/loading_deck.gif"
        "${pw_yad}" --picture --filename="${PW_GIF_FILE}" --close-on-unfocus --no-buttons --undecorated --fullscreen --skip-taskbar > /dev/null 2>&1 &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
    elif ! check_start_from_steam ; then
        PW_GIF_FILE="$1"
        PW_GIF_SIZE_X=$(file "${PW_GIF_FILE}" | awk '{print $7 + 8}')
        PW_GIF_SIZE_Y=$(file "${PW_GIF_FILE}" | awk '{print $9 + 15}')
        "${pw_yad}" --picture --filename="${PW_GIF_FILE}" --close-on-unfocus --no-buttons --undecorated \
        --skip-taskbar --width="$PW_GIF_SIZE_X" --height="$PW_GIF_SIZE_Y" --window-icon="$PW_GUI_ICON_PATH/portproton.svg" > /dev/null 2>&1 &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
    fi
    return 0
}

pw_start_progress_bar_cover_block () {
    if ! check_start_from_steam ; then
        [[ ! -f "${pw_yad}" ]] && local pw_yad="yad"
        PW_GIF_FILE="$1"
        PW_GIF_SIZE_X=$(file "${PW_GIF_FILE}" | awk '{print $7 + 8}')
        PW_GIF_SIZE_Y=$(file "${PW_GIF_FILE}" | awk '{print $9 + 15}')
        "${pw_yad}" --picture --filename="${PW_GIF_FILE}" --close-on-unfocus --no-buttons --undecorated \
        --skip-taskbar --width="$PW_GIF_SIZE_X" --height="$PW_GIF_SIZE_Y" --window-icon="$PW_GUI_ICON_PATH/portproton.svg" > /dev/null 2>&1 &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
        return 0
    fi
}

pw_update_pfx_cover_gui () {
    if check_gamescope_session ; then
        pw_start_progress_bar_cover
        return 0
    elif [[ "$1" == "winetricks" ]] ; then
        TAB_PLACE="--tab=${translations[TERMINAL]}!$PW_GUI_ICON_PATH/$TAB_SIZE.png --tab=${translations[LOGO]}!$PW_GUI_ICON_PATH/$TAB_SIZE.png"
        TAB_N1=2
        TAB_N2=1
        YAD_UNDECORATED=""
    else
        TAB_PLACE="--tab=${translations[LOGO]}!$PW_GUI_ICON_PATH/$TAB_SIZE.png --tab=${translations[TERMINAL]}!$PW_GUI_ICON_PATH/$TAB_SIZE.png"
        TAB_N1=1
        TAB_N2=2
        YAD_UNDECORATED="--undecorated"
    fi

    if ! check_start_from_steam \
    && ! pgrep -a yad | grep "yad_gui_pp --notebook --key=$PW_KEY_PROGRESS_BAR_UP" &>/dev/null
    then
        PW_KEY_PROGRESS_BAR_UP=$RANDOM
        PW_GIF_FILE="${COVERS_PATH}/update_prefix_${LANGUAGE_GIF}.gif"
        PW_GIF_SIZE_X=$(file "${PW_GIF_FILE}" | awk '{print $7 + 20}')
        PW_GIF_SIZE_Y=$(file "${PW_GIF_FILE}" | awk '{print $9 + 65}')
        echo "UPDATE PREFIX..." > "${PW_TMPFS_PATH}/update_pfx_log"
        local PW_TIMER=0
        while read -r line || [[ -n $(pgrep -a yad | grep "yad_gui_pp --notebook --key=$PW_KEY_PROGRESS_BAR_UP" | awk '{print $1}') ]] ; do
                sleep 0.005
                if [[ -n "${line}" ]] && ! echo "${line}" | grep -qi "gstreamer\|kerberos\|ntlm" ; then
                    echo "# ${line}"
                fi
                if [[ "${PW_TIMER}" != 1 ]] ; then
                    sleep 3
                    PW_TIMER=1
                fi
        done < "${PW_TMPFS_PATH}/update_pfx_log" | "${pw_yad}" --plug=$PW_KEY_PROGRESS_BAR_UP --tabnum=$TAB_N2 --text-info --tail  2>/dev/null &
        "${pw_yad}" --plug=$PW_KEY_PROGRESS_BAR_UP --tabnum=$TAB_N1 --picture --filename="${PW_GIF_FILE}" 2>/dev/null &

        "${pw_yad}" --notebook --key="$PW_KEY_PROGRESS_BAR_UP" $TAB_PLACE --no-buttons \
        --skip-taskbar --width="$PW_GIF_SIZE_X" --height="$PW_GIF_SIZE_Y" $YAD_UNDECORATED \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "PortProton" --tab-pos="bottom" --expand 2>/dev/null &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
        return 0
    fi
}

pw_start_progress_bar_cs () {
    if ! check_start_from_steam ; then
        "${pw_yad}" --progress-old --text="$@
        " --pulsate --hide-text --close-on-unfocus --borders="$PROGRESS_BAR_BORDERS_SIZE" \
        --no-buttons --undecorated --skip-taskbar \
        --width="$PROGRESS_BAR_WIDTH_SIZE" \
        --wrap-width="$PROGRESS_BAR_WIDTH_SIZE" \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" &>/dev/null &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
        return 0
    fi
}

pw_start_progress_bar_block () {
    if ! check_start_from_steam ; then
        "${pw_yad}" --progress-old --text="$@
        " --pulsate --hide-text --borders="$PROGRESS_BAR_BORDERS_SIZE" \
        --no-buttons --undecorated --skip-taskbar \
        --no-escape --text-align="center" --height=90 --fixed \
        --width="$PROGRESS_BAR_WIDTH_SIZE" \
        --wrap-width="$PROGRESS_BAR_WIDTH_SIZE" \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" &>/dev/null &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
        return 0
    fi
}

pw_start_progress_bar_install_game () {
    if ! check_start_from_steam ; then
        "${pw_yad}" --progress-old --text="${translations[Please wait. Installing the]} $@
        " --pulsate --hide-text --borders="$PROGRESS_BAR_BORDERS_SIZE" \
        --no-buttons --undecorated --skip-taskbar \
        --no-escape --text-align="center" --height=90 --fixed \
        --width="$PROGRESS_BAR_WIDTH_SIZE" \
        --wrap-width="$PROGRESS_BAR_WIDTH_SIZE" \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" &>/dev/null &
        PW_YAD_PID_PROGRESS_BAR_BLOCK+=($!)
        return 0
    fi
}

pw_stop_progress_bar () {
    if [[ -n ${PW_YAD_PID_PROGRESS_BAR_BLOCK[0]} ]] ; then
        local pid
        for pid in ${PW_YAD_PID_PROGRESS_BAR_BLOCK[@]} ; do
            # Здесь sleep нужен, потому что pid может уже быть, но kill его не убьет
            # со sleep 0.01 он делает 2 kill, c 0.02 нормально один
            while $(sleep 0.02) && [[ -f /proc/$pid/exe ]] ; do
                kill -s SIGUSR1 "$pid" &>/dev/null
            done
        done
        unset PW_YAD_PID_PROGRESS_BAR_BLOCK
    fi
}
export -f pw_stop_progress_bar

open_changelog () {
    [[ "$LANGUAGE" == ru ]] && local PW_CHANGELOG_FILE="changelog_ru" || local PW_CHANGELOG_FILE="changelog_en"
    "${pw_yad}" --title="${translations[CHANGELOG]}" --no-buttons \
    --text-info --show-uri --wrap --width=1200 --height=700 --uri-color=red \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --filename="${PORT_WINE_PATH}/data/${PW_CHANGELOG_FILE}" &>/dev/null
    YAD_STATUS="$?"

    if [[ "$YAD_STATUS" == "1" || "$YAD_STATUS" == "252" ]] && [[ -z "$WINEPREFIX" ]] ; then
        print_info "Restarting..."
        restart_pp
    else
        exit 0
    fi
}
export -f open_changelog

pw_tray_icon () {
    if [[ "$XDG_SESSION_TYPE" == "tty" ]] ; then
        if [[ -n "$(pgrep -a yad_gui_pp | grep "\--notification" | awk '{print $1}')" ]] ; then
            kill -s SIGUSR1 "$(pgrep -a yad_gui_pp | grep "\--notification" | awk '{print $1}')"
        fi
    else
        if [[ -n "$(pgrep -a tray_gui_pp)" ]] ; then
            kill -s SIGUSR1 $(pgrep -a tray_gui_pp) 2>/dev/null
        fi
    fi

    pw_tray_winefile () {
        pw_run winefile "C:\\users\\${USER}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\"
    }
    export -f pw_tray_winefile

    pw_tray_taskmgr () {
        pw_run taskmgr
    }
    export -f pw_tray_taskmgr

    tray_icon_click_exit () {
        pw_stop_progress_bar
        stop_portwine
    }
    export -f tray_icon_click_exit

    if [[ "$XDG_SESSION_TYPE" == "tty" ]] ; then
        tray_icon_click () {
            echo ""
        }
        export -f tray_icon_click
        "${pw_yad}" --notification --no-middle \
        --image="$PW_GUI_ICON_PATH/portproton_tray_flatpak.svg" \
        --command="bash -c tray_icon_click" \
        --tooltip="PortProton" \
        --icon-size=32 --menu="| \
        ${translations[WINEFILE]}!bash -c pw_tray_winefile!"$PW_GUI_ICON_PATH/wine_file.svg"|| \
        ${translations[TASKMGR]}!bash -c pw_tray_taskmgr!"$PW_GUI_ICON_PATH/wine_system.svg"|| \
        ${translations[CHANGELOG]}!bash -c open_changelog!"$PW_GUI_ICON_PATH/history.svg"|| \
        ${translations[FORCE EXIT]}!bash -c tray_icon_click_exit!"$PW_GUI_ICON_PATH/close.svg"||" 2>/dev/null &
    else
        PW_GUI_TRAY_PATH="${PW_GUI_THEMES_PATH}/tray"
        env LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" "${PW_GUI_TRAY_PATH}/tray_gui_pp" &
    fi

    return 0
}

# GUI GET OTHER WINE
gui_proton_downloader () {
    unset VERSION_WINE_GIT VERSION_INSTALLED_WINE URL_VERSION_PROTON_GIT GIVE_WINE_URL
    try_remove_file "${PW_TMPFS_PATH}/tmp_proton_pw_git"
    try_remove_file "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
    try_remove_file "${PW_TMPFS_PATH}/tmp_proton_ge_git"
    try_remove_file "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git"
    try_remove_file "${PW_TMPFS_PATH}/tmp_installed_wine"
    try_remove_file "${PW_TMPFS_PATH}/tmp_set_wine"

    if [[ "$PW_WINE_USE" == PROTON_LG ]]
    then PW_WINE_USE="${PW_PROTON_LG_VER}"
    elif [[ "$PW_WINE_USE" == WINE_*_LG ]] || [[ "$PW_WINE_USE" == WINE_LG ]]
    then PW_WINE_USE="${PW_WINE_LG_VER}"
    elif [[ "$1" == "silent" ]] && [[ -n "$2" ]]
    then PW_WINE_USE="$2"
    fi
    export PW_WINE_USE

    if [[ "$1" == "silent" ]] \
    && [[ -d "${PORT_WINE_PATH}/data/dist/${PW_WINE_USE}" ]] ; then
        return 0
    fi

    pw_start_progress_bar_block "${translations[Check new version WINE...]}"

    # PROTON_GE
    export PROTON_GE_GIT=($(curl -s "https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases" | grep "browser_download_url.*\.tar\.gz" | cut -d \" -f 4))
    if [[ -n "${PROTON_GE_GIT}" ]] ; then
        for PGEGIT in ${PROTON_GE_GIT[@]} ; do
            echo ${PGEGIT} | awk -F/ '{print $NF}' | sed 's/.tar.gz//' >> "${PW_TMPFS_PATH}/tmp_proton_ge_git"
        done
        sed -i '/Proton-6.5-GE-2/,$d' "${PW_TMPFS_PATH}/tmp_proton_ge_git"
        sed -i '/github-action/d' "${PW_TMPFS_PATH}/tmp_proton_ge_git"
        sed -i '/^$/d' "${PW_TMPFS_PATH}/tmp_proton_ge_git"
    fi

    # WINE_KRON4EK
    export WINE_KRON4EK=($(curl -s "https://api.github.com/repos/Kron4ek/Wine-Builds/releases" | grep "browser_download_url.*\.tar\.xz" | cut -d \" -f 4))
    if [[ -n "${WINE_KRON4EK}" ]] ; then
        for PGEGIT in ${WINE_KRON4EK[@]} ; do
            echo ${PGEGIT} | awk -F/ '{print $NF}' | sed 's/.tar.xz//' >> "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
        done
        sed -i '/6.3/,$d' "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
        sed -i '/-x86/d' "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
        sed -i '/-wow64/d' "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
        sed -i '/^$/d' "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
    fi

    # WINE_GE_CUSTOM
    export WINE_GE_CUSTOM=($(curl -s "https://api.github.com/repos/GloriousEggroll/wine-ge-custom/releases" | grep "browser_download_url.*\.tar\.xz" | cut -d \" -f 4))
    if [[ -n "${WINE_GE_CUSTOM}" ]] ; then
        for PGEGIT in ${WINE_GE_CUSTOM[@]} ; do
            echo ${PGEGIT} | awk -F/ '{print $NF}' | sed 's/.tar.xz//' >> "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git"
        done
        sed -i '/6.23/,$d' "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git"
        sed -i '/^$/d' "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git"
    fi

    # PROTON_LG
    export PROTON_PW_GIT=($(curl -s "https://api.github.com/repos/Castro-Fidel/wine_builds/releases" | grep "browser_download_url.*\.tar\.xz" | cut -d \" -f 4 | sort -r))
    if [[ -n "${PROTON_PW_GIT}" ]] ; then
        for PPWGIT in ${PROTON_PW_GIT[@]} ; do
            echo ${PPWGIT} | awk -F/ '{print $NF}' | sed 's/.tar.xz//' >> "${PW_TMPFS_PATH}/tmp_proton_pw_git"
        done
        sed -i /${PW_WINE_LG_VER}/d "${PW_TMPFS_PATH}/tmp_proton_pw_git"
        sed -i '/plugins/d' "${PW_TMPFS_PATH}/tmp_proton_pw_git"
        sed -i '/^$/d' "${PW_TMPFS_PATH}/tmp_proton_pw_git"
    fi
    pw_stop_progress_bar

    if [[ -z "${PROTON_PW_GIT}" ]] ; then
        yad_error "${translations[Error: check wine.]}"
        restart_pp
    fi

    pushd "${PORT_WINE_PATH}/data/dist/" || fatal
    for INSTALLING_VERSION_IN_DIST in * ; do
        sed -i "/${INSTALLING_VERSION_IN_DIST}$/Id" "${PW_TMPFS_PATH}/tmp_proton_pw_git"
        sed -i "/${INSTALLING_VERSION_IN_DIST}$/Id" "${PW_TMPFS_PATH}/tmp_proton_ge_git"
        sed -i "/${INSTALLING_VERSION_IN_DIST}$/Id" "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git"
        sed -i "/${INSTALLING_VERSION_IN_DIST}$/Id" "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git"
    done
    popd 1>/dev/null || fatal

    TMP_PROTON_PW_GIT="$(sed 's/^/FALSE /' "${PW_TMPFS_PATH}/tmp_proton_pw_git" | tr '\n' ' ')"
    TMP_PROTON_GE_GIT="$(sed 's/^/FALSE /' "${PW_TMPFS_PATH}/tmp_proton_ge_git" | tr '\n' ' ')"
    TMP_PROTON_KR_GIT="$(sed 's/^/FALSE /' "${PW_TMPFS_PATH}/tmp_wine_kron4ek_git" | tr '\n' ' ')"
    TMP_PROTON_CU_GIT="$(sed 's/^/FALSE /' "${PW_TMPFS_PATH}/tmp_wine_ge_custom_git" | tr '\n' ' ')"

    ls -l ${PORT_WINE_PATH}/data/dist | awk '{print $9}' | sed "/$PW_PROTON_LG_VER/d" | sed "/$PW_WINE_LG_VER/d" | sed '/^$/d' 1>${PW_TMPFS_PATH}/tmp_installed_wine
    TMP_INSTALLED_WINE="$(sed 's/^/FALSE /' "${PW_TMPFS_PATH}/tmp_installed_wine" | tr '\n' ' ')"

    if [[ "$1" != "silent" ]] ; then
        # GUI
        export KEY_WINE=$RANDOM

        "${pw_yad}" --plug=$KEY_WINE --tabnum=1 --list --checklist --separator="" \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --column "${translations[Set]}" \
        --column "${translations[Select WINE for download:]}" \
        $TMP_PROTON_PW_GIT \
        1>> "${PW_TMPFS_PATH}/tmp_set_wine" \
        2>/dev/null &

        "${pw_yad}" --plug=$KEY_WINE --tabnum=2 --list --checklist --separator="" \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --column "${translations[Set]}" \
        --column "${translations[Select WINE for download:]}" \
        $TMP_PROTON_KR_GIT \
        1>> "${PW_TMPFS_PATH}/tmp_set_wine" \
        2>/dev/null &

        "${pw_yad}" --plug=$KEY_WINE --tabnum=3 --list --checklist --separator="" \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --column "${translations[Set]}" \
        --column "${translations[Select WINE for download:]}" \
        $TMP_PROTON_GE_GIT \
        1>> "${PW_TMPFS_PATH}/tmp_set_wine" \
        2>/dev/null &

        "${pw_yad}" --plug=$KEY_WINE --tabnum=4 --list --checklist --separator="" \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --column "${translations[Set]}" \
        --column "${translations[Select WINE for download:]}" \
        $TMP_PROTON_CU_GIT \
        1>> "${PW_TMPFS_PATH}/tmp_set_wine" \
        2>/dev/null &

        "${pw_yad}" --plug=$KEY_WINE --tabnum=5 --list --checklist --separator="" \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --column "${translations[Set]}" \
        --column "${translations[Select installed WINE for delete:]}" \
        $TMP_INSTALLED_WINE \
        1> "${PW_TMPFS_PATH}/tmp_installed_wine_set" \
        2>/dev/null &

        "${pw_yad}" --key=$KEY_WINE --notebook --width=500 --height=600 --text-align=center \
        --gui-type="settings-notebook" \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "${translations[WINE MANAGER]}" --separator="" --expand \
        --tab-pos="top" \
        --tab="PROTON-LG"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="WINE-KRON4EK"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="PROTON-GE"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="WINE-GE-CUSTOM"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="${translations[INSTALLED]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":1 \
        --button="${translations[OK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":0 2>/dev/null
        YAD_WINE_STATUS="$?"
        if [[ "$YAD_WINE_STATUS" == "1" || "$YAD_WINE_STATUS" == "252" ]] ; then
            restart_pp
        fi
        if [[ -n $(<"${PW_TMPFS_PATH}/tmp_set_wine") ]] ; then
            VERSION_WINE_GIT="$(sed 's/TRUE//' "${PW_TMPFS_PATH}/tmp_set_wine")"
        fi
        if [[ -n $(<"${PW_TMPFS_PATH}/tmp_installed_wine_set") ]] ; then
            VERSION_INSTALLED_WINE="$(sed 's/TRUE//' "${PW_TMPFS_PATH}/tmp_installed_wine_set")"
        fi

        if [[ -z "${VERSION_WINE_GIT}" ]] \
        && [[ -z "${VERSION_INSTALLED_WINE}" ]]
        then
            print_info "Nothing to do."
            restart_pp
        fi

    elif [[ "$1" == "silent" ]] && [[ -n "$2" ]] ; then
        VERSION_WINE_GIT="$2"
    fi

    pw_download_get_wine () {
        print_info "Download and install ${VERSION_WINE_GIT}..."
        FILENAME="$(basename "${URL_VERSION_PROTON_GIT}")"
        if [[ "${URL_VERSION_PROTON_GIT}" =~ _LG ]]
        then USE_MIRROR=""
        else USE_MIRROR="no_mirror"
        fi
        if try_download "${URL_VERSION_PROTON_GIT}" "${PORT_WINE_PATH}/data/tmp/$FILENAME" "$USE_MIRROR" ; then
            if unpack "${PORT_WINE_PATH}/data/tmp/${FILENAME}" "${PORT_WINE_PATH}/data/dist/" ; then
                try_remove_file "${PORT_WINE_PATH}/data/tmp/${FILENAME}"
                if [[ -n "${portwine_exe}" ]] ; then
                    PW_WINE_USE="$(echo "${VERSION_WINE_GIT}" | tr [[:lower:]] [[:upper:]])"
                    edit_db_from_gui PW_WINE_USE
                fi
            else
                try_remove_file "${PORT_WINE_PATH}/data/tmp/${FILENAME}"
                try_remove_dir "${PORT_WINE_PATH}/data/dist/${FILENAME}"
                if yad_error_download
                then gui_proton_downloader ""
                else
                    export PW_WINE_VER="$PW_WINE_USE"
                    init_wine_ver
                fi
            fi
        else
            if yad_error_download
            then gui_proton_downloader ""
            else
                export PW_WINE_VER="$PW_WINE_USE"
                init_wine_ver
            fi
        fi
    }

    if [[ -n "${VERSION_INSTALLED_WINE}" ]] ; then
        for REMOVE_WINE in ${VERSION_INSTALLED_WINE} ; do
            try_remove_dir "${PORT_WINE_PATH}/data/dist/${REMOVE_WINE}"
        done
        if [[ -z "${VERSION_WINE_GIT}" ]] ; then
            restart_pp
        fi
    fi

    if [[ "$1" != "silent" ]] ; then
        for GIVE_ALL_WINE in ${VERSION_WINE_GIT} ; do
            for GIVE_WINE_URL in ${WINE_GE_CUSTOM[@]} ${PROTON_GE_GIT[@]} ${WINE_KRON4EK[@]} ${PROTON_PW_GIT[@]} ; do
                if [[ -n $(echo ${GIVE_WINE_URL} | grep -i "${GIVE_ALL_WINE}") ]] ; then
                    export URL_VERSION_PROTON_GIT="${GIVE_WINE_URL}"
                fi
            done
            pw_download_get_wine ""
        done
        edit_db_from_gui
        restart_pp
    else
        print_error "$PW_WINE_USE"
        for GIVE_WINE_URL in ${WINE_GE_CUSTOM[@]} ${PROTON_GE_GIT[@]} ${WINE_KRON4EK[@]} ${PROTON_PW_GIT[@]} ; do
            if [[ -n $(echo ${GIVE_WINE_URL} | grep -i "${PW_WINE_USE}") ]] ; then
                export URL_VERSION_PROTON_GIT="${GIVE_WINE_URL}"
            fi
        done
        pw_download_get_wine ""
    fi
}
export -f gui_proton_downloader

# GUI EDIT_DB
gui_edit_db () {
    KEY_EDIT_DB_GUI=$RANDOM
    PW_EDIT_DB_LIST=(PW_MANGOHUD PW_MANGOHUD_USER_CONF PW_VKBASALT PW_VKBASALT_USER_CONF PW_DGVOODOO2 PW_GAMESCOPE
    PW_NO_ESYNC PW_NO_FSYNC PW_USE_RAY_TRACING PW_USE_NVAPI_AND_DLSS PW_USE_FAKE_DLSS PW_WINE_FULLSCREEN_FSR
    PW_HIDE_NVIDIA_GPU PW_VIRTUAL_DESKTOP PW_USE_TERMINAL PW_GUI_DISABLED_CS PW_USE_GAMEMODE PW_USE_D3D_EXTRAS
    PW_FIX_VIDEO_IN_GAME PW_REDUCE_PULSE_LATENCY PW_USE_US_LAYOUT PW_USE_GSTREAMER PW_FORCE_LARGE_ADDRESS_AWARE
    PW_USE_SHADER_CACHE PW_USE_WINE_DXGI PW_USE_EAC_AND_BE PW_USE_SYSTEM_VK_LAYERS PW_USE_OBS_VKCAPTURE
    PW_DISABLE_COMPOSITING PW_USE_RUNTIME PW_DINPUT_PROTOCOL PW_USE_NATIVE_WAYLAND
    )
    # PW_USE_FAKE_DLSS_3

    if check_wayland_session ; then
        rm_from_array "PW_EDIT_DB_LIST" PW_USE_US_LAYOUT
    else
        rm_from_array "PW_EDIT_DB_LIST" PW_USE_NATIVE_WAYLAND
    fi

    if check_flatpak ; then
        rm_from_array "PW_EDIT_DB_LIST" PW_USE_RUNTIME
    fi
    # PW_HEAP_DELAY_FREE

    PW_DGVOODOO2_INFO=${translations[Enable dgVoodoo2. Forced use all dgVoodoo2 libs (Glide 2.11-3.1, DirectDraw 1-7, Direct3D 2-9) on all 3D API. For WineD3D OpenGL need use WineLG (For Gallium Nine and Zink use too)]}
    PW_DINPUT_PROTOCOL_INFO=${translations[Force use DirectInput protocol instead of XInput]}
    PW_USE_NATIVE_WAYLAND_INFO=${translations[Enable experemental native Wayland support (need special wine build to work)]}
    PW_VKBASALT_INFO=${translations[Enable vkBasalt by default to improve graphics in games running on Vulkan. (The HOME hotkey disables vkbasalt)]}
    PW_NO_ESYNC_INFO=${translations[Do not use in-process synchronization primitives based on eventfd. (It is recommended not to change the value.)]}
    PW_NO_FSYNC_INFO=${translations[Do not use futex-based in-process synchronization primitives. (Automatically disabled on systems without FUTEX_WAIT_MULTIPLE support) (It is recommended not to change the value)]}
    PW_USE_RAY_TRACING_INFO=${translations[Enable vkd3d support - Ray Tracing]}
    PW_FIX_VIDEO_IN_GAME_INFO=${translations[Required for video playback in some games so that it is not distorted (usually colored pink)]}
    PW_VULKAN_NO_ASYNC_INFO=${translations[Disable asynchronous calls for VULKAN and DXVK modes]}
    PW_USE_NVAPI_AND_DLSS_INFO=${translations[Enable DLSS on supported NVIDIA graphics cards]}
    PW_OLD_GL_STRING_INFO=${translations[Forced use of older versions of OpenGL]}
    PW_HIDE_NVIDIA_GPU_INFO=${translations[Disguise all features used for NVIDIA graphics cards]}
    PW_VIRTUAL_DESKTOP_INFO=${translations[Enable the application to run in the WINE virtual desktop]}
    PW_USE_TERMINAL_INFO=${translations[Run the application in the terminal]}
    PW_HEAP_DELAY_FREE_INFO=${translations[Include a delay in releasing some memory to bypass errors associated with using the application after the memory is released]}
    PW_NO_WRITE_WATCH_INFO=${translations[A very dangerous way to hack the memory write timer in ntdll. This improves the performance of some very specific games. (It is recommended not to change the value.)]}
    PW_GUI_DISABLED_CS_INFO=${translations[Disable the window for selecting startup modes and WINE versions]}
    PW_USE_GSTREAMER_INFO=${translations[Use Gstreamer to output clips in games (WMF support)]}
    PW_FORCE_LARGE_ADDRESS_AWARE_INFO=${translations[Increases RAM usage limits for 32-bit applications from two to four gigabytes]}
    PW_USE_RUNTIME_INFO=${translations[Use container launch mode (It is recommended not to change the value)]}
    PW_MANGOHUD_INFO=${translations[Using FPS and system load monitoring (Turns on and off by the key combination - right Shift + F12)]}
    PW_USE_GAMEMODE_INFO=${translations[Using automatic system optimization to improve performance in games (provided the gamemode package is installed on the system, doesn\'t work with ananicy)]}
    PW_USE_WINE_DXGI_INFO=${translations[Forced use of built-in DXGI library (in rare cases it solves problems with DX12 games)]}
    PW_MANGOHUD_USER_CONF_INFO=${translations[Forced use of MANGOHUD system settings (GOverlay, etc.)]}
    PW_VKBASALT_USER_CONF_INFO=${translations[Forced use of VKBASALT system settings (GOverlay, etc.)]}
    PW_USE_D3D_EXTRAS_INFO=${translations[Enable forced use of third-party DirectX libraries]}
    PW_USE_WINDOWS_7_INFO=${translations[Change the version of WINDOWS 10 to WINDOWS 7 in the prefix]}
    PW_USE_SHADER_CACHE_INFO=${translations[Use WINE shader caching (disable only if there are microfreezes in the game)]}
    PW_WINE_FULLSCREEN_FSR_INFO=${translations[Works while using any version of ProtonGE in full screen mode at a resolution below the standard screen]}
    PW_USE_FAKE_DLSS_INFO=${translations[Enable DLSS translator in FSR 2 in DirectX 12 games (CyberFSR2)]}
    PW_USE_EAC_AND_BE_INFO=${translations[Enable Easy Anti-Cheat and BattlEye Anti-Cheat runtimes (required if game used this anti-cheats)]}
    PW_REDUCE_PULSE_LATENCY_INFO=${translations[Reduce pulseaudio latency to fix intermittent sound]}
    PW_USE_US_LAYOUT_INFO=${translations[Forced use of the us layout (useful for games in which the control works correctly only on the us layout)]}
    PW_RESTORE_RESOLUTION_INFO=${translations[Remember the screen resolution when starting the game and return it when closing (useful for games that change the screen resolution when closing)]}
    PW_USE_SYSTEM_VK_LAYERS_INFO=${translations[Use system mangohud, vkBasalt, obs-vkcapture and other applications using vulkan layers]}
    PW_USE_OBS_VKCAPTURE_INFO=${translations[Enable the ability to write to OBS Studio using obs-vkcapture (ATTENTION: the forced use of system mangohud, vkBasalt, obs-vkcapture and other applications using vulkan layers will be enabled)]}
    PW_DISABLE_COMPOSITING_INFO=${translations[Disable desktop compositing (effects). It often improves performance.]}
    PW_GAMESCOPE_INFO=${translations[<b>Super + F :</b> Toggle fullscreen
<b>Super + N :</b> Toggle nearest neighbour filtering
<b>Super + U :</b> Toggle FSR upscaling
<b>Super + Y :</b> Toggle NIS upscaling
<b>Super + I :</b> Increase FSR sharpness by 1
<b>Super + O :</b> Decrease FSR sharpness by 1
<b>Super + S :</b> Take screenshot (currently goes to /tmp/gamescope_DATE.png)
<b>Super + G :</b> Toggle keyboard grab
<b>Super + C :</b> Update clipboard]}

    case "${PW_VULKAN_USE}" in
        0)
            # WineD3D OpenGL
            VKD3D_CB="DCB"
            DISABLE_EDIT_DB_LIST="PW_VKBASALT PW_VKBASALT_USER_CONF PW_USE_RAY_TRACING PW_USE_OBS_VKCAPTURE
            "
            ;;
        1|2)
            # Stable, Newest
            VKD3D_CB="CB"
            ;;
        3)
            # Gallium Nine
            VKD3D_CB="DCB"
            DISABLE_EDIT_DB_LIST="PW_MANGOHUD PW_MANGOHUD_USER_CONF PW_VKBASALT PW_VKBASALT_USER_CONF PW_USE_RAY_TRACING PW_WINE_FULLSCREEN_FSR
            PW_USE_SYSTEM_VK_LAYERS PW_USE_OBS_VKCAPTURE
            "
            ;;
        4|5|6)
            # Galliun Zink, Legacy, WineD3D Vulkan
            VKD3D_CB="DCB"
            DISABLE_EDIT_DB_LIST="PW_USE_RAY_TRACING
            "
            ;;
    esac

    unset ADD_CHK_BOX_EDIT_DB
    for int_to_boole in ${PW_EDIT_DB_LIST[@]} ; do
        if [[ "${!int_to_boole}" == "1" ]]
        then export ${int_to_boole}="TRUE"
        else export ${int_to_boole}="FALSE"
        fi
        TMP_HELP_FOR_GUI="${int_to_boole}_INFO"
        int_to_boole_non_pw="${int_to_boole//PW_/}"
        int_to_boole_non_pw="${int_to_boole_non_pw//"_"/" "}"
        if [[ ! "${PW_VULKAN_USE}" == [12] ]] \
        && [[ "${DISABLE_EDIT_DB_LIST}" =~ ${int_to_boole} ]]
        then ADD_CHK_BOX_EDIT_DB+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:D${THEME_CHKBOX}%${!int_to_boole}%"
        else ADD_CHK_BOX_EDIT_DB+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:${THEME_CHKBOX}%${!int_to_boole}%"
        fi
    done

    IFS="%"
    "${pw_yad}" --plug=$KEY_EDIT_DB_GUI --tabnum="1" --form --separator=" " --columns=3 ${ADD_CHK_BOX_EDIT_DB} \
    1> "${PW_TMPFS_PATH}/tmp_output_yad_edit_db" 2>/dev/null &
    IFS="$orig_IFS"

    case ${PW_WINDOWS_VER} in
         "7") ADD_WINVER_EDIT_DB="7!10!11!XP" ;;
        "XP") ADD_WINVER_EDIT_DB="XP!7!10!11" ;;
        "10") ADD_WINVER_EDIT_DB="10!11!7!XP" ;;
           *) ADD_WINVER_EDIT_DB="11!10!7!XP" ;;
    esac

    if [[ "${PW_WINE_CPU_TOPOLOGY}" == *[0-9]:* ]] \
    && [[ "${PW_WINE_CPU_TOPOLOGY}" != "disabled" ]]
    then
        CPU_LIMIT_VAR="${PW_WINE_CPU_TOPOLOGY%%:*}"
    else
        CPU_LIMIT_VAR="disabled"
    fi

    "${pw_yad}" --plug=$KEY_EDIT_DB_GUI --tabnum="2" --form --separator="%" --columns=1 \
    --field="${translations[Change the version of <b>WINDOWS</b> emulation]}!${translations[Changing the <b>WINDOWS</b> emulation version may be required to run older games. <b>WINDOWS</b> versions below 10 do not support new games with DirectX 12]} :CB" "${ADD_WINVER_EDIT_DB}" \
    --field="${translations[AUTOINSTALL WITH <b>WINETRICKS</b>]}!${translations[Automatically install with <b>WINETRICKS</b> additional libraries required to run the game/program. List of libraries separated by spaces]} :CBE" "$(combobox_fix --empty "${PW_DLL_INSTALL}" "vcrun2019 corefonts lucida")" \
    --field="${translations[Forced to use/disable libraries]}!${translations[Forced to use/disable the library only for the given application. (There are examples in the drop-down list)

A brief instruction:
    * libraries are written <b>WITHOUT</b> the .dll file extension
    * libraries are separated by semicolons - <b>;</b>
    * library=n - use the <b>WINDOWS</b> (third-party) library
    * library=b - use <b>WINE</b> (built-in) library
    * library=n,b - use <b>WINDOWS</b> library and then <b>WINE</b>
    * library=b,n - use <b>WINE</b> library and then <b>WINDOWS</b>
    * library= - disable the use of this library]} :CBE" "$(combobox_fix --empty "${WINEDLLOVERRIDES}" "libglesv2=!d3dx9_36,d3dx9_42=n,b;mfc120=b,n")" \
    --field=":LBLH" "" \
    --field="${translations[ADD ARGUMENTS FOR .EXE FILE]}!${translations[Adding an argument after the <b>.exe</b> file, just like you would add an argument in a shortcut on a <b>WINDOWS </b> system]} :CBE" "$(combobox_fix --empty "\\${LAUNCH_PARAMETERS[@]}" "-dx11 -skipintro 1")" \
    --field=":LBLH" "" \
    --field="${translations[Limit the use of processor cores]}!${translations[Limiting the number of CPU cores is useful for Unity games (It is recommended to set the value equal to 8)]} :CB" "$(combobox_fix --disabled "${CPU_LIMIT_VAR}" "${GET_LOGICAL_CORE}")" \
    --field="${translations[Forcibly select the OpenGL version for the game]}!${translations[You can select the required OpenGL version, some games require a forced Compatibility Profile (COMPAT). (Examples are in the drop-down list)]} :CB" "$(combobox_fix --disabled "${PW_MESA_GL_VERSION_OVERRIDE}" "4.6COMPAT!4.5COMPAT!4.3COMPAT!4.1COMPAT!3.3COMPAT!3.2COMPAT")" \
    --field="${translations[Forcibly select the VKD3D feature level]}!${translations[You can set a forced feature level VKD3D for games on DirectX12]} :$VKD3D_CB" "$(combobox_fix --disabled "${PW_VKD3D_FEATURE_LEVEL}" "12_2!12_1!12_0!11_1!11_0")" \
    --field="${translations[Force certain locale for an app:]}!${translations[Fixes encoding issues in legacy software]} :CB" "$(combobox_fix --disabled "${PW_LOCALE_SELECT}" "$LOCALE_LIST")" \
    --field="${translations[Window mode (for Vulkan and OpenGL)]}!${translations[fifo - First in, first out. Limits the frame rate + no tearing. (VSync)
immediate - Unlimited frame rate + tearing.
mailbox - Triple buffering. Unlimited frame rate + no tearing.
relaxed - Same as fifo but allows tearing when below the monitors refresh rate.]} :CB" "$(combobox_fix --disabled "${PW_MESA_VK_WSI_PRESENT_MODE}" "fifo!immediate!mailbox!relaxed")" \
    1> "$PW_TMPFS_PATH/tmp_output_yad_fps_limit" 2>/dev/null &

    "${pw_yad}" --notebook --key="$KEY_EDIT_DB_GUI" --title "${translations[EDIT DB]}" --text-align=center \
    --text "${translations[Change settings in database file for]} <b>$PW_NAME_DESKTOP_PROXY</b>\n ${translations[<b>NOTE:</b> To display help for each item, simply hover your mouse over the text]}" \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --separator=" " --expand \
    --gui-type="settings-base" \
    --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" \
    --tab="${translations[MAIN]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
    --tab="${translations[ADVANCED]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
    --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
    --button="${translations[RESET SETTINGS]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings]}":2 \
    --button="${translations[OPEN THE SETTINGS FILE]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Open the <b>.ppdb</b> settings file in a system text editor to view and change variables manually]}":150 \
    --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":0 2>/dev/null
    YAD_STATUS="$?"

    case "$YAD_STATUS" in
        1|252)
            restart_pp
            ;;
        2)
            try_remove_file "$portwine_exe".ppdb
            restart_pp
            ;;
        150)
            gui_edit_db_file
            ;;
    esac

    output_yad_edit_db=($(<"${PW_TMPFS_PATH}/tmp_output_yad_edit_db"))
    bool_from_yad="0"
    for boole_to_int in ${PW_EDIT_DB_LIST[@]} ; do
        export ${boole_to_int}="${output_yad_edit_db[$bool_from_yad]}"
        if [[ "${!boole_to_int}" == "TRUE" ]]
        then export ${boole_to_int}="1"
        else export ${boole_to_int}="0"
        fi
        export bool_from_yad=$(( bool_from_yad + 1 ))
    done

    IFS='%' read -r -a PW_ADD_SETTINGS <"${PW_TMPFS_PATH}/tmp_output_yad_fps_limit"
    IFS="$orig_IFS"
    PW_WINDOWS_VER="${PW_ADD_SETTINGS[0]}"
    PW_DLL_INSTALL="${PW_ADD_SETTINGS[1]}"
    WINEDLLOVERRIDES="${PW_ADD_SETTINGS[2]}"
    LAUNCH_PARAMETERS="${PW_ADD_SETTINGS[4]}"
    CPU_LIMIT="${PW_ADD_SETTINGS[6]}"
    PW_MESA_GL_VERSION_OVERRIDE="${PW_ADD_SETTINGS[7]}"
    PW_VKD3D_FEATURE_LEVEL="${PW_ADD_SETTINGS[8]}"
    PW_LOCALE_SELECT="${PW_ADD_SETTINGS[9]}"
    PW_MESA_VK_WSI_PRESENT_MODE="${PW_ADD_SETTINGS[10]}"

    if [[ "${CPU_LIMIT}" =~ [0-9]+ ]] ; then
        PW_WINE_CPU_TOPOLOGY="${CPU_LIMIT}:$(seq -s, 0 $(( CPU_LIMIT - 1 )))"
    else
        PW_WINE_CPU_TOPOLOGY="disabled"
    fi
    export PW_WINE_CPU_TOPOLOGY

    edit_db_from_gui ${PW_EDIT_DB_LIST[@]} LAUNCH_PARAMETERS PW_WINDOWS_VER PW_DLL_INSTALL WINEDLLOVERRIDES PW_WINE_CPU_TOPOLOGY \
    PW_MESA_GL_VERSION_OVERRIDE PW_VKD3D_FEATURE_LEVEL PW_LOCALE_SELECT PW_MESA_VK_WSI_PRESENT_MODE

    if [[ -z "$MANGOHUD_CONFIG" ]] ; then
        MONITOR_HEIGHT="$(echo "$PW_SCREEN_RESOLUTION" | awk -F'x' '{print $2}')"
        MH_FONT_SIZE="font_size=$(( MONITOR_HEIGHT / 45 ))"

        if [[ -n "$MH_FONT_SIZE" ]]
        then MANGOHUD_CONFIG="$DEFAULT_MANGOHUD_CONFIG,$MH_FONT_SIZE"
        else MANGOHUD_CONFIG="$DEFAULT_MANGOHUD_CONFIG"
        fi

        edit_db_from_gui MANGOHUD_CONFIG
    fi

    if [[ "$YAD_STATUS" == "0" ]] ; then
        print_info "Restarting PP after update ppdb file..."
        restart_pp
    fi
}

# GUI VKBASALT
gui_vkbasalt () {
    KEY_FX_GUI=$RANDOM
    FILE_VKBASALT_CONF="${PORT_WINE_PATH}/data/vkBasalt.conf"
    LIST_FX=($(grep -E '.fx$|.fxh$' "${FILE_VKBASALT_CONF}" | awk '{print $1}'))
    GET_FX_IN_FILE=($(echo ${PW_VKBASALT_EFFECTS} | sed s/"cas:"// | sed s/":"/" "/g))

    PW_3DFX_INFO=${translations[Simulation of an old 3dfx graphics accelerator (adds horizontal stripes)]}
    PW_AdaptiveSharpen_INFO=${translations[Sharpness increase, can be used with CAS]}
    PW_Bloom_INFO=${translations[Adds glow from bright light sources in the game]}
    PW_Border_INFO=${translations[Cropping the image from the top and bottom (like in a movie =)]}
    PW_Cartoon_INFO=${translations[Strong sharpening of texture edges]}
    PW_ChromaticAberration_INFO=${translations[Adds chromatic aberration to an image]}
    PW_Clarity_INFO=${translations[Sharpening textures with slight modifications of image contrast (similar in effect to CAS)]}
    PW_ColorMatrix_INFO=${translations[Adding cool colors]}
    PW_Colourfulness_INFO=${translations[Increasing color saturation]}
    PW_FakeHDR_INFO=${translations[Add fake HDR]}
    PW_FilmGrain2_INFO=${translations[Adding the film grain effect]}
    PW_Curves_INFO=${translations[Increases the contrast of the image without affecting the bright and dark areas, so that the detail in shadows and sky is not lost]}
    PW_Denoise_INFO=${translations[Reducing noise by blurring the image]}
    PW_Emphasize_INFO=${translations[Reducing the bit depth of color]}
    PW_FakeMotionBlur_INFO=${translations[Strong blurring of objects in motion]}
    PW_FilmicAnamorphSharpen_INFO=${translations[Sharpening (recommended for cartoon games)]}
    PW_FilmicPass_INFO=${translations[Adding cold colors]}
    PW_SMAA_INFO=${translations[Alternative antialiasing option (less effect, but with less consumption of GPU resources, relative to the standard SMAA)]}
    PW_GaussianBlur_INFO=${translations[Slight blur effect on bright objects (such as flames)]}
    PW_Glitch_INFO=${translations[Glitch effect]}
    PW_HighPassSharpen_INFO=${translations[Another method of sharpening using highpass frequencies]}
    PW_HQ4X_INFO=${translations[Smoothing of nearby pixels with the drawing of missing parts (in normal games the picture is blurred)]}
    PW_HSLShift_INFO=${translations[Advanced HSL shift (for each shade)]}
    PW_Layer_INFO=${translations[Image overlay on the game]}
    PW_Levels_INFO=${translations[Increases contrast, but some detail in shadows or highlights may be lost]}
    PW_LevelsPlus_INFO=${translations[Same as Levels, but with less loss of detail]}
    PW_LiftGammaGain_INFO=${translations[Gamma correction by individual color channels: red, green and blue]}
    PW_LightDoF_INFO=${translations[Increases depth of field (greatly affects FPS)]}
    PW_LumaSharpen_INFO=${translations[Enhances image sharpness for improved detail]}
    PW_LUT_INFO=${translations[Image color correction]}
    PW_MagicBloom_INFO=${translations[Same as Bloom, but more natural]}
    PW_Monochrome_INFO=${translations[Converts the image into monochrome]}
    PW_MultiLUT_INFO=${translations[Extended version of the LUT (Hollywood loot is pre-installed)]}
    PW_MXAO_INFO=${translations[SSAO algorithm (Greatly affects FPS)]}
    PW_NightVision_INFO=${translations[Night vision effect]}
    PW_Nostalgia_INFO=${translations[Makes the picture look like old photos]}
    PW_PerfectPerspective_INFO=${translations[Fisheye effect (suitable for VR)]}
    PW_PPFX_Godrays_INFO=${translations[Add God rays (also called 3D light rays) effect]}
    PW_Prism_INFO=${translations[The prismatic lens effect]}
    PW_ReflectiveBumpMapping_INFO=${translations[Creates the illusion of depth in textures]}
    PW_Sepia_INFO=${translations[Adds a sepia effect like in old photos]}
    PW_Splitscreen_INFO=${translations[Splits the image into raw and processed output for comparison]}
    PW_SurfaceBlur_INFO=${translations[Reducing object detail without blurring contrast contours]}
    PW_Technicolor_INFO=${translations[Makes the picture look like films from the 1930s]}
    PW_Technicolor2_INFO=${translations[The updated version of Technicolor, gives a different picture by changing colors more aggressively]}
    PW_TiltShift_INFO=${translations[Blur on the edges of the screen to create a Tilt Shift effect]}
    PW_Tonemap_INFO=${translations[Changes the saturation of the picture]}
    PW_TriDither_INFO=${translations[Reduces the amount of noise]}
    PW_UIDetect_INFO=${translations[Automatically switches effects depending on the visibility of the UI]}
    PW_Vibrance_INFO=${translations[Saturates faded colors without touching the bright ones]}
    PW_Vignette_INFO=${translations[Adds a vignette to the image]}
    PW_AspectRatio_INFO=${translations[An effect for adjusting the aspect ratio (for games that do not support widescreen monitors)]}
    PW_UIMask_INFO=${translations[Part of the overall ReShade shader . It uses a mask with gradients from black to white to determine where the effects will be applied]}
    PW_StageDepth_INFO=${translations[Allows you to add new elements to the 3d space inside the game and apply custom textures]}
    PW_PPFX_Bloom_INFO=${translations[Adds a Bloom effect]}

    unset ADD_GUI_FX GUI_FX_RESULT
    for add_list_fx in ${LIST_FX[@]} ; do
        PW_VKBASALT_GUI_HELP="PW_${add_list_fx}_INFO"
        if [[ ${GET_FX_IN_FILE[*]} =~ ${add_list_fx} ]]; then
            ADD_GUI_FX+="--field=${CHKBOX_SPACE}${add_list_fx}!${!PW_VKBASALT_GUI_HELP}:${THEME_CHKBOX}%TRUE%"
        else
            ADD_GUI_FX+="--field=${CHKBOX_SPACE}${add_list_fx}!${!PW_VKBASALT_GUI_HELP}:${THEME_CHKBOX}%FALSE%"
        fi
    done

    case "$PW_VKBASALT_FFX_CAS" in
        0|-1) VKBASALT_FFX_CAS_GUI="0" ;;
           1) VKBASALT_FFX_CAS_GUI="100" ;;
        0.0*) VKBASALT_FFX_CAS_GUI="$(echo "$PW_VKBASALT_FFX_CAS" | awk -F'0.0' '{print $2}')" ;;
           *) VKBASALT_FFX_CAS_GUI="$(echo "$PW_VKBASALT_FFX_CAS" | awk -F'0.' '{print $2}')" ;;
    esac
    export VKBASALT_FFX_CAS_GUI

    IFS="%"
    "${pw_yad}" --plug=$KEY_FX_GUI --tabnum="1" --form --columns=4 --separator=" " \
    --text-align=center --text="${translations[VkBasalt settings for adding effects to games running under Vulkan. (The <b>HOME</b> key disables vkbasalt)\\n<b>NOTE:</b> To display help for each item, simply hover over the text]}" \
    --gui-type-text="${PANED_GUI_TYPE_TEXT_UP}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_UP}" \
    ${ADD_GUI_FX} 1> "${PW_TMPFS_PATH}/tmp_yad_basalt_set" 2>/dev/null &
    IFS="$orig_IFS"

    "${pw_yad}" --plug=$KEY_FX_GUI --tabnum="2" --separator=" " --form \
    --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_DOWN}" \
    --field="AMD FidelityFX - Contrast Adaptive Sharpening"!"${translations[AMD FidelityFX - CAS is designed to dramatically improve texture sharpness without additional modification settings for games, with minimal loss of performance. (For older games it is recommended to set value = 100)]}":SCL "${VKBASALT_FFX_CAS_GUI}" \
    1> "${PW_TMPFS_PATH}/tmp_yad_cas_set" 2>/dev/null &

    "${pw_yad}" --paned --key="$KEY_FX_GUI" --sensitive --title="vkBasalt" \
    --gui-type="settings-paned" \
    --separator=" " --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
    --button="${translations[RESET]} VKBASALT"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings for]} vkBasalt":178 \
    --button="${translations[DISABLE]} VKBASALT"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Disable vkBasalt and go to the previous menu]}":180 \
    --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":182 2>/dev/null
    YAD_VKBASALT_STATUS="$?"

    case "${YAD_VKBASALT_STATUS}" in
        1|252)
            restart_pp
            ;;
        178)
            sed -i '/VKBASALT/d' "$portwine_exe".ppdb
            restart_pp
            ;;
        180)
            export PW_VKBASALT="0"
            ;;
        182)
            export PW_VKBASALT="1"
            ;;
    esac
    YAD_BASALT_SET=$(<"${PW_TMPFS_PATH}/tmp_yad_basalt_set")
    YAD_CAS_SET=$(sed s/" "//g "${PW_TMPFS_PATH}/tmp_yad_cas_set")

    INT_COUNT_FX=0
    for read_list_fx in ${YAD_BASALT_SET} ; do
        if [[ "$read_list_fx" == "TRUE" ]] ; then
            export GUI_FX_RESULT+="${LIST_FX[$INT_COUNT_FX]}:"
        fi
        ((INT_COUNT_FX++))
    done
    GUI_FX_RESULT="${GUI_FX_RESULT}cas"
    export PW_VKBASALT_EFFECTS="${GUI_FX_RESULT}"

    if [[ "$YAD_CAS_SET" == "0" ]]
    then export PW_VKBASALT_FFX_CAS="-1"
    elif [[ "$YAD_CAS_SET" == "100" ]]
    then export PW_VKBASALT_FFX_CAS="1"
    elif [[ "$YAD_CAS_SET" -lt 10 ]]
    then export PW_VKBASALT_FFX_CAS="0.0$YAD_CAS_SET"
    else export PW_VKBASALT_FFX_CAS="0.$YAD_CAS_SET"
    fi

    edit_db_from_gui PW_VKBASALT_EFFECTS PW_VKBASALT_FFX_CAS PW_VKBASALT
    restart_pp
}

# GUI MANGOHUD
gui_mangohud () {
    KEY_MH_GUI=$RANDOM
    LIST_MH=(
        ARCH BATTERY BATTERY_ICON BATTERY_TIME BATTERY_WATT CORE_BARS CORE_LOAD
        CPU_MHZ CPU_POWER CPU_TEMP DEVICE_BATTERY_ICON ENGINE_SHORT_NAMES
        ENGINE_VERSION EXEC_NAME FCAT FPS_METRICS FRAME_COUNT FRAMETIME FULL
        GAMEMODE GPU_CORE_CLOCK GPU_FAN GPU_JUNCTION_TEMP GPU_MEM_CLOCK
        GPU_MEM_TEMP GPU_NAME GPU_POWER GPU_TEMP GPU_VOLTAGE HISTOGRAM HORIZONTAL
        HORIZONTAL_STRETCH HUD_COMPACT HUD_NO_MARGIN IO_READ IO_WRITE NO_DISPLAY
        NO_SMALL_FONT PROCMEM PROCMEM_SHARED PROCMEM_VIRT RAM RESOLUTION
        SHOW_FPS_LIMIT SWAP TEMP_FAHRENHEIT THROTTLING_STATUS THROTTLING_STATUS_GRAPH
        TIME VERSION VKBASALT VRAM VULKAN_DRIVER WINE
    )

    PW_MH_ARCH_INFO=${translations[Show if the application is 32- or 64-bit]}
    PW_MH_BATTERY_INFO=${translations[Display current battery percent and energy consumption]}
    PW_MH_BATTERY_ICON_INFO=${translations[Display battery icon instead of percent]}
    PW_MH_BATTERY_TIME_INFO=${translations[Display remaining time for battery option]}
    PW_MH_BATTERY_WATT_INFO=${translations[Display wattage for the battery option]}
    PW_MH_CORE_BARS_INFO=${translations[Change the display of core_load from numbers to vertical bars]}
    PW_MH_CORE_LOAD_INFO=${translations[Display load & frequency per core]}
    PW_MH_CPU_MHZ_INFO=${translations[Show the CPUs current MHz]}
    PW_MH_CPU_POWER_INFO=${translations[Display CPU draw in watts]}
    PW_MH_CPU_TEMP_INFO=${translations[Display current CPU temperature]}
    PW_MH_DEVICE_BATTERY_ICON_INFO=${translations[Display wirless device battery icon.]}
    PW_MH_ENGINE_SHORT_NAMES_INFO=${translations[Display a short version of the used engine (e.g. OGL instead of OpenGL)]}
    PW_MH_ENGINE_VERSION_INFO=${translations[Display OpenGL or vulkan and vulkan-based render engines version]}
    PW_MH_EXEC_NAME_INFO=${translations[Display current exec name]}
    PW_MH_FCAT_INFO=${translations[Enables frame capture analysis]}
    PW_MH_FPS_METRICS_INFO=${translations[Takes a list of decimal values or the value avg, e.g avg,0.001]}
    PW_MH_FRAME_COUNT_INFO=${translations[Display frame count]}
    PW_MH_FRAMETIME_INFO=${translations[Display frametime next to FPS text]}
    PW_MH_FULL_INFO=${translations[Enable most of the toggleable parameters (currently excludes histogram)]}
    PW_MH_GAMEMODE_INFO=${translations[Show if GameMode is on]}
    PW_MH_GPU_CORE_CLOCK_INFO=${translations[Display GPU core frequency]}
    PW_MH_GPU_FAN_INFO=${translations[GPU fan in rpm on AMD, FAN in percent on NVIDIA]}
    PW_MH_GPU_JUNCTION_TEMP_INFO=${translations[Display current GPU temperature]}
    PW_MH_GPU_MEM_CLOCK_INFO=${translations[Display GPU memory frequency]}
    PW_MH_GPU_MEM_TEMP_INFO=${translations[Display current GPU temperature]}
    PW_MH_GPU_NAME_INFO=${translations[Display GPU name from pci.ids]}
    PW_MH_GPU_POWER_INFO=${translations[Display GPU draw in watts]}
    PW_MH_GPU_TEMP_INFO=${translations[Display current GPU temperature]}
    PW_MH_GPU_VOLTAGE_INFO=${translations[Display GPU voltage (only works on AMD GPUs)]}
    PW_MH_HISTOGRAM_INFO=${translations[Change FPS graph to histogram]}
    PW_MH_HORIZONTAL_INFO=${translations[Display Mangohud in a horizontal position]}
    PW_MH_HORIZONTAL_STRETCH_INFO=${translations[Stretches the background to the screens width in horizontal mode]}
    PW_MH_HUD_COMPACT_INFO=${translations[Display compact version of MangoHud]}
    PW_MH_HUD_NO_MARGIN_INFO=${translations[Remove margins around MangoHud]}
    PW_MH_IO_READ_INFO=${translations[Show non-cached IO read, in MiB/s]}
    PW_MH_IO_WRITE_INFO=${translations[Show non-cached IO write, in MiB/s]}
    PW_MH_NO_DISPLAY_INFO=${translations[Hide the HUD by default]}
    PW_MH_NO_SMALL_FONT_INFO=${translations[Use primary font size for smaller text like units]}
    PW_MH_PROCMEM_INFO=${translations[Displays process memory usage: resident procmem (resident) also toggles others off if disabled]}
    PW_MH_PROCMEM_SHARED_INFO=${translations[Displays process memory usage: shared]}
    PW_MH_PROCMEM_VIRT_INFO=${translations[Displays process memory usage: virtual]}
    PW_MH_RAM_INFO=${translations[Display system RAM usage]}
    PW_MH_RESOLUTION_INFO=${translations[Display the current resolution]}
    PW_MH_SHOW_FPS_LIMIT_INFO=${translations[Display the current FPS limit]}
    PW_MH_SWAP_INFO=${translations[Display swap space usage next to system RAM usage]}
    PW_MH_TEMP_FAHRENHEIT_INFO=${translations[Show temperature in Fahrenheit]}
    PW_MH_THROTTLING_STATUS_INFO=${translations[Show if GPU is throttling based on Power, current, temp or "other" (Only shows if throttling is currently happening). Currently disabled by default for Nvidia as it causes lag on 3000 series]}
    PW_MH_THROTTLING_STATUS_GRAPH_INFO=${translations[Same as throttling_status but displays throttling in the frametime graph and only power and temp throttling]}
    PW_MH_TIME_INFO=${translations[Display time]}
    PW_MH_VERSION_INFO=${translations[Show current MangoHud version]}
    PW_MH_VKBASALT_INFO=${translations[Show if vkBasalt is on]}
    PW_MH_VRAM_INFO=${translations[Display system VRAM usage]}
    PW_MH_VULKAN_DRIVER_INFO=${translations[Display used Vulkan driver (radv/amdgpu-pro/amdvlk)]}
    PW_MH_WINE_INFO=${translations[Show current Wine or Proton version in use]}

    unset ADD_GUI_MH GUI_MH_RESULT ADD_GUI_MH_FPS GUI_MH_FPS_RESULT PW_FPS_LIMIT_VAR PW_MANGOHUD_CONFIG
    try_remove_file "${PW_TMPFS_PATH}/tmp_yad_mh_set"
    try_remove_file "${PW_TMPFS_PATH}/tmp_yad_mh_fps_limit"

    GET_REFRESH_RATE=(30 40 45 48 60 75 90 120 144 165 175 240)

    if [[ -n "$MANGOHUD_CONFIG" ]] ; then
        PW_MANGOHUD_CONFIG=($(echo "$MANGOHUD_CONFIG" | tr ',' '\n' | grep -v '=' | tr [[:lower:]] [[:upper:]]))
    else
        PW_MANGOHUD_CONFIG=($(echo "$DEFAULT_MANGOHUD_CONFIG" | tr ',' '\n' | grep -v '=' | tr [[:lower:]] [[:upper:]]))
    fi

    if [[ -n "$FPS_LIMIT" ]] ; then
        PW_FPS_LIMIT_VAR=($(echo "$FPS_LIMIT" | tr '' '\n' | grep -v '='))
    fi

    for add_list_mh in "${LIST_MH[@]}"; do
        PW_MH_GUI_HELP="PW_MH_${add_list_mh}_INFO"
        if [[ ${PW_MANGOHUD_CONFIG[*]} =~ $add_list_mh ]]; then
            ADD_GUI_MH+="--field=${CHKBOX_SPACE}${add_list_mh//"_"/" "}!${!PW_MH_GUI_HELP}:${THEME_CHKBOX}%TRUE%"
        else
            ADD_GUI_MH+="--field=${CHKBOX_SPACE}${add_list_mh//"_"/" "}!${!PW_MH_GUI_HELP}:${THEME_CHKBOX}%FALSE%"
        fi
    done

    for add_list_mh_fps in "${GET_REFRESH_RATE[@]}"; do
        if [[ ${PW_FPS_LIMIT_VAR[*]} =~ $add_list_mh_fps ]]; then
            ADD_GUI_MH_FPS+="--field=${CHKBOX_SPACE}$add_list_mh_fps:${THEME_CHKBOX}%TRUE%"
        else
            ADD_GUI_MH_FPS+="--field=${CHKBOX_SPACE}$add_list_mh_fps:${THEME_CHKBOX}%FALSE%"
        fi
    done

    IFS="%"
    "${pw_yad}" --plug=$KEY_MH_GUI --tabnum="1" --form --columns=5 --separator=" " --text-align=center \
        --text="${translations[MangoHud settings (Keys <b>R_SHIFT + F12</b> disable MangoHud)\\n<b>note:</b> To display help for each item, just hover the mouse cursor over the text.]}" \
        --gui-type-text="${PANED_GUI_TYPE_TEXT_UP}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_UP}" \
        ${ADD_GUI_MH} 1> "${PW_TMPFS_PATH}/tmp_yad_mh_set" 2>/dev/null &
    "${pw_yad}" --plug=$KEY_MH_GUI --tabnum="2" --form --columns=10 --separator=" " --text-align=center \
        --text="${translations[Enabling fps limitation with MANGOHUD tools built into PortProton (Keys <b>L_SHIFT + F1</b> Toggles fps limitation)]}" \
        --gui-type-text="${PANED_GUI_TYPE_TEXT_DOWN}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_DOWN}" \
        ${ADD_GUI_MH_FPS} 1> "${PW_TMPFS_PATH}/tmp_yad_mh_fps_limit" 2>/dev/null &
    IFS="$orig_IFS"

    "${pw_yad}" --paned --key="$KEY_MH_GUI" --title="MangoHud" \
        --separator=" " --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --sensitive \
        --gui-type="settings-paned" \
        --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
        --button="${translations[RESET]} MANGOHUD"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings for]} MangoHud":180 \
        --button="${translations[PREVIEW CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Start vkcube for preview changes]}":184 \
        --button="${translations[DISABLE]} MANGOHUD"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Disable MangoHud and go to the previous menu]}":182 \
        --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":186  2>/dev/null
    YAD_MANGOHUD_STATUS="$?"

    case "${YAD_MANGOHUD_STATUS}" in
        1|252)
            restart_pp
            ;;
        180)
            sed -i '/FPS_LIMIT/d' "$portwine_exe".ppdb
            sed -i '/MANGOHUD/d' "$portwine_exe".ppdb
            restart_pp
            ;;
        182)
            export PW_MANGOHUD="0"
            ;;
        186)
            export PW_MANGOHUD="1"
            ;;
    esac

    YAD_MH_SET=$(<"${PW_TMPFS_PATH}/tmp_yad_mh_set")
    YAD_MH_FPS_LIMIT=$(<"${PW_TMPFS_PATH}/tmp_yad_mh_fps_limit")

    MONITOR_HEIGHT="$(echo "$PW_SCREEN_RESOLUTION" | awk -F'x' '{print $2}')"
    if [[ -n "$MONITOR_HEIGHT" ]]
    then MH_FONT_SIZE="font_size=$(( MONITOR_HEIGHT / 45 ))"
    fi

    INT_COUNT_MH="0"
    for read_list_mh in ${YAD_MH_SET} ; do
        if [[ "$read_list_mh" == "TRUE" ]]
        then GUI_MH_RESULT+="${LIST_MH[$INT_COUNT_MH]},"
        fi
        ((INT_COUNT_MH++))
    done
    GUI_MH_RESULT=$(echo "$GUI_MH_RESULT" | sed 's/ /_/g' | tr '[:upper:]' '[:lower:]')

    INT_COUNT_MH_FPS="0"
    for read_list_mh_fps in ${YAD_MH_FPS_LIMIT} ; do
        if [[ "$read_list_mh_fps" == "TRUE" ]]
        then GUI_MH_FPS_RESULT+="${GET_REFRESH_RATE[$INT_COUNT_MH_FPS]}+"
        fi
        ((INT_COUNT_MH_FPS++))
    done

    if [[ "$(echo "${GUI_MH_FPS_RESULT}" | awk -F'+' '{print $2}')" ]] ; then
        export FPS_LIMIT="${GUI_MH_FPS_RESULT%+}"
        if [[ ! "${GUI_MH_RESULT}" =~ "show_fps_limit" ]] ; then
            GUI_MH_RESULT="${GUI_MH_RESULT}show_fps_limit,"
        fi
    else
        export FPS_LIMIT="${GUI_MH_FPS_RESULT%+}"
    fi

    if [[ -n "$MH_FONT_SIZE" ]]
    then GUI_MH_RESULT="${GUI_MH_RESULT}${MH_FONT_SIZE}"
    else GUI_MH_RESULT="${GUI_MH_RESULT%,}"
    fi

    if [[ -n "$FPS_LIMIT" ]] ; then
        GUI_MH_RESULT="${GUI_MH_RESULT},fps_limit=$FPS_LIMIT"
    elif [[ "$FPS_LIMIT" == "disabled" ]] ; then
        GUI_MH_RESULT="${GUI_MH_RESULT},fps_limit=0"
    fi

    if [[ "${GUI_MH_RESULT}" =~ "fps_only" ]] ; then
        local GUI_MH_RESULT="fps_only"
        print_info "In the MangoHud config fps_only is detected all settings are reseted"
    fi

    export MANGOHUD_CONFIG="${GUI_MH_RESULT}"
    export PW_MANGOHUD FPS_LIMIT
    edit_db_from_gui MANGOHUD_CONFIG PW_MANGOHUD FPS_LIMIT

    if [[ "${YAD_MANGOHUD_STATUS}" == "184" ]] ; then
        PW_MANGOHUD="1"
        pw_init_runtime
        pw_mangohud_check
        ${pw_runtime} \
        LD_PRELOAD="${PW_LD_PRELOAD}" \
        VK_LAYER_PATH="${PW_VK_LAYER_PATH}" \
        VK_INSTANCE_LAYERS="${PW_VK_INSTANCE_LAYERS}" \
        "${PW_PLUGINS_PATH}/portable/bin/vkcube"
        gui_mangohud
    fi

    restart_pp
}

# GUI DGVOODOO2
gui_dgvoodoo2 () {
    KEY_DGV2_GUI=$RANDOM
    PW_DGV2_LIST=(PW_DGV2_USE_DX12 PW_DGV2_DISABLE_MIPMAPPING PW_DGV2_FREE_MOUSE PW_DGV2_ENABLE_CRT PW_DGV2_DISABLE_D3D PW_DGV2_FILTER_POINT_SAMPLED
    PW_DGV2_BLIT_STRETCH PW_DGV2_FORCE_VSYNC PW_DGV2_FASTMEMORY PW_DGV2_PHONG_SHADING PW_DGV2_DGVOODOO_WATERMARK PW_DGV2_GLIDE_NAPALM PW_DGV2_ONBOARD_RAM
    PW_DGV2_GLIDE_GAMMA_RAMP PW_DGV2_EMULATING_PCI_ACCESS PW_DGV2_16_BIT_DEPTH_BUFFER PW_DGV2_3DFX_WATERMARK PW_DGV2_3DFX_SPLASH_SCREEN
    PW_DGV2_INACTIVE_APP_STATE
    )

    PW_DGV2_USE_DX12_INFO=${translations[Use DirectX12 for dgVoodoo2. Doesnt always work better. (Working only on newest and stable dxvk/vkd3d) (Direct3D and Glide settings)]}
    PW_DGV2_FORCE_VSYNC_INFO=${translations[Force the vertical sync to avoid tearing or prevent the GPU from rendering at crazy high speed. Keep in mind that some application need unforced vSync because of synchronization reasons. (Direct3D settings)]}
    PW_DGV2_DGVOODOO_WATERMARK_INFO=${translations[Shows the dgVoodoo watermark in-game when enabled. (Direct3D settings)]}
    PW_DGV2_ENABLE_CRT_INFO=${translations[CRT-like blurred appearance. (Direct3D and Glide settings)]}
    PW_DGV2_DISABLE_MIPMAPPING_INFO=${translations[Disabling mipmapping can be used to make textured surfaces sharper. (Direct3D and Glide settings)]}
    PW_DGV2_FREE_MOUSE_INFO=${translations[If enabled then physical mouse is free to move inside the game window when using emulated scaling and/or application and forced resolution differs. Can be useful when a game relies and the physical window size. (Direct3D and Glide settings)]}
    PW_DGV2_DISABLE_D3D_INFO=${translations[Do not use d3d8 and d3d9 dgVoodoo2 libraries. For some old games, using the example of Space Rangers, a bug with a black screen is corrected. (Direct3D settings)]}
    PW_DGV2_FILTER_POINT_SAMPLED_INFO=${translations[if enabled then forced filtering affects only non-point sampled textures. (Direct3D settings)]}
    PW_DGV2_FASTMEMORY_INFO=${translations[Enable fast memory access. (Enable if games have poor performance, using Unreal 2 as an example) (Direct3D settings)]}
    PW_DGV2_PHONG_SHADING_INFO=${translations[If this option is enabled then Phong shading is applied in place of Gouraud when it is possible. It works only when an application uses the fixed function vertex/pixel pipline and pushes all the work of the vertex transforming and lighting to Direct3D when rendering primitives. Keep in mind that it requires much more GPU power than default shading. (Direct3D settings)]}
    PW_DGV2_BLIT_STRETCH_INFO=${translations[If this options enabled then linear filtering is applied for stretched copying between 2D surfaces (DirectDraw only). Early hardware did not support or apply point sampled blitting which can end up very pixelated results. Linear filtering is much nicer in general but can cause artifacts especially with colorkeyed blitting. (Direct3D settings)]}
    PW_DGV2_GLIDE_NAPALM_INFO=${translations[Use 3dfx glide napalm, uses antialiasing provided by the application. (Disables antialiasing setting) (Glide settings)]}
    PW_DGV2_GLIDE_GAMMA_RAMP_INFO=${translations[Enable gamma ramp coming for Glide. (Glide settings)]}
    PW_DGV2_ONBOARD_RAM_INFO=${translations[Increases memory for videocard Voodoo Graphics, Voodoo Rush, Voodoo 2, Voodoo Banshee. You can set the game resolution higher. (Glide settings)]}
    PW_DGV2_EMULATING_PCI_ACCESS_INFO=${translations[When enabled, the virtual 3Dfx card will have PCI bus speeds emulated as closely as possible. Emulation of true PCI access should theoretically never be disabled but there can be possible degradation of performance when left enabled. Only some games require accurate emulation of the PCI bus, so in most cases PCI bus emulation should be left disabled. (Glide settings)]}
    PW_DGV2_16_BIT_DEPTH_BUFFER_INFO=${translations[Enabling 16-bit depth buffers can prevent Z-fighting in games, but also has the disadvantage of possibly causing artifacting. (Glide settings)]}
    PW_DGV2_3DFX_WATERMARK_INFO=${translations[Shows the 3Dfx watermark in-game when enabled. (Glide settings)]}
    PW_DGV2_3DFX_SPLASH_SCREEN_INFO=${translations[The 3Dfx splash screen is seen when an application starts, disabling this option prevents this animation from playing. (Glide settings)]}
    PW_DGV2_INACTIVE_APP_STATE_INFO=${translations[Enabling inactive state prevents the application from detecting losing the application focus. Most of the Glide applications close or deactivate themself when losing focus, so this can be used to let the application run in the background. (Glide settings)]}

    # fix
    [[ "${PW_DGV2_FILTERING}" == "0" ]] && export PW_DGV2_FILTERING="disabled" && edit_db_from_gui PW_DGV2_FILTERING
    [[ "${PW_DGV2_ANTIALIASING}" == "0" ]] && export PW_DGV2_ANTIALIASING="disabled" && edit_db_from_gui PW_DGV2_ANTIALIASING

    case "${PW_VULKAN_USE}" in
        0|3|4|5|6)
            DISABLE_DGV2_LIST="PW_DGV2_USE_DX12
            "
            ;;
    esac

    unset ADD_CHK_BOX_DGV2
    for int_to_boole in ${PW_DGV2_LIST[@]} ; do
        if [[ "${!int_to_boole}" == "1" ]]
        then export ${int_to_boole}="TRUE"
        else export ${int_to_boole}="FALSE"
        fi
        TMP_HELP_FOR_GUI="${int_to_boole}_INFO"
        int_to_boole_non_pw="${int_to_boole//PW_DGV2/}"
        int_to_boole_non_pw="${int_to_boole_non_pw//"_"/" "}"
        if [[ ! "${PW_VULKAN_USE}" == [12] ]] \
        && [[ "${DISABLE_DGV2_LIST}" =~ ${int_to_boole} ]]
        then ADD_CHK_BOX_DGV2+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:D${THEME_CHKBOX}%${!int_to_boole}%"
        else ADD_CHK_BOX_DGV2+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:${THEME_CHKBOX}%${!int_to_boole}%"
        fi
    done

    IFS="%"
    "${pw_yad}" --plug=$KEY_DGV2_GUI --tabnum="1" --form --separator=" " --columns=4 ${ADD_CHK_BOX_DGV2} --text-align=center \
    --text="${translations[dgVoodoo2 settings\\n<b>NOTE:</b> To display help for each item, simply hover over the text]}" \
    --gui-type-text="${PANED_GUI_TYPE_TEXT_UP}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_UP}" \
    1> "${PW_TMPFS_PATH}/tmp_yad_dgv2_set" 2>/dev/null &
    IFS="$orig_IFS"

    DGVOODOO2_XRANDR="$(grep -e '[0-9]x' "${PW_TMPFS_PATH}/xrandr.tmp" | awk '{print $1}' | sort -rVu | grep ^"[0-9]" | tr '\n' ' ')"
    for drop_low in ${DGVOODOO2_XRANDR} ; do
        if (( "${drop_low//x/}" > "1000000" )) ; then
            DGVOODOO2_XRANDR_NEW+="${drop_low}!"
        fi
    done

    DGVOODOO2_FILTERING="Point sampled!Bilinear!Linear mip!Trilinear!Anisotropic 2x!Anisotropic 4x!Anisotropic 8x!Anisotropic 16x"
    DGVOODOO2_RESAMPLING="Point sampled!Bilinear!Lanczos-2!Bicubic!Lanczos-3"
    DGVOODOO2_VIDEOCARD="dgVoodoo2 SVGA 3D!dgVoodoo2 Virtual 3D!Geforce 4 Ti 4800!ATI Radeon 8500!Matrox Parhelia-512!GeForce FX 5700 Ultra!GeForce 9800 GT!Voodoo Graphics!Voodoo Rush!Voodoo 2!Voodoo Banshee"

    "${pw_yad}" --plug=$KEY_DGV2_GUI --tabnum="2" --form --columns=3 --separator="%" \
    --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_DOWN}" \
    --field="${CHKBOX_SPACE}RESOLUTION!${translations[Set the resolution used. (Direct3D and Glide settings)]} :CBE" "$(combobox_fix --disabled "${PW_DGV2_RESOLUTION}" "4x app resolution!3x app resolution!2x app resolution!${DGVOODOO2_XRANDR_NEW::-1}")" \
    --field="${CHKBOX_SPACE}FPS LIMIT!${translations[You can configure fps limit. (Direct3D and Glide settings)]} :CBE" "$(combobox_fix --disabled "${PW_DGV2_FPS_LIMIT}" "30!40!45!48!60!75!90!120!144!165!175!240")" \
    --field="${CHKBOX_SPACE}FILTERING!${translations[You can select from various texture filtering modes here. Forcing other than the app default can result in glitches or break some rendering effects. (Glide have max filtering bilinear) (Direct3D and Glide settings)]} :CB" "$(combobox_fix --disabled "${PW_DGV2_FILTERING}" "${DGVOODOO2_FILTERING}")" \
    --field="${CHKBOX_SPACE}ANTIALIASING!${translations[Forcing antialiasing. This can cause artifacts. (Direct3D and Glide settings)]} :CB" "$(combobox_fix --disabled "${PW_DGV2_ANTIALIASING}" "2x!4x!8x")" \
    --field="${CHKBOX_SPACE}BIT DEPTH!${translations[You can define what screen bit depth should be reported through dgVoodoo. (For game MOTO need 16 bit depth) (Direct3D and Glide settings)]} :CB" "$(combobox_fix --disabled "${PW_DGV2_BIT_DEPTH}" "8!16!32")" \
    --field="${CHKBOX_SPACE}VIDEOCARD!${translations[You can select a virtual video card. (For game Quake 2 need Voodoo Graphics or Voodoo Rush card) (Direct3D and Glide settings)]} :CB" "$(combobox_fix "${PW_DGV2_VIDEOCARD}" "${DGVOODOO2_VIDEOCARD}")" \
    --field="${CHKBOX_SPACE}VRAM!${translations[Increase the amount of vram for dgVoodoo2. (Direct3D settings)
- dgVoodoo2 SVGA 3D: 16 - 128
- dgVoodoo2 Virtual 3D: 16 - 4096
- Geforce 4 Ti 4800: 64 - 256
- ATI Radeon 8500: 64 - 256
- Matrox Parhelia-512: 128 - 256
- GeForce FX 5700 Ultra: 64 - 256
- GeForce 9800 GT: 512 - 1024]} :CB" "$(combobox_fix "${PW_DGV2_VRAM}" "16!32!64!128!256!512!1024!2048!4096")" \
    --field="${CHKBOX_SPACE}BRIGHTNESS!${translations[Brightness can be finetuned here. (Direct3D and Glide settings)]} :NUM" "${PW_DGV2_BRIGHTNESS}:!0..400" \
    --field="${CHKBOX_SPACE}COLOR!${translations[Color intensity. Finetued it to make colors or less vital compared to the application default, or even Black and White, according to your taste. (Direct3D and Glide settings)]} :NUM" "${PW_DGV2_COLOR}:!0..400" \
    --field="${CHKBOX_SPACE}CONTRAST!${translations[Contrast is the intensity difference between dark and bright regions. Only static contrast is implemented and you can finetune it here. (Direct3D and Glide settings)]} :NUM" "${PW_DGV2_CONTRAST}:!0..400" \
    --field="${CHKBOX_SPACE}DISPLAY ROI!${translations[Useful for applications rendering into a widescreen subrectangle inside a 4:3 resolution - the widescreen subrectangle can be defined as display ROI, the input of the scaling process. (Direct3D and Glide settings)]} :CBE" "$(combobox_fix --disabled "${PW_DGV2_DISPLAY_ROI}" "3_2!4_3!5_4!16_9!16_10!21_9")" \
    --field="${CHKBOX_SPACE}RESAMPLING!${translations[If scaling is done by the dgVoodoo than you can choose which resampling method to use. The more complex filter the more computationally expensive. Available ones in order of complexty. (Direct3D and Glide settings)
- Point sampled (unblurred pixels)
- Bilinear (smoothed)
- Lanczos-2 (smoothed but sharper)
- Bicubic (smoothed but sharper)
- Lanczos-3 (smoothed, sharpest)]} :CB" "$(combobox_fix --disabled "${PW_DGV2_RESAMPLING}" "${DGVOODOO2_RESAMPLING}")" \
    --field="${CHKBOX_SPACE}CURSOR SCALE!${translations[Integer scale factor of the emulated hardware mouse cursor. 0: calculated from the application and forced resolution. (Direct3D and Glide settings)]} :NUM" "${PW_DGV2_CURSOR_SCALE}:!0..5" \
    1> "${PW_TMPFS_PATH}/tmp_yad_dgv2_set_cb" 2>/dev/null &

    "${pw_yad}" --paned --key=$KEY_DGV2_GUI --height="350" --title="dgVoodoo2" \
    --separator=" " --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --gui-type="settings-paned" \
    --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
    --button="${translations[RESET]} DGVOODOO2"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings for]} dgVoodoo2":162 \
    --button="${translations[DISABLE]} DGVOODOO2"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Disable dgVoodoo2 and go to the previous menu]}":164 \
    --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":166 \
    2>/dev/null
    YAD_DGV2_STATUS="$?"

    case "${YAD_DGV2_STATUS}" in
        1|252)
            restart_pp
            ;;
        162)
            sed -i '/PW_DGV2/d' "$portwine_exe".ppdb
            sed -i '/DGVOODOO2/d' "$portwine_exe".ppdb
            restart_pp
            ;;
        164)
            export PW_DGVOODOO2="0"
            ;;
        166)
            export PW_DGVOODOO2="1"
            ;;
    esac

    output_yad_dgv2=($(<"${PW_TMPFS_PATH}/tmp_yad_dgv2_set"))
    bool_from_yad=0
    for boole_to_int in ${PW_DGV2_LIST[@]} ; do
        export ${boole_to_int}="${output_yad_dgv2[$bool_from_yad]}"
        if [[ "${!boole_to_int}" == "TRUE" ]]
        then export ${boole_to_int}="1"
        else export ${boole_to_int}="0"
        fi
        export bool_from_yad=$(( bool_from_yad + 1 ))
    done

    IFS='%' read -r -a PW_ADD_SETTINGS_DGV2 <"${PW_TMPFS_PATH}/tmp_yad_dgv2_set_cb"
    IFS="$orig_IFS"
    PW_DGV2_RESOLUTION="${PW_ADD_SETTINGS_DGV2[0]}"
    PW_DGV2_FPS_LIMIT="${PW_ADD_SETTINGS_DGV2[1]}"
    PW_DGV2_FILTERING="${PW_ADD_SETTINGS_DGV2[2]}"
    PW_DGV2_ANTIALIASING="${PW_ADD_SETTINGS_DGV2[3]}"
    PW_DGV2_BIT_DEPTH="${PW_ADD_SETTINGS_DGV2[4]}"
    PW_DGV2_VIDEOCARD="${PW_ADD_SETTINGS_DGV2[5]}"
    PW_DGV2_VRAM="${PW_ADD_SETTINGS_DGV2[6]}"
    PW_DGV2_BRIGHTNESS="${PW_ADD_SETTINGS_DGV2[7]}"
    PW_DGV2_COLOR="${PW_ADD_SETTINGS_DGV2[8]}"
    PW_DGV2_CONTRAST="${PW_ADD_SETTINGS_DGV2[9]}"
    PW_DGV2_DISPLAY_ROI="${PW_ADD_SETTINGS_DGV2[10]}"
    PW_DGV2_RESAMPLING="${PW_ADD_SETTINGS_DGV2[11]}"
    PW_DGV2_CURSOR_SCALE="${PW_ADD_SETTINGS_DGV2[12]}"

    edit_db_from_gui ${PW_DGV2_LIST[@]} PW_DGVOODOO2 PW_DGV2_FILTERING PW_DGV2_ANTIALIASING PW_DGV2_VRAM PW_DGV2_RESOLUTION \
    PW_DGV2_FPS_LIMIT PW_DGV2_BIT_DEPTH PW_DGV2_BRIGHTNESS PW_DGV2_COLOR PW_DGV2_CONTRAST PW_DGV2_VIDEOCARD PW_DGV2_DISPLAY_ROI \
    PW_DGV2_CURSOR_SCALE PW_DGV2_RESAMPLING

    restart_pp
}

# GUI GAMESCOPE
gui_gamescope () {
    KEY_GS_GUI=$RANDOM
    PW_GS_LIST=(PW_GS_FULLSCREEN PW_GS_FORCE_FULLSCREEN PW_GS_BORDERLESS_WINDOW PW_GS_FORCE_GRAB_CURSOR
    PW_GS_FORCE_GRAB_KEYBOARD PW_GS_HDR_ENABLE PW_GS_ENABLE_GAMESCOPE_WSI PW_GS_HDR_ITM_ENABLE PW_GS_SDR_GAMMUT_WIDENESS
    PW_GS_FORCE_COMPOSITION PW_GS_HDR_FORCE_SUPPORT PW_GS_HDR_FORCE_OUTPUT PW_GS_HDR_FORCE_HEATMAP
    PW_GS_EXPOSE_WAYLAND PW_GS_REALTIME_SCHEDULING
    )

    grep -e '--mangoapp' "${PW_TMPFS_PATH}/gamescope.tmp" &>/dev/null && add_to_array "PW_GS_LIST" PW_GS_MANGOAPP
    grep -e '--backend' "${PW_TMPFS_PATH}/gamescope.tmp" &>/dev/null && add_to_array "PW_GS_LIST" PW_GS_BACKEND_SDL PW_GS_SDL_VIDEODRIVER_X11

    GS_FILTER_CB="linear!nearest!fsr!nis!pixel"
    #debian bookworm fix
    if grep -e '-U, --fsr-upscaling' "${PW_TMPFS_PATH}/gamescope.tmp" &>/dev/null ; then
        GS_FILTER_CB="fsr!nis"
        export PW_GS_FILTER_MODE_OLD="true"
        rm_from_array "PW_GS_LIST" PW_GS_FORCE_GRAB_CURSOR PW_GS_FORCE_GRAB_KEYBOARD PW_GS_HDR_ENABLE PW_GS_HDR_FORCE_SUPPORT \
        PW_GS_HDR_FORCE_OUTPUT
    fi

    PW_GS_FULLSCREEN_INFO=${translations[Make the window fullscreen]}
    PW_GS_FORCE_FULLSCREEN_INFO=${translations[Force windows inside of gamescope to be the size of the nested display (fullscreen)]}
    PW_GS_BORDERLESS_WINDOW_INFO=${translations[Make the window borderless. Working only with backend sdl or X11 session.]}
    PW_GS_FORCE_GRAB_KEYBOARD_INFO=${translations[Grab the keyboard]}
    PW_GS_FORCE_GRAB_CURSOR_INFO=${translations[Always use relative mouse mode instead of flipping dependent on cursor visibility.]}
    PW_GS_HDR_ENABLE_INFO=${translations[Enable HDR output (needs Gamescope WSI layer enabled for support from clients). If this is not set, and there is a HDR client, it will be tonemapped SDR.]}
    PW_GS_ENABLE_GAMESCOPE_WSI_INFO=${translations[This can be useful for some HDR options and for some DXVK v2.3 vsync optimisations]}
    PW_GS_SDR_GAMMUT_WIDENESS_INFO=${translations[Set the \'wideness\' of the gamut for SDR comment. 0 - 1.]}
    PW_GS_HDR_ITM_ENABLE_INFO=${translations[Enable SDR->HDR inverse tone mapping. only works for SDR input.]}
    PW_GS_FORCE_COMPOSITION_INFO=${translations[Disables direct scan-out]}
    PW_GS_HDR_FORCE_SUPPORT_INFO=${translations[Forces support for HDR and associated opptions even if the current display does not support it]}
    PW_GS_HDR_FORCE_OUTPUT_INFO=${translations[Forces support and output to HDR10 PQ even if the output does not support it (will look very wrong if it doesn\'t)]}
    PW_GS_HDR_FORCE_HEATMAP_INFO=${translations[Displays a heatmap-style debug view of HDR luminence across the scene in nits.]}
    PW_GS_EXPOSE_WAYLAND_INFO=${translations[Expose Wayland clients using xdg-shell]}
    PW_GS_REALTIME_SCHEDULING_INFO=${translations[Enable GameScope realtime scheduling]}
    PW_GS_MANGOAPP_INFO=${translations[Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.]}
    PW_GS_BACKEND_SDL_INFO=${translations[Use sdl backend. (by default wayland backend is used).]}
    PW_GS_SDL_VIDEODRIVER_X11_INFO=${translations[Force use sdl videodriver x11, works with BACKEND SDL. (Default is wayland)]}

    unset ADD_CHK_BOX_GS
    if [[ "${GAMESCOPE_INSTALLED}" == 1 ]] ; then
        GAMESCOPE_NEED_INSTALL="${translations[Change settings gamescope for]} <b>$PW_NAME_DESKTOP_PROXY</b>\n ${translations[<b>NOTE:</b> To display help for each item, simply hover your mouse over the text]}"
        GS_CB="CB" && GS_CBE="CBE" && GS_NUM="NUM" && GS_NUMN="NUMN"
        for int_to_boole in ${PW_GS_LIST[@]} ; do
            if [[ "${!int_to_boole}" == "1" ]]
            then export ${int_to_boole}="TRUE"
            else export ${int_to_boole}="FALSE"
            fi
            TMP_HELP_FOR_GUI="${int_to_boole}_INFO"
            int_to_boole_non_pw="${int_to_boole//PW_GS/}"
            int_to_boole_non_pw="${int_to_boole_non_pw//"_"/" "}"
            ADD_CHK_BOX_GS+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:${THEME_CHKBOX}%${!int_to_boole}%"
        done
    else
        if check_flatpak ; then
            GAMESCOPE_VERSION="$(grep 'VERSION_ID=' /etc/os-release)"
            GAMESCOPE_NEED_INSTALL=$(eval_translations "<b>Gamescope is not detected on the system, to install it, run the command in the terminal:\\nflatpak install -y runtime/org.freedesktop.Platform.VulkanLayer.gamescope/x86_64/\$%{GAMESCOPE_VERSION}%\\n(Can be selected and copied)</b>" "GAMESCOPE_VERSION=${GAMESCOPE_VERSION//VERSION_ID=/}")
            YAD_TEXT_SELECTION="--selectable-labels"
        else
            GAMESCOPE_NEED_INSTALL="${translations[<b>Gamescope is not detected on the system, please contact the manufacturer of your distribution\\nor search the Internet for information on how to install gamescope on your system.</b>]}"
        fi
        GS_CB="DCB" && GS_CBE="DCBE" && GS_NUM="DNUM" && GS_NUMN="DNUMN"
        for int_to_boole in ${PW_GS_LIST[@]} ; do
            if [[ "${!int_to_boole}" == "1" ]]
            then export ${int_to_boole}="TRUE"
            else export ${int_to_boole}="FALSE"
            fi
            TMP_HELP_FOR_GUI="${int_to_boole}_INFO"
            int_to_boole_non_pw="${int_to_boole//PW_GS/}"
            int_to_boole_non_pw="${int_to_boole_non_pw//"_"/" "}"
            ADD_CHK_BOX_GS+="--field=${CHKBOX_SPACE}${int_to_boole_non_pw}!${!TMP_HELP_FOR_GUI}:D${THEME_CHKBOX}%${!int_to_boole}%"
        done
    fi

    IFS="%"
    "${pw_yad}" --plug=$KEY_GS_GUI --tabnum="1" --form --columns=4 --separator=" " --text-align=center --text "$GAMESCOPE_NEED_INSTALL" \
    --gui-type-text="${PANED_GUI_TYPE_TEXT_UP}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_UP}" $YAD_TEXT_SELECTION \
    ${ADD_CHK_BOX_GS} \
    1> "${PW_TMPFS_PATH}/tmp_yad_gs_set" 2>/dev/null &
    IFS="$orig_IFS"

    GAMESCOPE_XRANDR="$(grep -e '[0-9]x' "${PW_TMPFS_PATH}/xrandr.tmp" | awk '{print $1}' | sort -rVu | grep ^"[0-9]" | tr '\n' ' ')"
    for drop_low in ${GAMESCOPE_XRANDR} ; do
        if (( "${drop_low//x/}" > "1000000" )) ; then
            GAMESCOPE_XRANDR_NEW+="${drop_low}!"
        fi
    done

    "${pw_yad}" --plug=$KEY_GS_GUI --tabnum="2" --form --columns=2 --separator="%" --homogeneous-row \
    --gui-type-text="${PANED_GUI_TYPE_TEXT_DOWN}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_DOWN}" \
    --field="${CHKBOX_SPACE}${translations[Show resolution]}!${translations[Set the resolution used by gamescope. Resizing the gamescope window will update these settings. Defaults to 1280x720.]} :${GS_CBE}" "$(combobox_fix --disabled "${PW_GS_SHOW_RESOLUTION}" "${GAMESCOPE_XRANDR_NEW::-1}")" \
    --field="${CHKBOX_SPACE}${translations[Internal resolution]}!${translations[Scale internal resolution (0.0 is unused)]} :${GS_NUMN}" "${PW_GS_INTERNAL_RESOLUTION}:!0..2" \
    --field="${CHKBOX_SPACE}${translations[Frame limit]}!${translations[Set a framerate limit. Specified in frames per second]} :${GS_CBE}" "$(combobox_fix --disabled "${PW_GS_FRAME_LIMIT}" "30!40!45!48!60!75!90!120!144!165!175!240")" \
    --field="${CHKBOX_SPACE}${translations[Scaler mode]}!${translations[Specify how to scale the GameScope window content]} :${GS_CB}" "$(combobox_fix --disabled "${PW_GS_SCALER_MODE}" "auto!integer!fit!fill!stretch")" \
    --field="${CHKBOX_SPACE}${translations[Filter mode]}!${translations[Use a filter such as AMD FidelityFX SuperResolution 1.0 (FSR) or NVIDIA Image Scaling v1.0.3 (NIS)]} :${GS_CB}" "$(combobox_fix --disabled "${PW_GS_FILTER_MODE}" "${GS_FILTER_CB}")" \
    --field="${CHKBOX_SPACE}${translations[Upscale sharpness]}!${translations[Sharpening value for FidelityFX SuperResolution 1.0 (FSR) and NVIDIA Image Scaling v1.0.3 (NIS). 0 is max sharpening, 20 is min sharpening.]} :${GS_NUM}" "${PW_GS_UPSCALE_SHARPNESS}:!0..20" \
    --field="${CHKBOX_SPACE}${translations[Max scale factor]}!${translations[Maximum Scale Factor. Working only on X11 or backend sdl (0.0 is unused)]} :${GS_NUMN}" "${PW_GS_MAX_SCALE_FACTOR}:!0..100" \
    --field="${CHKBOX_SPACE}${translations[Mouse sensitivity]}!${translations[Configurable mouse sensitivity, multiply mouse movement by specified decimal number amount]} :${GS_NUMN}" "${PW_GS_MOUSE_SENSITIVITY}:!0..100" \
    --field="${CHKBOX_SPACE}${translations[HDR SDR nits]}!${translations[Set the luminance of SDR content in nits. Default: 400 nits.]} :${GS_NUM}" "${PW_GS_SDR_CONTENT_NITS}:!0..10000" \
    --field="${CHKBOX_SPACE}${translations[HDR inverse SDR]}!${translations[Set the luminance of SDR content in nets used as the input for the inverse tone mapping process - Maximum is 1000 nits]} :${GS_NUM}" "${PW_GS_ITM_SDR_NITS}:!0..1000" \
    --field="${CHKBOX_SPACE}${translations[HDR inverse target]}!${translations[Set the target luninance of the inverse tone mapping process - Max is 10000 nits]} :${GS_NUM}" "${PW_GS_ITM_TARGET_NITS}:!0..10000" \
    1> "${PW_TMPFS_PATH}/tmp_yad_gs_set_cb" 2>/dev/null &

    "${pw_yad}" --paned --key="$KEY_GS_GUI" --title="GameScope" \
    --separator=" " --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --gui-type="settings-paned" \
    --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
    --button="${translations[RESET]} GAMESCOPE"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings for]} GameScope":162 \
    --button="${translations[DISABLE]} GAMESCOPE"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Disable GameScope and go to the previous menu]}":164 \
    --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":166 \
    2>/dev/null
    YAD_GAMESCOPE_STATUS="$?"

    case "${YAD_GAMESCOPE_STATUS}" in
        1|252)
            restart_pp
            ;;
        162)
            sed -i '/PW_GS/d' "$portwine_exe".ppdb
            sed -i '/GAMESCOPE/d' "$portwine_exe".ppdb
            restart_pp
            ;;
        164)
            export PW_GAMESCOPE="0"
            ;;
        166)
            export PW_GAMESCOPE="1"
            ;;
    esac

    output_yad_gs=($(<"${PW_TMPFS_PATH}/tmp_yad_gs_set"))
    bool_from_yad="0"
    for boole_to_int in ${PW_GS_LIST[@]} ; do
        export ${boole_to_int}="${output_yad_gs[$bool_from_yad]}"
        if [[ "${!boole_to_int}" == "TRUE" ]]
        then export ${boole_to_int}="1"
        else export ${boole_to_int}="0"
        fi
        export bool_from_yad=$(( bool_from_yad + 1 ))
    done

    IFS='%' read -r -a PW_ADD_SETTINGS_GS <"${PW_TMPFS_PATH}/tmp_yad_gs_set_cb"
    IFS="$orig_IFS"
    PW_GS_SHOW_RESOLUTION="${PW_ADD_SETTINGS_GS[0]}"
    PW_GS_INTERNAL_RESOLUTION="${PW_ADD_SETTINGS_GS[1]//','/'.'}"
    PW_GS_FRAME_LIMIT="${PW_ADD_SETTINGS_GS[2]}"
    PW_GS_SCALER_MODE="${PW_ADD_SETTINGS_GS[3]}"
    PW_GS_FILTER_MODE="${PW_ADD_SETTINGS_GS[4]}"
    PW_GS_UPSCALE_SHARPNESS="${PW_ADD_SETTINGS_GS[5]}"
    PW_GS_MAX_SCALE_FACTOR="${PW_ADD_SETTINGS_GS[6]//','/'.'}"
    PW_GS_MOUSE_SENSITIVITY="${PW_ADD_SETTINGS_GS[7]//','/'.'}"
    PW_GS_SDR_CONTENT_NITS="${PW_ADD_SETTINGS_GS[8]}"
    PW_GS_ITM_SDR_NITS="${PW_ADD_SETTINGS_GS[9]}"
    PW_GS_ITM_TARGET_NITS="${PW_ADD_SETTINGS_GS[10]}"

    edit_db_from_gui ${PW_GS_LIST[@]} PW_GAMESCOPE PW_GS_SHOW_RESOLUTION PW_GS_INTERNAL_RESOLUTION \
    PW_GS_FRAME_LIMIT PW_GS_SCALER_MODE PW_GS_FILTER_MODE \
    PW_GS_UPSCALE_SHARPNESS PW_GS_MAX_SCALE_FACTOR PW_GS_MOUSE_SENSITIVITY \
    PW_GS_SDR_CONTENT_NITS PW_GS_ITM_SDR_NITS PW_GS_ITM_TARGET_NITS

    restart_pp
}

# GUI USERCONF
gui_userconf () {
    if [[ -f "${portwine_exe}" ]] ; then
        export PW_YAD_FORM_TAB="1"
        export TAB_START="2"
    fi

    if [[ "$MIRROR" == "CLOUD" ]]
    then NEW_MIRROR="GITHUB"
    else NEW_MIRROR="CLOUD"
    fi

    if [[ "$BRANCH" == "master" ]]
    then NEW_BRANCH="DEVEL"
    else NEW_BRANCH="STABLE"
    fi

    if [[ "$DOWNLOAD_STEAM_GRID" == "1" ]]
    then NEW_STEAM_BEHAVIOR="${translations[Disable]}"
    else NEW_STEAM_BEHAVIOR="${translations[Enable]}"
    fi

    if [[ "$PW_GUI_START" == "NOTEBOOK" ]]
    then NEW_START_GUI="PANED"
    else NEW_START_GUI="NOTEBOOK"
    fi

    KEY_USERCONF_GUI=$RANDOM

    "${pw_yad}" --plug=$KEY_USERCONF_GUI --tabnum="1" --form --columns=2 --separator=" " --text-align=center \
    --text "${translations[Change global settings]} <b>(edit user.conf)</b>\n ${translations[<b>NOTE:</b> To display help for each item, simply hover your mouse over the text]}" \
    --align-buttons --homogeneous-column --gui-type-text="${PANED_GUI_TYPE_TEXT_UP}" --gui-type-layout="${PANED_GUI_TYPE_LAYOUT_UP}" \
    --field="   ${translations[Change mirror to]} $NEW_MIRROR"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE_MM.png"!"${translations[Depending on which mirror is selected, updates will be downloaded from there.]}":"FBTN" '@bash -c "button_click --userconf change_mirror"' \
    --field="   ${translations[Change branch to]} $NEW_BRANCH"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE_MM.png"!"${translations[Depending on the version of the scripts, PortProton will receive the latest changes first (the DEVEL branch), the STABLE branch is updated later and is stable.]}":"FBTN" '@bash -c "button_click --userconf change_branch"' \
    --field="   ${translations[Change start gui to]} $NEW_START_GUI"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE_MM.png"!"${translations[When using PANED in the game start menu, additional buttons are located on one large page; if NOTEBOOK, then they are divided into several.]}":"FBTN" '@bash -c "button_click --userconf change_gui_start"' \
    --field="   $NEW_STEAM_BEHAVIOR ${translations[steam covers download]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE_MM.png"!"${translations[If downloading steam covers is enabled, they will be downloaded and created. (Disablement is provided in cases where their downloading is unavailable for some reason)]}":"FBTN" '@bash -c "button_click --userconf change_download_grid"' \
    2>/dev/null &

    if [[ -n "${PW_SOUND_DRIVER_USE}" ]] \
    && [[ "${PW_SOUND_DRIVER_USE}" != "disabled" ]]
    then
        SOUND_DRIVER_VAR="${PW_SOUND_DRIVER_USE}"
    else
        SOUND_DRIVER_VAR="disabled"
    fi

    if [[ -n "${PW_GPU_USE}" ]] \
    && [[ "${PW_GPU_USE}" != "disabled" ]]
    then
        GPU_VAR="${PW_GPU_USE}"
    else
        GPU_VAR="disabled"
    fi

    if [[ -n "${DESKTOP_WITH_TIME}" ]] \
    && [[ "${DESKTOP_WITH_TIME}" != "disabled" ]]
    then
        DESKTOP_WITH_TIME="enabled"
    else
        DESKTOP_WITH_TIME="disabled"
    fi

    if [[ -n "${SORT_WITH_TIME}" ]] \
    && [[ "${SORT_WITH_TIME}" == "disabled" ]]
    then
        SORT_WITH_TIME="disabled"
    else
        SORT_WITH_TIME="enabled"
    fi

    "${pw_yad}" --plug=$KEY_USERCONF_GUI --tabnum="2" --form --columns=1 --separator="%" --homogeneous-row \
    --gui-type-text="$PANED_GUI_TYPE_TEXT_DOWN" --gui-type-layout="$PANED_GUI_TYPE_LAYOUT_DOWN" \
    --field="${translations[Choose a graphics card to run the game]}!${translations[Select which video card will be used to run the game (used for all running games and programs in PortProton)]} :CB" "$(combobox_fix --disabled "$GPU_VAR" "$GET_GPU_NAMES")" \
    --field="${translations[Choice wine audio driver]}!${translations[Fixes sound popling if choice alsa]} :CB" "$(combobox_fix --disabled "$SOUND_DRIVER_VAR" "alsa!oss!pulse")" \
    --field="${translations[Choice gui themes]}!${translations[Allows you to select a theme for PortProton]} :CB" "$(combobox_fix "$GUI_THEME" "default!compact!classic")" \
    --field="${translations[Time display]}!${translations[Displays time spent in an application or game]} :CB" "$(combobox_fix --disabled "$DESKTOP_WITH_TIME" "enabled")" \
    --field="${translations[Sort shortcuts by time]}!${translations[This setting sorts the shortcuts in the main menu depending on the time spent in the application or game]} :CB" "$(combobox_fix --disabled "$SORT_WITH_TIME" "enabled")" \
    1> "${PW_TMPFS_PATH}/tmp_yad_userconf_set_cb" 2>/dev/null &

    "${pw_yad}" --key=$KEY_USERCONF_GUI --paned --sensitive \
    --title="${translations[GLOBAL SETTINGS (USER.CONF)]}" \
    --separator=" " --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --gui-type="settings-paned" \
    --button="${translations[CANCEL THE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Cancel the current changes and return to the previous menu]}":1 \
    --button="${translations[RESET]} USER.CONF"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Restore default settings for]} user.conf":2 \
    --button="${translations[OPEN THE SETTINGS FILE]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Open the <b>user.conf</b> settings file in a system text editor to view and change variables manually]}":164 \
    --button="${translations[SAVE CHANGES]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Save the current changes, and go to the previous menu]}":166 \
    2>/dev/null
    YAD_USERCONF_STATUS="$?"

    case "$YAD_USERCONF_STATUS" in
        1|252)
            restart_pp
            ;;
        2)
            if yad_question "${translations[Do you really want to reset settings for]} <b>user.conf</b>?"
            then
                try_remove_file "$USER_CONF"
                exit 0
            else
                restart_pp --userconf
            fi
            ;;
        164)
            gui_open_user_conf
            ;;
        166)
            IFS='%' read -r -a PW_ADD_SETTINGS_UC <"${PW_TMPFS_PATH}/tmp_yad_userconf_set_cb"
            IFS="$orig_IFS"
            PW_GPU_USE="${PW_ADD_SETTINGS_UC[0]}"
            PW_SOUND_DRIVER_USE="${PW_ADD_SETTINGS_UC[1]}"
            GUI_THEME="${PW_ADD_SETTINGS_UC[2]}"
            DESKTOP_WITH_TIME="${PW_ADD_SETTINGS_UC[3]}"
            SORT_WITH_TIME="${PW_ADD_SETTINGS_UC[4]}"
            edit_user_conf_from_gui PW_GPU_USE PW_SOUND_DRIVER_USE GUI_THEME DESKTOP_WITH_TIME SORT_WITH_TIME
            restart_pp
            ;;
    esac

    pw_yad_set_form
    case "$PW_YAD_SET" in
        change_mirror)
            change_mirror
            ;;
        change_branch)
            change_branch
            ;;
        change_gui_start)
            change_gui_start
            ;;
        change_download_grid)
            change_download_grid
            ;;
    esac
}

# RESIZE PNG FILE
resize_png () {
    if [[ -z "$1" ]] || [[ -z "$2" ]] || [[ -z "$3" ]] ; then
        print_error "no argument specified for resize_png"
        return 1
    else
        local RESIZE_FILE="$1"
        local RESIZE_NAME_PNG="${2// /_}"
        local RESIZE_TO="$3"
    fi

    if [[ -f "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png" ]] \
    || [[ ! -f "${RESIZE_FILE}" ]]
    then
        return 0
    fi
    try_remove_file "${PORT_WINE_PATH}/data/img/launcher.png"
    try_remove_file "${PORT_WINE_PATH}/data/img/Launcher.png"

    if check_flatpak ; then
        if ! timeout 3 \
        exe-thumbnailer --force-resize -s "$RESIZE_TO" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png" \
        && [[ "$ALPINE_FP" != "1" ]]
        then
            print_error "exe-thumbnailer - broken!"
        fi
    else
        print_warning "use portable exe-thumbnailer"
        env PYTHONPATH="${PW_PLUGINS_PATH}/portable/lib/python3.9/site-packages/" \
        LD_LIBRARY_PATH="${PW_PLUGINS_PATH}/portable/lib/lib64" \
        "${PW_WINELIB}/runtime/files/bin/python3.9"  \
        "${PW_PLUGINS_PATH}/portable/bin/exe-thumbnailer" --force-resize -s "$RESIZE_TO" "$(readlink -f "${RESIZE_FILE}")" "${PORT_WINE_PATH}/data/img/${RESIZE_NAME_PNG}.png"
    fi
    return 0
}

# GUI CREATE SHORTCUT
portwine_create_shortcut () {
    export GDK_BACKEND="x11"
    pw_stop_progress_bar
    pw_exit_tray
    [[ ! -e ${portwine_exe} ]] && return 1
    unset PORTPROTON_NAME name_desktop_png
    pw_create_gui_png

    [[ -z "${PW_SHORTCUT_MENU}" ]] && PW_SHORTCUT_MENU="TRUE"
    [[ -z "${PW_SHORTCUT_DESKTOP}" ]] && PW_SHORTCUT_DESKTOP="TRUE"
    [[ -z "${PW_SHORTCUT_STEAM}" ]] && PW_SHORTCUT_STEAM="FALSE"

    unset name_desktop
    create_name_desktop
    export name_desktop="$PW_NAME_DESKTOP_PROXY"

    [[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}"

    OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \
    --gui-type="settings-shortcut" \
    --gui-type-box="${NOTEBOOK_GUI_TYPE_BOX}" --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" \
    --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" --gui-type-images="${NOTEBOOK_GUI_TYPE_IMAGE}" \
    --window-icon "$PW_GUI_ICON_PATH/portproton.svg" \
    --image "${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" \
    --text-align="center" --text "${translations[The shortcut will be created in the PortProton directory.]}" \
    --field="${translations[Name]}" "${name_desktop}" \
    --field="  ${translations[Add shortcut to MENU -> GAMES]}":CHK "$PW_SHORTCUT_MENU" \
    --field="  ${translations[Add shortcut to Desktop]}":CHK "$PW_SHORTCUT_DESKTOP" \
    --field="  ${translations[Add shortcut to STEAM library]}":CHK "$PW_SHORTCUT_STEAM" \
    --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":2 \
    --button="${translations[CREATE SHORTCUT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null)
    PW_YAD_OUT=$?
    portwine_output_yad_shortcut
}

portwine_output_yad_shortcut () {
    if [[ "$PW_YAD_OUT" == "0" ]] ; then
        name_desktop=$(echo "$OUTPUT" | awk -F'|' '{print $1}' | sed "s/\`//g" | sed "s/\"//g" | sed "s/'//g" | sed "s/\!//g")
        PW_SHORTCUT_MENU=$(echo "$OUTPUT" | awk -F'|' '{print $2}')
        PW_SHORTCUT_DESKTOP=$(echo "$OUTPUT" | awk -F'|' '{print $3}')
        PW_SHORTCUT_STEAM=$(echo "$OUTPUT" | awk -F'|' '{print $4}')

        if [[ $PORTWINE_CHANGE_SHORTCUT != 1 ]] ; then
            edit_user_conf_from_gui PW_SHORTCUT_MENU PW_SHORTCUT_DESKTOP PW_SHORTCUT_STEAM
        fi

        portwine_delete_shortcut

        [[ -z $name_desktop ]] && create_name_desktop && export name_desktop="$PW_NAME_DESKTOP_PROXY"

        echo "[Desktop Entry]" > "${PORT_WINE_PATH}/${name_desktop}.desktop"
        echo "Name=${name_desktop}" >> "${PORT_WINE_PATH}/${name_desktop}.desktop"
        if check_flatpak
        then echo "Exec=flatpak run ru.linux_gaming.PortProton \"${portwine_exe}\"" >> "${PORT_WINE_PATH}/${name_desktop}.desktop"
        else echo "Exec=env \"${PORT_SCRIPTS_PATH}/start.sh\" \"${portwine_exe}\"" >> "${PORT_WINE_PATH}/${name_desktop}.desktop"
        fi
        {
            echo "Type=Application"
            echo "Categories=Game"
            echo "StartupNotify=true"
            echo "Path=${PORT_SCRIPTS_PATH}/"
            echo "Icon=${PORT_WINE_PATH}/data/img/${name_desktop_png}.png"
        } >> "${PORT_WINE_PATH}/${name_desktop}.desktop"
        chmod u+x "${PORT_WINE_PATH}/${name_desktop}.desktop"

        if [[ "${PW_SHORTCUT_MENU}" == "TRUE" ]] ; then
            try_remove_file "${HOME}/.local/share/applications/${name_desktop}.desktop"
            cp -f "${PORT_WINE_PATH}/${name_desktop}.desktop" "${HOME}/.local/share/applications/"
        fi

        if [[ "${PW_SHORTCUT_DESKTOP}" == "TRUE" ]] ; then
            if [[ -d "${HOME}/Desktop" ]] ; then
                cp -f "${PORT_WINE_PATH}/${name_desktop}.desktop" "${HOME}/Desktop/"
            elif [[ -d "${HOME}/Рабочий стол" ]] ; then
                cp -f "${PORT_WINE_PATH}/${name_desktop}.desktop" "${HOME}/Рабочий стол/"
            elif [[ $(xdg-user-dir DESKTOP) ]] ; then
                cp -f "${PORT_WINE_PATH}/${name_desktop}.desktop" "$(xdg-user-dir DESKTOP)"
            fi
        fi

        if [[ "${PW_SHORTCUT_STEAM}" == "TRUE" ]] ; then
            export STEAM_SCRIPTS="${PORT_WINE_PATH}/steam_scripts"
            create_new_dir "${STEAM_SCRIPTS}"
            echo "#!/usr/bin/env bash" > "${STEAM_SCRIPTS}/${name_desktop}.sh"
            echo "export START_FROM_STEAM=1" >> "${STEAM_SCRIPTS}/${name_desktop}.sh"
            echo "export LD_PRELOAD=" >> "${STEAM_SCRIPTS}/${name_desktop}.sh"
            if check_flatpak
            then echo "flatpak run ru.linux_gaming.PortProton \"${portwine_exe}\" " >> "${STEAM_SCRIPTS}/${name_desktop}.sh"
            else echo "\"${PORT_SCRIPTS_PATH}/start.sh\" \"${portwine_exe}\" " >> "${STEAM_SCRIPTS}/${name_desktop}.sh"
            fi
            chmod u+x "${STEAM_SCRIPTS}/${name_desktop}.sh"
            export SCVDF="shortcuts.vdf"
            for STUIDPATH in "${HOME}"/.local/share/Steam/userdata/*/; do
                if [[ -d "$STUIDPATH" ]]; then
                    create_new_dir "${STUIDPATH}config/"
                    create_new_dir "${STUIDPATH}config/grid"
                    export SCPATH="${STUIDPATH}config/$SCVDF"
                    export SGGRIDDIR="${STUIDPATH}config/grid"
                    # shellcheck source=/dev/null
                    source "${PORT_SCRIPTS_PATH}/add_in_steam.sh"
                fi
            done

            if [[ "${PW_SKIP_RESTART_STEAM}" != 1 ]] && pgrep -i steam &>/dev/null ; then
                if yad_question "${translations[For adding shortcut to STEAM, needed restart.\\n\\nRestart STEAM now?]}" ; then
                    pw_start_progress_bar_block "${translations[Restarting STEAM... Please wait.]}"
                    kill -s SIGTERM $(pgrep -a steam) &>/dev/null
                    while pgrep -i steam &>/dev/null ; do
                        sleep 0.5
                    done
                    steam &
                    sleep 5
                    pw_stop_progress_bar
                    exit 0
                fi
            fi
            unset PW_SKIP_RESTART_STEAM
        fi

        export PW_NEW_DESKTOP="1"

        if [[ "$PW_NO_RESTART_PPDB" != "1" ]] ; then
            print_info "Restarting PP..."
            [[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB
            restart_pp
        fi
    elif [[ "$PW_YAD_OUT" =~ (^1$|^2$|^252$) ]] ; then
        print_info "Restarting PP..."
        [[ -n $KEY_MENU ]] && unset portwine_exe
        [[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB
        [[ -z $LINKS ]] && restart_pp
    fi
}

pw_auto_create_shortcut () {
    if [[ "${PW_CHECK_AUTOINSTALL}" == "1" ]] \
    || [[ "${PW_NO_AUTO_CREATE_SHORTCUT}" == "1" ]] \
    || [[ -z "${portwine_exe}" ]] \
    || echo "${portwine_exe}" | grep -i "gc_api.exe\|vkplay\|pulseonline" &>/dev/null
    then
        print_warning "Skipping auto create shortcut"
        return 0
    fi

    unset LINKS
    for link_file in "${PORT_WINE_PATH}"/data/prefixes/*/drive_c/users/*/Desktop/*.lnk
    do
        link_file=$(readlink -f "${link_file}")
        LINKS+=(${link_file// /@_@})
    done

    [[ -z "${LINKS[0]}" ]] && return 0
    read -r -a SORTED_LINKS < <(echo ${LINKS[@]} | tr ' ' '\n' | sort -u | tr '\n' ' ')

    for link_file in "${SORTED_LINKS[@]//@_@/ }" ; do
        if command -v exiftool &>/dev/null ; then
            if timeout 3 exiftool "$link_file" &> "${PW_TMPFS_PATH}/exiftool.tmp" ; then
                prefix_name=$(echo "$link_file" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
                if fix_icon_name=$(grep -i "Icon File Name" "${PW_TMPFS_PATH}/exiftool.tmp" 2>/dev/null) \
                && [[ "${fix_icon_name//*.exe/true}" == "true" ]] ; then
                    link_drive=$(sed -n 's/^Icon File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | cut -d: -f1 | awk '{print tolower($0)}')
                    link_path=$(sed -n 's/^Icon File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|%ProgramFiles(x86)%|C:\\Program Files (x86)|gi;s|%ProgramFiles%|C:\\Program Files|gi' | sed "s|^.|${PORT_WINE_PATH}/data/prefixes/$prefix_name/dosdevices/$link_drive|g" | sed 's/\\/\//g')
                else
                    link_drive=$(sed -n 's/^Local Base Path\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | cut -d: -f1 | awk '{print tolower($0)}')
                    link_path=$(sed -n 's/^Local Base Path\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|%ProgramFiles(x86)%|C:\\Program Files (x86)|gi;s|%ProgramFiles%|C:\\Program Files|gi' | sed "s|^.|${PORT_WINE_PATH}/data/prefixes/$prefix_name/dosdevices/$link_drive|g" | sed 's/\\/\//g')
                fi
                link_name=$(sed -n 's/^File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|\.lnk||')
                link_cmd=$(sed -n 's/^Command Line Arguments\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
            else
                print_error "exiftool - broken!"
            fi
        else
            print_warning "use portable exiftool"
            env PERL5LIB="${PW_PLUGINS_PATH}/portable/lib/perl5" "${PW_PLUGINS_PATH}/portable/bin/exiftool" "$link_file" &> "${PW_TMPFS_PATH}/exiftool.tmp"
            prefix_name=$(echo "$link_file" | awk -F"/prefixes/" '{print $2}' | awk -F"/" '{print $1}')
            if fix_icon_name=$(grep -i "Icon File Name" "${PW_TMPFS_PATH}/exiftool.tmp" 2>/dev/null) \
            && [[ "${fix_icon_name//*.exe/true}" == "true" ]] ; then
                link_drive=$(sed -n 's/^Icon File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | cut -d: -f1 | awk '{print tolower($0)}')
                link_path=$(sed -n 's/^Icon File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|%ProgramFiles(x86)%|C:\\Program Files (x86)|gi;s|%ProgramFiles%|C:\\Program Files|gi' | sed "s|^.|${PORT_WINE_PATH}/data/prefixes/$prefix_name/dosdevices/$link_drive|g" | sed 's/\\/\//g')
            else
                link_drive=$(sed -n 's/^Local Base Path\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | cut -d: -f1 | awk '{print tolower($0)}')
                link_path=$(sed -n 's/^Local Base Path\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|%ProgramFiles(x86)%|C:\\Program Files (x86)|gi;s|%ProgramFiles%|C:\\Program Files|gi' | sed "s|^.|${PORT_WINE_PATH}/data/prefixes/$prefix_name/dosdevices/$link_drive|g" | sed 's/\\/\//g')
            fi
            link_name=$(sed -n 's/^File Name\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp" | sed 's|\.lnk||')
            link_cmd=$(sed -n 's/^Command Line Arguments\s*:\s*//p' "${PW_TMPFS_PATH}/exiftool.tmp")
        fi

        if ! exe_path="$(realpath "${link_path}" 2>/dev/null)" ; then
            print_warning "Link broken for: $link_name"
        else
            print_info "Created link for: $link_name"
            PORTPROTON_NAME="$link_name"
            export portwine_exe="$exe_path"
            resize_png "$portwine_exe" "${PORTPROTON_NAME}" "128"
            export PW_NO_RESTART_PPDB=1
            portwine_create_shortcut
        fi
    done
}
export -f pw_auto_create_shortcut

# GUI CHANGE SHORTCUT
portwine_change_shortcut () {
    export GDK_BACKEND="x11"

    portwine_search_shortcut
    if [[ -n $PW_DELETE_MENU ]]
    then PW_SHORTCUT_MENU="TRUE"
    else PW_SHORTCUT_MENU="FALSE"
    fi
    if [[ -n ${PW_DELETE_SHORTCUT_DESKTOP[0]} ]]
    then PW_SHORTCUT_DESKTOP="TRUE"
    else PW_SHORTCUT_DESKTOP="FALSE"
    fi
    PW_SHORTCUT_STEAM="FALSE"

    unset name_desktop
    create_name_desktop
    export name_desktop="$PW_NAME_DESKTOP_PROXY"

    [[ -z "${name_desktop_png}" ]] && name_desktop_png="${PORTPROTON_NAME// /_}"

    OUTPUT=$("${pw_yad}" --title="${translations[Choices]}" --form \
    --gui-type="settings-shortcut" \
    --gui-type-box="${NOTEBOOK_GUI_TYPE_BOX}" --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" \
    --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" --gui-type-images="${NOTEBOOK_GUI_TYPE_IMAGE}" \
    --window-icon "$PW_GUI_ICON_PATH/portproton.svg" \
    --image "${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" \
    --text-align="center" --text "${translations[The shortcut will be changed in the PortProton directory.]}" \
    --field="${translations[Name]}" "${name_desktop}" \
    --field="  ${translations[Add shortcut to MENU -> GAMES]}":CHK "$PW_SHORTCUT_MENU" \
    --field="  ${translations[Add shortcut to Desktop]}":CHK "$PW_SHORTCUT_DESKTOP" \
    --field="  ${translations[Add shortcut to STEAM library]}":CHK "$PW_SHORTCUT_STEAM" \
    --button="${translations[REMOVE SHORTCUT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1 \
    --button="${translations[CHANGE SHORTCUT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null)
    PW_YAD_OUT=$?
    PORTWINE_CHANGE_SHORTCUT=1
    if [[ $PW_YAD_OUT == 1 ]] ; then
        [[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB
        portwine_delete_shortcut
        restart_pp
    fi
    portwine_output_yad_shortcut
}

portwine_search_shortcut () {
    unset PW_DELETE_SHORTCUT_MENU PW_DELETE_SHORTCUT_DESKTOP
    PW_DELETE_MENU="$(grep -il "${portwine_exe}" "${HOME}/.local/share/applications"/*.desktop 2>/dev/null)"
    PW_DELETE_SHORTCUT_MENU+=(${PW_DELETE_MENU// /@_@})

    PW_DELETE_PP="$(grep -il "${portwine_exe}" "${PORT_WINE_PATH}"/*.desktop 2>/dev/null)"
    PW_DELETE_SHORTCUT_MENU+=(${PW_DELETE_PP// /@_@})

    if [[ -d "${HOME}/Desktop" ]] ; then
        PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Desktop"/*.desktop 2>/dev/null)"
        PW_DELETE_SHORTCUT_DESKTOP+=(${PW_DELETE_DESKTOP// /@_@})
    fi
    if [[ -d "${HOME}/Рабочий стол" ]] ; then
        PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Рабочий стол"/*.desktop 2>/dev/null)"
        PW_DELETE_SHORTCUT_DESKTOP+=(${PW_DELETE_DESKTOP// /@_@})
    fi
    if [[ $(xdg-user-dir DESKTOP) ]] ; then
        PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "$(xdg-user-dir DESKTOP)"/*.desktop 2>/dev/null)"
        PW_DELETE_SHORTCUT_DESKTOP+=(${PW_DELETE_DESKTOP// /@_@})
    fi
}

portwine_delete_shortcut () {
    if [[ $PORTWINE_CHANGE_SHORTCUT != 1 ]] ; then
        portwine_search_shortcut
    fi
    unset PORTWINE_CHANGE_SHORTCUT

    for delete_shortcut in ${PW_DELETE_SHORTCUT_MENU[@]} ${PW_DELETE_SHORTCUT_DESKTOP[@]} ; do
        rm -f "${delete_shortcut//@_@/ }"
    done
}

portwine_missing_shortcut () {
    "${pw_yad}" --title="${translations[Error]}" --form \
    --window-icon "$PW_GUI_ICON_PATH/portproton.svg" --fixed \
    --image "$PW_GUI_ICON_PATH/error.svg" \
    --text "\n${translations[Could not find the file:]}\n$(print_wrapped "${portwine_exe}" "50")\n\n${translations[ATTENTION:\\nIf you forgot to mount the disk with the running application, click CANCEL!]}\n" \
    --button="${translations[DELETE SHORTCUT]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 \
    --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1
    if [[ $? -eq "0" ]] ; then
        portwine_delete_shortcut
    fi
    if [[ -n "$TAB_MAIN_MENU" ]]
    then restart_pp
    else exit 0
    fi
}

# GUI WINETRICKS | GUI PREFIX MANAGER
pw_prefix_manager () {
    update_winetricks
    start_portwine
    if [[ ! -f "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ]] ; then
        touch "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log"
    fi

    pw_start_progress_bar_block "${translations[Starting prefix manager:]} $PW_PREFIX_NAME"
    "${PORT_WINE_TMP_PATH}/winetricks" dlls list | awk -F'(' '{print $1}' 1> "${PW_TMPFS_PATH}/dll_list"
    "${PORT_WINE_TMP_PATH}/winetricks" fonts list | awk -F'(' '{print $1}' 1> "${PW_TMPFS_PATH}/fonts_list"
    "${PORT_WINE_TMP_PATH}/winetricks" settings list | awk -F'(' '{print $1}' 1> "${PW_TMPFS_PATH}/settings_list"

    gui_prefix_manager () {
        unset SET_FROM_PFX_MANAGER_TMP SET_FROM_PFX_MANAGER
        IFS=$'\n'
        try_remove_file "${PW_TMPFS_PATH}/dll_list_tmp"
        while read -r PW_BOOL_IN_DLL_LIST ; do
            if [[ ! ${PW_BOOL_IN_DLL_LIST} =~ (d3d|directx9|dont_use|dxvk|vkd3d|galliumnine|faudio1|Foundation) ]] ; then
                if grep ^"$(echo "${PW_BOOL_IN_DLL_LIST}" | awk '{print $1}')"$ "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ; then
                    echo -e "true\n$(echo "${PW_BOOL_IN_DLL_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_DLL_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/dll_list_tmp"
                else
                    echo -e "false\n$(echo "${PW_BOOL_IN_DLL_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_DLL_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/dll_list_tmp"
                fi
            fi
        done < "${PW_TMPFS_PATH}/dll_list"
        try_remove_file "${PW_TMPFS_PATH}/fonts_list_tmp"
        while read -r PW_BOOL_IN_FONTS_LIST ; do
            if [[ ! ${PW_BOOL_IN_FONTS_LIST} =~ dont_use ]] ; then
                if grep ^"$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')"$ "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ; then
                    echo -e "true\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/fonts_list_tmp"
                else
                    echo -e "false\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/fonts_list_tmp"
                fi
            fi
        done < "${PW_TMPFS_PATH}/fonts_list"
        try_remove_file "${PW_TMPFS_PATH}/settings_list_tmp"
        while read -r PW_BOOL_IN_FONTS_LIST ; do
            if [[ ! ${PW_BOOL_IN_FONTS_LIST} =~ (vista|alldlls|autostart_|bad|good|win|videomemory|vd=|isolate_home) ]] ; then
                if grep ^"$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')"$ "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" ; then
                    echo -e "true\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/settings_list_tmp"
                else
                    echo -e "false\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{print $1}')\n$(echo "${PW_BOOL_IN_FONTS_LIST}" | awk '{ $1 = ""; print substr($0, 2) }')" >> "${PW_TMPFS_PATH}/settings_list_tmp"
                fi
            fi
        done < "${PW_TMPFS_PATH}/settings_list"
        pw_stop_progress_bar

        KEY_EDIT_MANAGER_GUI=$RANDOM
        "${pw_yad}" --plug=$KEY_EDIT_MANAGER_GUI --tabnum=1 --list --checklist \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --text="${translations[Select components to install in prefix:]} <b>\"${PW_PREFIX_NAME}\"</b>, ${translations[using wine:]} <b>\"${PW_WINE_USE}\"</b>" \
        --column="${translations[Set]}" --column="${translations[Libraries]}" \
        --column="${translations[Information]}" < "${PW_TMPFS_PATH}/dll_list_tmp" 1>> "${PW_TMPFS_PATH}/to_winetricks" 2>/dev/null &

        "${pw_yad}" --plug=$KEY_EDIT_MANAGER_GUI --tabnum=2 --list --checklist \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --text="${translations[Select fonts to install in prefix:]} <b>\"${PW_PREFIX_NAME}\"</b>, ${translations[using wine:]} <b>\"${PW_WINE_USE}\"</b>" \
        --column="${translations[Set]}" --column="${translations[Libraries]}" \
        --column="${translations[Information]}" < "${PW_TMPFS_PATH}/fonts_list_tmp" 1>> "${PW_TMPFS_PATH}/to_winetricks" 2>/dev/null &

        "${pw_yad}" --plug=$KEY_EDIT_MANAGER_GUI --tabnum=3 --list --checklist \
        --gui-type-layout="${NOTEBOOK_GUI_TYPE_LAYOUT}" --gui-type-text="${NOTEBOOK_GUI_TYPE_TEXT}" \
        --text="${translations[Change config for prefix:]} <b>\"${PW_PREFIX_NAME}\"</b>" \
        --column="${translations[Set]}" --column="${translations[Libraries]}" \
        --column="${translations[Information]}" < "${PW_TMPFS_PATH}/settings_list_tmp" 1>> "${PW_TMPFS_PATH}/to_winetricks" 2>/dev/null &

        "${pw_yad}" --key=$KEY_EDIT_MANAGER_GUI --notebook \
        --width=700 --height=700 --expand \
        --gui-type="settings-notebook" \
        --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "${translations[PREFIX MANAGER]}" \
        --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":1 \
        --button="${translations[FORCE INSTALL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Installation with forced redownload of libraries]}":2 \
        --button="${translations[INSTALL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"${translations[Standard installation.]}":0 \
        --tab-pos="top" \
        --tab="${translations[DLLS]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="${translations[FONTS]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" \
        --tab="${translations[SETTINGS]}"!"$PW_GUI_ICON_PATH/$TAB_SIZE.png"!"" 2>/dev/null
        YAD_STATUS="$?"

        try_remove_file  "${PW_TMPFS_PATH}/dll_list_tmp"
        try_remove_file  "${PW_TMPFS_PATH}/fonts_list_tmp"
        try_remove_file  "${PW_TMPFS_PATH}/settings_list_tmp"

        case "$YAD_STATUS" in
            0)
                WT_FORCE=""
                ;;
            2)
                WT_FORCE="-r -f"
                ;;
        esac

        for STPFXMNG in $(<"${PW_TMPFS_PATH}/to_winetricks") ; do
            grep $(echo ${STPFXMNG} | awk -F'|' '{print $2}') "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" &>/dev/null
            if [[ "$?" == "1" ]] ; then
                [[ -n "${STPFXMNG}" ]] && SET_FROM_PFX_MANAGER+="$(echo "${STPFXMNG}" | awk -F'|' '{print $2}') "
            fi
        done
        IFS="$orig_IFS"
        try_remove_file "${PW_TMPFS_PATH}/to_winetricks"

        if [[ -n ${SET_FROM_PFX_MANAGER} ]] ; then
            pw_update_pfx_cover_gui "winetricks"
            echo "START WINETRICKS..." >> "${PW_TMPFS_PATH}/update_pfx_log"
            echo "Try to install DLL in prefix: ${SET_FROM_PFX_MANAGER}" >> "${PW_TMPFS_PATH}/update_pfx_log"
            print_info "Try to install DLL in prefix: ${SET_FROM_PFX_MANAGER}"
            ${pw_runtime} LD_LIBRARY_PATH="${PW_LD_LIBRARY_PATH}" GST_PLUGIN_SYSTEM_PATH_1_0="" \
            "${PORT_WINE_TMP_PATH}/winetricks" -q ${WT_FORCE} ${SET_FROM_PFX_MANAGER} | tee -a "${PW_TMPFS_PATH}/update_pfx_log"
            wait_wineserver
            kill_portwine
            pw_stop_progress_bar
            gui_prefix_manager
        else
            print_info "Nothing to do. Restarting PortProton..."
            stop_portwine --restart
        fi
    }
    gui_prefix_manager
}

portwine_start_debug () {
    pw_skip_get_info
    kill_portwine
    export PW_LOG=1
    if [[ -z "$VULKAN_DRIVER_NAME" ]] || [[ "$VULKAN_DRIVER_NAME" == "llvmpipe" ]] ; then
        pw_notify_send -i warning \
        "${translations[Attention working version of vulkan not detected!]}" \
        "${translations[It is recommended to run games in OpenGL (low performance possible)!]}"
    fi
    echo "${translations[PortProton was launched in creation mode PortProton.log and it is successfully stored in the root directory of the port]}" > "${PORT_WINE_PATH}/PortProton.log"
    echo "${translations[To diagnose the problem, copy ALL of the log to:]} https://linux-gaming.ru/t/opisanie-kategorii-portproton-pomoshh/1642" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "PortWINE version:" >> "${PORT_WINE_PATH}/PortProton.log"
    read install_ver < "${PORT_WINE_TMP_PATH}/PortProton_ver"
    echo "PortProton-${install_ver}" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Scripts version:" >> "${PORT_WINE_PATH}/PortProton.log"
    cat "${PORT_WINE_TMP_PATH}/scripts_ver" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-----------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if check_flatpak ; then
        echo "FLATPAK in used" >> "${PORT_WINE_PATH}/PortProton.log"
    elif [[ "${PW_USE_RUNTIME}" = 0 ]] ; then
        echo "RUNTIME is disabled" >> "${PORT_WINE_PATH}/PortProton.log"
    else
        echo "RUNTIME is enabled" >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "----------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if [[ -n "${portwine_exe}" ]] ; then
        echo "Debug for programm:" >> "${PORT_WINE_PATH}/PortProton.log"
        echo "${portwine_exe}" >> "${PORT_WINE_PATH}/PortProton.log"
        echo "---------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "GLIBC version:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo $(ldd --version | grep -m1 ldd | awk '{print $NF}') >> "${PORT_WINE_PATH}/PortProton.log"
    echo "--------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    case "$PW_VULKAN_USE" in
        0) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - DirectX to wined3d opengl" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        1) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - DXVK v.${DXVK_STABLE_VER}, VKD3D-PROTON v.${VKD3D_STABLE_VER}" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        2) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - DXVK v.${DXVK_GIT_VER}, VKD3D-PROTON v.${VKD3D_GIT_VER}" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        3) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - Native DX9 on MESA drivers" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        4) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - OpenGL on MESA vulkan drivers" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        5) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - DXVK v.${DXVK_LEGACY_VER}" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        6) echo "PW_VULKAN_USE=${PW_VULKAN_USE} - DirectX to wined3d vulkan" >> "${PORT_WINE_PATH}/PortProton.log" ;;
        *) echo "PW_VULKAN_USE=${PW_VULKAN_USE}" >> "${PORT_WINE_PATH}/PortProton.log" ;;
    esac
    echo "--------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Version WINE in use:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "$PW_WINE_USE" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Program bit depth:" >> "${PORT_WINE_PATH}/PortProton.log"
    if [[ $(file "$portwine_exe") =~ x86-64 ]] ; then
        echo "64 bit" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-----------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    else
        echo "32 bit" >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "--------------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Date and time of start debug for PortProton:" >> "${PORT_WINE_PATH}/PortProton.log"
    date >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-----------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "The installation path of the PortProton:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "$PORT_WINE_PATH" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if check_flatpak ; then
        echo "Flatpak runtime:" >> "${PORT_WINE_PATH}/PortProton.log"
        grep -oP 'PRETTY_NAME="\K[^"]+' /etc/os-release  >> "${PORT_WINE_PATH}/PortProton.log"
        echo "Operating system:" >> "${PORT_WINE_PATH}/PortProton.log"
        grep -oP 'PRETTY_NAME="\K[^"]+' /run/host/etc/os-release  >> "${PORT_WINE_PATH}/PortProton.log"
    else
        echo "Operating system:" >> "${PORT_WINE_PATH}/PortProton.log"
        grep -oP 'PRETTY_NAME="\K[^"]+' /etc/os-release  >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "--------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Desktop environment:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Desktop session: ${DESKTOP_SESSION}" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Current desktop: ${XDG_CURRENT_DESKTOP}" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Session type: ${XDG_SESSION_TYPE}" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "---------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Kernel:" >> "${PORT_WINE_PATH}/PortProton.log"
    uname -r >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "CPU:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "CPU physical cores:$(grep 'cpu cores' /proc/cpuinfo | sort -u | cut -d':' -f2)" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "CPU logical cores: $(grep 'processor' /proc/cpuinfo | wc -l)" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "CPU model name:$(grep 'model name' /proc/cpuinfo | sort -u | cut -d':' -f2)" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "RAM:" >> "${PORT_WINE_PATH}/PortProton.log"
    free -m >> "${PORT_WINE_PATH}/PortProton.log"
    echo "--------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Filesystem "${PATH_TO_GAME}" - $(stat -f -c %T "${PATH_TO_GAME}")" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Filesystem "${PORT_WINE_PATH}" - $(stat -f -c %T "${PORT_WINE_PATH}")" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Filesystem "${PW_TMPFS_PATH}" - $(stat -f -c %T "${PW_TMPFS_PATH}")" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "---------------------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Graphic cards and drivers:" >> "${PORT_WINE_PATH}/PortProton.log"
    echo 'lspci -k | grep -EA3 VGA|3D|Display :' >> "${PORT_WINE_PATH}/PortProton.log"
    lspci -k | grep -EA3 'VGA|3D|Display' >> "${PORT_WINE_PATH}/PortProton.log"
    echo "----" >> "${PORT_WINE_PATH}/PortProton.log"
    command -v glxinfo &>/dev/null && glxinfo -B >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-----" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "inxi -G:" >> "${PORT_WINE_PATH}/PortProton.log"
    if ! check_flatpak ; then
        "${PW_PLUGINS_PATH}/portable/bin/inxi" -Gc0 >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    if echo "$LSPCI_VGA" | grep -i nvidia &>/dev/null ; then
        if command -v ldconfig &>/dev/null ; then
            echo "------" >> "${PORT_WINE_PATH}/PortProton.log"
            echo "ldconfig -p | grep libGLX_nvidia" >> "${PORT_WINE_PATH}/PortProton.log"
            ldconfig -p | grep libGLX_nvidia >> "${PORT_WINE_PATH}/PortProton.log"
        fi
    fi
    echo "PW_SCREEN_RESOLUTION=$PW_SCREEN_RESOLUTION" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "PW_SCREEN_PRIMARY=$PW_SCREEN_PRIMARY" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "----------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "Vulkan info device name:" >> "${PORT_WINE_PATH}/PortProton.log"
    grep -E '^GPU|deviceName|driverName' "${PW_TMPFS_PATH}/vulkaninfo.tmp" >> "${PORT_WINE_PATH}/PortProton.log"
    "${PW_PLUGINS_PATH}/portable/bin/vkcube" --c 50
    if [[ $? -eq 0 ]] ; then
        echo "Vulkan cube test passed successfully" >> "${PORT_WINE_PATH}/PortProton.log"
    else
        echo "Vulkan cube test completed with error" >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "----------------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo 'locale:' >> "${PORT_WINE_PATH}/PortProton.log"
    locale >> "${PORT_WINE_PATH}/PortProton.log"
    echo "---" >> "${PORT_WINE_PATH}/PortProton.log"
    echo 'locale -a | grep -i "$(locale | grep -e '^LANG=' | sed 's/LANG=//' | sed  's/\-8//')" :' >> "${PORT_WINE_PATH}/PortProton.log"
    locale -a | grep -i "$(locale | grep -e '^LANG=' | sed 's/LANG=//' | sed  's/\-8//')" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if [[ "${PW_USE_D3D_EXTRAS}" != 1 ]]
    then echo "D3D_EXTRAS - disabled" >> "${PORT_WINE_PATH}/PortProton.log"
    else echo "D3D_EXTRAS - enabled" >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "------------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    echo "winetricks.log:" >> "${PORT_WINE_PATH}/PortProton.log"
    cat "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/winetricks.log" | sed -e /^"d3dcomp*"/d -e /^"d3dx*"/d >> "${PORT_WINE_PATH}/PortProton.log"
    echo "-----------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if [[ -n "${PORTWINE_DB_FILE}" ]] ; then
        echo "Use ${PORTWINE_DB_FILE} db file:" >> "${PORT_WINE_PATH}/PortProton.log"
        cat "${PORTWINE_DB_FILE}" | sed '/##/d' >> "${PORT_WINE_PATH}/PortProton.log"
    else
        echo "Use ${PORT_SCRIPTS_PATH}/portwine_db/default db file:" >> "${PORT_WINE_PATH}/PortProton.log"
        cat "${PORT_SCRIPTS_PATH}/portwine_db/default" | sed '/##/d' >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "----------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"
    if [[ -f "${USER_CONF}" ]] ; then
        cat "${USER_CONF}" | sed '/bash/d' >> "${PORT_WINE_PATH}/PortProton.log"
    fi
    echo "---------------------------------------" >> "${PORT_WINE_PATH}/PortProton.log"

    export DXVK_HUD="full"

    portwine_launch &
    sleep 3
    pw_stop_progress_bar
    local PW_TIMER=0
    while read -r line || [[ -n $(pgrep -a yad | grep "yad_gui_pp --text-info --tail --button="STOP"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 --title="DEBUG"" | awk '{print $1}') ]] ; do
            sleep 0.005
            if [[ -n "${line}" ]] && ! echo "${line}" | grep -qi "kerberos\|ntlm" ; then
                echo "# ${line}"
            fi
            if [[ "${PW_TIMER}" != 1 ]] ; then
                sleep 3
                PW_TIMER=1
            fi
    done < "${PORT_WINE_PATH}/PortProton.log" | "${pw_yad}" --text-info --tail --button="STOP"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 --title="DEBUG" \
    --skip-taskbar --width=800 --height=400 --text "${translations[Please wait! After finishing the PortProton, click STOP.]}" --window-icon="$PW_GUI_ICON_PATH/portproton.svg" 2>/dev/null &&
    kill_portwine
    sed -i '/.fx$/d' "${PORT_WINE_PATH}/PortProton.log"
    sed -i '/HACK_does_openvr_work/d' "${PORT_WINE_PATH}/PortProton.log"
    sed -i '/Uploading is disabled/d' "${PORT_WINE_PATH}/PortProton.log"
    sed -i '/wine: RLIMIT_NICE is <= 20/d' "${PORT_WINE_PATH}/PortProton.log"
    sed -i '/ALT_2.24/d' "${PORT_WINE_PATH}/PortProton.log"
    sed -i '/UDEV monitor/d' "${PORT_WINE_PATH}/PortProton.log"
    deb_text=$(awk '! a[$0]++' "${PORT_WINE_PATH}/PortProton.log")
    echo "$deb_text" > "${PORT_WINE_PATH}/PortProton.log"
    "$pw_yad" --title="PortProton.log" --no-buttons --text-align=center \
    --text-info --show-uri --wrap --width=1200 --height=550  --uri-color=red \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --filename="${PORT_WINE_PATH}/PortProton.log"
    stop_portwine
}

pw_create_prefix_backup () {
    cd "$HOME" || :
    PW_PREFIX_TO_BACKUP=$("${pw_yad}" --file --directory --width=800 --height=500 \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "${translations[BACKUP PREFIX TO...]}" \
    --button="${translations[CANCEL]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":1 \
    --button="${translations[OK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png":0 2>/dev/null)
    YAD_STATUS="$?"

    if [[ "$YAD_STATUS" == "1" || "$YAD_STATUS" == "252" ]] ; then
        restart_pp
    fi
    if [[ -n "$(grep "/${PW_PREFIX_NAME}/" "${PORT_WINE_PATH}"/*.desktop )" ]] ; then
        try_remove_file "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.create_shortcut"
        grep "/${PW_PREFIX_NAME}/" "${PORT_WINE_PATH}"/*.desktop | awk -F"/${PW_PREFIX_NAME}/" '{print $2}' \
        | awk -F\" '{print $1}' > "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}/.create_shortcut"
    fi
    unset PW_SANDBOX_HOME_PATH
    pw_init_runtime
    if check_flatpak
    then TMP_ALL_PATH=""
    else TMP_ALL_PATH="LD_LIBRARY_PATH=\"${PW_LD_LIBRARY_PATH}\""
    fi
    chmod -R u+w "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}"
cat << EOF > "${PORT_WINE_TMP_PATH}"/pp_pfx_backup.sh
    #!/usr/bin/env bash
    ${TMP_ALL_PATH} mksquashfs "${PORT_WINE_PATH}/data/prefixes/${PW_PREFIX_NAME}" \
    "${PW_PREFIX_TO_BACKUP}/${PW_PREFIX_NAME}.ppack.part" -comp zstd \
    || rm -f "${PW_PREFIX_TO_BACKUP}/${PW_PREFIX_NAME}.ppack.part"
EOF
    chmod u+x "${PORT_WINE_TMP_PATH}"/pp_pfx_backup.sh
    ${pw_runtime} ${PW_TERM} "${PORT_WINE_TMP_PATH}"/pp_pfx_backup.sh
    try_remove_file "${PORT_WINE_TMP_PATH}"/pp_pfx_backup.sh
    if [[ -f "${PW_PREFIX_TO_BACKUP}/${PW_PREFIX_NAME}.ppack.part" ]] ; then
        mv -f "${PW_PREFIX_TO_BACKUP}/${PW_PREFIX_NAME}.ppack.part" "${PW_PREFIX_TO_BACKUP}/${PW_PREFIX_NAME}.ppack"
        yad_info "${translations[Backup has been successfully created for prefix:]} $PW_PREFIX_NAME"
        if [[ ! -f "${PORT_WINE_TMP_PATH}/pfx_backup_info" ]] ; then
            yad_info "${translations[Attention! Do not pass the resev copy to third parties, there is a risk of losing accounts!]}"
            echo "1" > "${PORT_WINE_TMP_PATH}/pfx_backup_info"
        fi
    else
        yad_error "${translations[An error occurred while backing up the prefix:]} $PW_PREFIX_NAME"
    fi
    restart_pp
}

pw_autoinstall_from_db () {
    export PW_USER_TEMP="${PORT_WINE_TMP_PATH}"
    export PW_FORCE_LARGE_ADDRESS_AWARE=1
    export PW_USE_GAMEMODE=0
    export PW_CHECK_AUTOINSTALL=1
    export PW_GUI_DISABLED_CS=1
    export PW_NO_WRITE_WATCH=0
    export PW_VULKAN_USE=1
    export PW_USE_EAC_AND_BE=0
    export PW_NO_FSYNC=1
    export PW_NO_ESYNC=1
    unset PORTWINE_CREATE_SHORTCUT_NAME
    export PW_DISABLED_CREATE_DB=1
    export PW_MANGOHUD=0
    export PW_VKBASALT=0
    export PW_USE_D3D_EXTRAS=1
    . "${PORT_SCRIPTS_PATH}/pw_autoinstall/${PW_YAD_SET}"

}

button_click () {
    echo "$2" > "${PW_TMPFS_PATH}/tmp_yad_form"

    case "$1" in
        --normal)
            kill -s SIGUSR1 $(pgrep -a yad | grep "\--key=${KEY_MENU}" | awk '{print $1}') > /dev/null 2>&1
            ;;
        --start)
            kill -s SIGUSR1 $(pgrep -a yad | grep "\--key=${KEY_START}" | awk '{print $1}') > /dev/null 2>&1
            ;;
        --userconf)
            kill -s SIGUSR1 $(pgrep -a yad | grep "\--key=${KEY_USERCONF_GUI}" | awk '{print $1}') > /dev/null 2>&1
            ;;
        --desktop)
            kill -s SIGUSR1 $(pgrep -a yad | grep "\--key=${KEY_MENU}" | awk '{print $1}') > /dev/null 2>&1
            PW_YAD_SET="${PORT_WINE_PATH}/${PW_YAD_SET//#@_@#/ }"
            if [[ -n $PW_DESKTOP_FILES_REGEX ]] ; then
                local count=1
                for y in "${PW_DESKTOP_FILES_REGEX[@]}" ; do
                    PW_YAD_SET="${PW_YAD_SET//#+_$count#/$y}"
                    (( count++ ))
                done
            fi
            export DESKTOP_NAME_YAD="${PW_YAD_SET//"$PORT_WINE_PATH/"/}"
            if check_flatpak
            then PW_EXEC_FROM_DESKTOP="$(grep Exec "$PW_YAD_SET" | head -n 1 | sed 's|flatpak run ru.linux_gaming.PortProton|\"${PORT_SCRIPTS_PATH}/start.sh\"|' | awk -F'=' '{print $2}')"
            else PW_EXEC_FROM_DESKTOP="$(grep Exec "$PW_YAD_SET" | head -n 1 | awk -F"=env " '{print $2}')"
            fi

            print_info "Restarting PP after choose desktop file..."
            # stop_portwine
            /usr/bin/env bash -c "${PW_EXEC_FROM_DESKTOP}" &
            exit 0
            ;;
    esac
}
export -f button_click

gui_clear_pfx () {
    if yad_question "${translations[Do you want to clear prefix in PortProton?]}" ; then
        pw_clear_pfx
        print_info "Restarting PP after clearing prefix..."
    fi
    restart_pp
}
export -f gui_clear_pfx

gui_rm_portproton () {
    if yad_question "${translations[Do you really want to remove PortProton?]}" ; then
        rm -fr "${PORT_WINE_PATH}"
        rm -fr "${PORT_WINE_TMP_PATH}"
        rm -fr "${HOME}/PortWINE"
        rm -f "$(grep -il PortProton "${HOME}/.local/share/applications"/*.desktop)"
        update-desktop-database -q "${HOME}/.local/share/applications"
        exit 0
    fi
    restart_pp
}
export -f gui_rm_portproton

gui_pw_update () {
    export PW_FORCE_UPDATE="1"
    try_remove_file "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
    print_info "Restarting PP for check update..."
    unset SKIP_CHECK_UPDATES
    restart_pp
}
export -f gui_pw_update

change_loc () {
    export PW_FORCE_CHANGE_LOC="1"
    print_info "Restarting PP for change language..."
    restart_pp
}
export -f change_loc

change_mirror () {
    if [[ "$MIRROR" == "CLOUD" ]] ; then
        sed -i 's/="CLOUD"/="GITHUB"/g' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Mirror changed to:]}" "<b>https://github.com/Castro-Fidel</b>"
    else
        sed -i 's/="GITHUB"/="CLOUD"/g' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Mirror changed to:]}" "<b>https://cloud.linux-gaming.ru</b>"
    fi
    print_info "Restarting PP for change mirror..."
    restart_pp --userconf
}
export -f change_mirror

change_branch () {
    if [[ "$BRANCH" == "master" ]] ; then
        if yad_question "${translations[Do you actually want to change the scripts version to:]} <b>DEVEL?</b>" ; then
            sed -i 's/="master"/="devel"/g' "$USER_CONF"
            export MIRROR="GITHUB"
            pw_notify_send -i info \
            "${translations[Branch changed to:]}" "<b>DEVEL</b>"
            unset SKIP_CHECK_UPDATES
            export PW_FORCE_UPDATE="1"
        fi
    else
        if yad_question "${translations[Do you actually want to change the scripts version to:]} <b>STABLE?</b>" ; then
            sed -i 's/="devel"/="master"/g' "$USER_CONF"
            echo "2024" > "${PORT_WINE_TMP_PATH}/scripts_ver"
            export PW_CHANGE_BRANCH="1"
            pw_notify_send -i info \
            "${translations[Branch changed to:]}" "<b>STABLE</b>"
            unset SKIP_CHECK_UPDATES
            export PW_FORCE_UPDATE="1"
        fi
    fi
    print_info "Restarting PP for change branch..."
    restart_pp --userconf
}
export -f change_branch

change_download_grid () {
    if [[ "$DOWNLOAD_STEAM_GRID" == "1" ]] ; then
        sed -i 's/DOWNLOAD_STEAM_GRID=.*/DOWNLOAD_STEAM_GRID="0"/' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Cover downloads are disabled]}"
    else
        sed -i 's/DOWNLOAD_STEAM_GRID=.*/DOWNLOAD_STEAM_GRID="1"/' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Cover downloads are enabled]}"
    fi
    print_info "Restarting PP for change cover download behavior..."
    restart_pp --userconf
}
export -f change_download_grid

open_game_folder () {
    xdg-open "${PATH_TO_GAME}"
    print_info "Restarting PP after open game folder..."
    restart_pp
}
export -f open_game_folder

change_gui_start () {
    if [[ "$PW_GUI_START" == "NOTEBOOK" ]] ; then
        sed -i 's/="NOTEBOOK"/="PANED"/g' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Gui start changed to:]}" "<b>PANED</b>"
    else
        sed -i 's/="PANED"/="NOTEBOOK"/g' "$USER_CONF"
        pw_notify_send -i info \
        "${translations[Gui start changed to:]}" "<b>NOTEBOOK</b>"
    fi
    print_info "Restarting PP for change gui start..."
    restart_pp --userconf
}
export -f change_gui_start

gui_wine_uninstaller () {
    start_portwine
    pw_run uninstaller
    stop_portwine --restart
}
export -f gui_wine_uninstaller

gui_open_user_conf () {
    PW_USERCONF_GUI="$("${pw_yad}" --title="${translations[EDIT USER CONFIG]}" \
    --text-info --editable --width=800 --height=600 \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --button="${translations[BACK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":1 \
    --button="${translations[SAVE]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":2 \
    --filename="${PORT_WINE_PATH}/data/user.conf" 2>/dev/null)"
    YAD_STATUS="$?"

    case "${YAD_STATUS}" in
        1|252)
                print_info "Restarting..."
                restart_pp --userconf
                ;;
            2)
                echo "${PW_USERCONF_GUI}" > "${PORT_WINE_PATH}/data/user.conf"
                print_info "Restarting..."
                restart_pp --userconf
                ;;
    esac
}
export -f gui_open_user_conf

gui_edit_db_file () {
    GUI_EDIT_DB_FILE="$("${pw_yad}" --title="${translations[EDIT DB]}" \
    --text-info --editable --width=800 --height=600 \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --button="${translations[BACK]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":1 \
    --button="${translations[SAVE]}"!"$PW_GUI_ICON_PATH/$BUTTON_SIZE.png"!"":2 \
    --filename="${PORTWINE_DB_FILE}" 2>/dev/null)"
    YAD_STATUS="$?"

    case "$YAD_STATUS" in
        1|252)
                restart_pp --edit_db
                ;;
          2)
                echo "${GUI_EDIT_DB_FILE}" > "${PORTWINE_DB_FILE}"
                restart_pp --edit_db
                ;;
    esac
}

gui_open_scripts_from_backup () {
    cd "${PORT_WINE_TMP_PATH}/scripts_backup/" || fatal
    PW_SCRIPT_FROM_BACKUP=$("${pw_yad}" --file --width=650 --height=500 \
    --window-icon="$PW_GUI_ICON_PATH/portproton.svg" --title "SCRIPTS FROM BACKUP" --file-filter="backup_scripts|scripts_v*.tar.gz" 2>/dev/null )
    YAD_STATUS="$?"

    if [[ "$YAD_STATUS" == "1" || "$YAD_STATUS" == "252" ]] ; then
        restart_pp
    fi
    unpack "$PW_SCRIPT_FROM_BACKUP" "${PORT_WINE_PATH}/data/"
    echo "0" > "${PORT_WINE_TMP_PATH}/scripts_update_notifier"
    print_info "Restarting PP after backup..."
    restart_pp
}
export -f gui_open_scripts_from_backup

#GUI CREDITS AND ABOUT
gui_credits () {
    ########################################################################
    # grep ';subscription;' stat-subscriptions.csv | awk -F';' '{print $1}' | sort -u | sed "s/\"//g" > thanks
    ########################################################################
    KEY_CREDITS=$RANDOM

    # shellcheck source=/dev/null
    source "${PORT_WINE_PATH}/data/scripts/thanks"

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=1 --show-uri --scroll \
    --text-align=center --text="${translations[PortProton v. \${install_ver}
scripts v. \${scripts_install_ver}]}" --text-info <<< "https://linux-gaming.ru

$(eval_translations "Copyright © \$%DATE% Castro-Fidel (linux-gaming.ru)" "DATE=$(date +%Y)")

${translations[This program comes with absolutely no warranty.
See the License for details.]}" 2>/dev/null &

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=2 --scroll \
    --text-info <<< "${translations[Author:   Casro-Fidel (Mikhail Tergoev)

Developer assistants and testers:]}
$(credits_devel)" 2>/dev/null &

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=3 --text-info --scroll <<< "$(eval_translations "MIT License

Copyright © \$%DATE% Castro-Fidel (linux-gaming.ru)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the \"Software\"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED (AS IS), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE." "DATE=$(date +%Y)")" 2>/dev/null &

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=4 \
    --text-info --show-uri --scroll \
    <<< "${translations[The project was supported:
https://boosty.to/portwine-linux.ru]}
$(credits_boosty)

${translations[The list will be updated...]}" 2>/dev/null &

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=5 \
    --text="${translations[Do you want to join and help in the development of the project:]}" \
    --image-path="$PW_GUI_ICON_PATH" --image="port_proton" \
    --uri-color=red --show-uri --text-info --scroll <<< "${translations[Website:  http://linux-gaming.ru
Discord:  http://discord.gg/yJSEFjF
VK:       https://vk.com/linuxgamingru
-------------------------------------------
Become a paid subscriber:
boosty:  https://boosty.to/portwine-linux.ru
Yandex wallet:   410012267513818
-------------------------------------------]}" 2>/dev/null &

    "${pw_yad}" --plug="${KEY_CREDITS}" --tabnum=6 --show-uri --title="THIRD PARTY LIBRARIES" \
    --text-info <<< "${translations[                               Third-party libraries that are used in PortProton

            PortProton is built on the basis of the following free software libraries:

WINE-PROTON: https://github.com/ValveSoftware/Proton
WINE-PROTON-GE: https://github.com/GloriousEggroll/proton-ge-custom/
Kron4ek/Wine: https://github.com/Kron4ek/Wine-Builds
YAD: https://github.com/v1cont/yad
DGVOODOO2: https://dege.fw.hu/]}" 2>/dev/null &

    "${pw_yad}" --title "${translations[ABOUT US]}" --key="${KEY_CREDITS}" --window-icon="$PW_GUI_ICON_PATH/portproton.svg" \
    --notebook --no-buttons  --tab-pos=bottom --expand --width=750 --height=400 \
    --tab="${translations[ABOUT PORTPROTON]}" --tab="${translations[AUTORS]}" --tab="${translations[LICENSE]}" \
    --tab="${translations[SPONSORS]}" --tab="${translations[JOIN]}" --tab="${translations[THIRD PARTY LIBRARIES]}"

    restart_pp
}
