mirror of
https://gitlab.com/mattia.basaglia/ASCII-Pony.git
synced 2024-11-25 05:17:59 +01:00
Replace tabs with spaces
This commit is contained in:
parent
ab5bc2aac0
commit
fe7cc34ff4
1 changed files with 206 additions and 206 deletions
384
systempony
384
systempony
|
@ -12,45 +12,45 @@ IP_INTERFACE="eth0"
|
||||||
|
|
||||||
function ponyget_Shell()
|
function ponyget_Shell()
|
||||||
{
|
{
|
||||||
echo "$SHELL"
|
echo "$SHELL"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_User()
|
function ponyget_User()
|
||||||
{
|
{
|
||||||
whoami
|
whoami
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Distro()
|
function ponyget_Distro()
|
||||||
{
|
{
|
||||||
lsb_release -isr | paste "-d " - -
|
lsb_release -isr | paste "-d " - -
|
||||||
}
|
}
|
||||||
|
|
||||||
function pccolor()
|
function pccolor()
|
||||||
{
|
{
|
||||||
local color="32";
|
local color="32";
|
||||||
if [ "$1" -gt 66 ]
|
if [ "$1" -gt 66 ]
|
||||||
then
|
then
|
||||||
color="31"
|
color="31"
|
||||||
elif [ "$1" -gt 33 ]
|
elif [ "$1" -gt 33 ]
|
||||||
then
|
then
|
||||||
color="33"
|
color="33"
|
||||||
fi
|
fi
|
||||||
echo -e "\x1b[$color;1m"
|
echo -e "\x1b[$color;1m"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_RAM()
|
function ponyget_RAM()
|
||||||
{
|
{
|
||||||
local ramtable=$(free -h | head -n -1)
|
local ramtable=$(free -h | head -n -1)
|
||||||
local used=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3)
|
local used=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3)
|
||||||
local total=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2)
|
local total=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2)
|
||||||
|
|
||||||
ramtable=$(free -m | head -n -1)
|
ramtable=$(free -m | head -n -1)
|
||||||
local used_M=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3)
|
local used_M=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3)
|
||||||
local total_M=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2)
|
local total_M=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2)
|
||||||
let percent="$used_M * 100 / $total_M"
|
let percent="$used_M * 100 / $total_M"
|
||||||
|
|
||||||
|
|
||||||
echo -e "$(pccolor $percent)$used\x1b[0m / $total"
|
echo -e "$(pccolor $percent)$used\x1b[0m / $total"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Swap()
|
function ponyget_Swap()
|
||||||
|
@ -70,17 +70,17 @@ function ponyget_Swap()
|
||||||
|
|
||||||
function ponyget_Kernel()
|
function ponyget_Kernel()
|
||||||
{
|
{
|
||||||
uname -r -m
|
uname -r -m
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Hostname()
|
function ponyget_Hostname()
|
||||||
{
|
{
|
||||||
hostname
|
hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_CPU()
|
function ponyget_CPU()
|
||||||
{
|
{
|
||||||
cat /proc/cpuinfo | grep "model name" | head -n 1 | sed -r "s/model name\s: //"
|
cat /proc/cpuinfo | grep "model name" | head -n 1 | sed -r "s/model name\s: //"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_CPU_Usage()
|
function ponyget_CPU_Usage()
|
||||||
|
@ -90,8 +90,8 @@ function ponyget_CPU_Usage()
|
||||||
|
|
||||||
function ponyget_Uptime()
|
function ponyget_Uptime()
|
||||||
{
|
{
|
||||||
uptime | grep -oE "up.*user" | \
|
uptime | grep -oE "up.*user" | \
|
||||||
sed -r -e "s/up\s*(.+),\s*[0-9]+\s*user/\1/" -e "s/\s+/ /g"
|
sed -r -e "s/up\s*(.+),\s*[0-9]+\s*user/\1/" -e "s/\s+/ /g"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Load()
|
function ponyget_Load()
|
||||||
|
@ -101,40 +101,40 @@ function ponyget_Load()
|
||||||
|
|
||||||
function ponyget_Packages()
|
function ponyget_Packages()
|
||||||
{
|
{
|
||||||
if which dpkg &>/dev/null
|
if which dpkg &>/dev/null
|
||||||
then
|
then
|
||||||
dpkg --get-selections | grep -v deinstall | wc -l
|
dpkg --get-selections | grep -v deinstall | wc -l
|
||||||
elif which rpm &>/dev/null
|
elif which rpm &>/dev/null
|
||||||
then
|
then
|
||||||
rpm -qa | wc -l
|
rpm -qa | wc -l
|
||||||
elif which pacman &>/dev/null
|
elif which pacman &>/dev/null
|
||||||
then
|
then
|
||||||
pacman -Q | wc -l
|
pacman -Q | wc -l
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Disk()
|
function ponyget_Disk()
|
||||||
{
|
{
|
||||||
local dfoption=$FSTYPE
|
local dfoption=$FSTYPE
|
||||||
[ "$dfoption" ] && dfoption="-t $FSTYPE"
|
[ "$dfoption" ] && dfoption="-t $FSTYPE"
|
||||||
local diskusage=$(df -lh $dfoption --total | tail -n 1 | sed -r "s/ +/\t/g" )
|
local diskusage=$(df -lh $dfoption --total | tail -n 1 | sed -r "s/ +/\t/g" )
|
||||||
local used=$(echo "$diskusage" | cut -f 3)
|
local used=$(echo "$diskusage" | cut -f 3)
|
||||||
local total=$(echo "$diskusage" | cut -f 2)
|
local total=$(echo "$diskusage" | cut -f 2)
|
||||||
local percent=$(echo "$diskusage" | cut -f 5 | sed s/%// )
|
local percent=$(echo "$diskusage" | cut -f 5 | sed s/%// )
|
||||||
|
|
||||||
echo -e "$(pccolor $percent)$used\x1b[0m / $total"
|
echo -e "$(pccolor $percent)$used\x1b[0m / $total"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_Containers()
|
function ponyget_Containers()
|
||||||
{
|
{
|
||||||
local active="$(lxc-ls --active | wc -l)"
|
local active="$(lxc-ls --active | wc -l)"
|
||||||
local total="$(lxc-ls | wc -l)"
|
local total="$(lxc-ls | wc -l)"
|
||||||
local color=32
|
local color=32
|
||||||
if [ "$active" -lt "$total" ]
|
if [ "$active" -lt "$total" ]
|
||||||
then
|
then
|
||||||
color=31
|
color=31
|
||||||
fi
|
fi
|
||||||
echo -e "\x1b[$color;1m$active\x1b[0m / $total active"
|
echo -e "\x1b[$color;1m$active\x1b[0m / $total active"
|
||||||
}
|
}
|
||||||
|
|
||||||
function ponyget_IP()
|
function ponyget_IP()
|
||||||
|
@ -150,143 +150,143 @@ function ponyget_IPv6()
|
||||||
|
|
||||||
function bold()
|
function bold()
|
||||||
{
|
{
|
||||||
echo -en "\x1b[1m${*}\x1b[22m"
|
echo -en "\x1b[1m${*}\x1b[22m"
|
||||||
}
|
}
|
||||||
|
|
||||||
function underline()
|
function underline()
|
||||||
{
|
{
|
||||||
echo -en "\x1b[4m${*}\x1b[24m"
|
echo -en "\x1b[4m${*}\x1b[24m"
|
||||||
}
|
}
|
||||||
|
|
||||||
function title()
|
function title()
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
bold ${*}
|
bold ${*}
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
function help()
|
function help()
|
||||||
{
|
{
|
||||||
title NAME
|
title NAME
|
||||||
echo -e "\t$(bold $0) - show a pony and some system information"
|
echo -e "\t$(bold $0) - show a pony and some system information"
|
||||||
|
|
||||||
title SYNOPSIS
|
title SYNOPSIS
|
||||||
echo -e "\t$(bold $0) [$(bold --pony) $(underline pony)|$(bold -p)$(underline pony)] [$(bold --info) $(underline id)|$(bold -i)$(underline id)...]"
|
echo -e "\t$(bold $0) [$(bold --pony) $(underline pony)|$(bold -p)$(underline pony)] [$(bold --info) $(underline id)|$(bold -i)$(underline id)...]"
|
||||||
echo -e "\t$(bold $0) $(bold help)|$(bold --help)|$(bold -h)"
|
echo -e "\t$(bold $0) $(bold help)|$(bold --help)|$(bold -h)"
|
||||||
|
|
||||||
title OPTIONS
|
title OPTIONS
|
||||||
echo -e "\t$(bold --pony) $(underline pony), $(bold -p)$(underline pony)"
|
echo -e "\t$(bold --pony) $(underline pony), $(bold -p)$(underline pony)"
|
||||||
echo -e "\t\tSelect a pony (default: $PONY)."
|
echo -e "\t\tSelect a pony (default: $PONY)."
|
||||||
echo
|
echo
|
||||||
echo -e "\t$(bold --info) $(underline id), $(bold -i)$(underline id)"
|
echo -e "\t$(bold --info) $(underline id), $(bold -i)$(underline id)"
|
||||||
echo -e "\t\tShow the given info (default: ${INFO[@]})."
|
echo -e "\t\tShow the given info (default: ${INFO[@]})."
|
||||||
echo -e "\t\tThis option supports multiples IDs separated by commas, spaces or colons."
|
echo -e "\t\tThis option supports multiples IDs separated by commas, spaces or colons."
|
||||||
echo -e "\t\tAvailable IDs:"
|
echo -e "\t\tAvailable IDs:"
|
||||||
declare -F | grep ponyget_ | sed "s/declare -f ponyget_/\t\t * /"
|
declare -F | grep ponyget_ | sed "s/declare -f ponyget_/\t\t * /"
|
||||||
echo
|
echo
|
||||||
echo -e "\t$(bold --list), $(bold --list-ponies)"
|
echo -e "\t$(bold --list), $(bold --list-ponies)"
|
||||||
echo -e "\t\tShows a list of possible values for $(bold --pony)."
|
echo -e "\t\tShows a list of possible values for $(bold --pony)."
|
||||||
|
|
||||||
title CONFIGURATION
|
title CONFIGURATION
|
||||||
echo -e "\tYou can override $(bold PONY) and $(bold INFO) in the config files."
|
echo -e "\tYou can override $(bold PONY) and $(bold INFO) in the config files."
|
||||||
echo -e "\tConfiguration files:"
|
echo -e "\tConfiguration files:"
|
||||||
echo -e "\t * $(underline PREFIX)$(bold /share/ascii-pony/systempony.conf) (system)"
|
echo -e "\t * $(underline PREFIX)$(bold /share/ascii-pony/systempony.conf) (system)"
|
||||||
echo -e "\t * $(bold ~/.systempony) (user)"
|
echo -e "\t * $(bold ~/.systempony) (user)"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
function list_ponies()
|
function list_ponies()
|
||||||
{
|
{
|
||||||
ponydir=$(get_data_file "rendered/ansi/")
|
ponydir=$(get_data_file "rendered/ansi/")
|
||||||
echo random
|
echo random
|
||||||
find "$ponydir" -name '*.ansi' -exec basename {} .ansi \; | sort
|
find "$ponydir" -name '*.ansi' -exec basename {} .ansi \; | sort
|
||||||
}
|
}
|
||||||
|
|
||||||
function select_info()
|
function select_info()
|
||||||
{
|
{
|
||||||
INFO=($(echo "${*}" | column -t -s:,))
|
INFO=($(echo "${*}" | column -t -s:,))
|
||||||
}
|
}
|
||||||
|
|
||||||
SELFDIR=$(dirname $(readlink -se "${BASH_SOURCE[0]}"))
|
SELFDIR=$(dirname $(readlink -se "${BASH_SOURCE[0]}"))
|
||||||
function get_data_file()
|
function get_data_file()
|
||||||
{
|
{
|
||||||
if [ -e "$SELFDIR/$1" ]
|
if [ -e "$SELFDIR/$1" ]
|
||||||
then
|
then
|
||||||
# Not installed
|
# Not installed
|
||||||
echo "$SELFDIR/$1"
|
echo "$SELFDIR/$1"
|
||||||
elif [ -e "$SELFDIR/../share/ascii-pony/$1" ]
|
elif [ -e "$SELFDIR/../share/ascii-pony/$1" ]
|
||||||
then
|
then
|
||||||
# Installed with PREFIX=$SELFDIR/..
|
# Installed with PREFIX=$SELFDIR/..
|
||||||
echo "$SELFDIR/../share/ascii-pony/$1"
|
echo "$SELFDIR/../share/ascii-pony/$1"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns the number of displayed characters, ignoring color codes
|
# Returns the number of displayed characters, ignoring color codes
|
||||||
function strlen_color()
|
function strlen_color()
|
||||||
{
|
{
|
||||||
echo -n "$1" | sed -r 's/\x1b\[[0-9;]+m//g' | wc -c
|
echo -n "$1" | sed -r 's/\x1b\[[0-9;]+m//g' | wc -c
|
||||||
}
|
}
|
||||||
|
|
||||||
# Truncates a string
|
# Truncates a string
|
||||||
function truncate_color()
|
function truncate_color()
|
||||||
{
|
{
|
||||||
local length="$(strlen_color "$1")"
|
local length="$(strlen_color "$1")"
|
||||||
local target="$2"
|
local target="$2"
|
||||||
if [ "$length" -gt "$target" ]
|
if [ "$length" -gt "$target" ]
|
||||||
then
|
then
|
||||||
let cut="$target-$length"
|
let cut="$target-$length"
|
||||||
echo -n "$1" | head -c $cut
|
echo -n "$1" | head -c $cut
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
echo "$1"
|
echo "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read global config
|
# Read global config
|
||||||
globalconfig=$(get_data_file systempony.conf)
|
globalconfig=$(get_data_file systempony.conf)
|
||||||
if [ -r "$globalconfig" ]
|
if [ -r "$globalconfig" ]
|
||||||
then
|
then
|
||||||
source "$globalconfig"
|
source "$globalconfig"
|
||||||
fi
|
fi
|
||||||
# Read user config
|
# Read user config
|
||||||
if [ -r ~/.systempony ]
|
if [ -r ~/.systempony ]
|
||||||
then
|
then
|
||||||
source ~/.systempony
|
source ~/.systempony
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Read parameters
|
# Read parameters
|
||||||
while [ "$1" ]
|
while [ "$1" ]
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
--help|-h|help)
|
--help|-h|help)
|
||||||
help
|
help
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
--list|--list-ponies)
|
--list|--list-ponies)
|
||||||
list_ponies
|
list_ponies
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
--pony|-p)
|
--pony|-p)
|
||||||
shift
|
shift
|
||||||
PONY="$1"
|
PONY="$1"
|
||||||
;;
|
;;
|
||||||
-p=*|--pony=*)
|
-p=*|--pony=*)
|
||||||
PONY="$(echo "$1" | sed -r "s/^(-p|--pony)=//")"
|
PONY="$(echo "$1" | sed -r "s/^(-p|--pony)=//")"
|
||||||
;;
|
;;
|
||||||
--info|-i)
|
--info|-i)
|
||||||
infostring=""
|
infostring=""
|
||||||
while [ "$2" ] && ! echo "$2" | grep -q -e "-"
|
while [ "$2" ] && ! echo "$2" | grep -q -e "-"
|
||||||
do
|
do
|
||||||
infostring="$infostring $2"
|
infostring="$infostring $2"
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
select_info "$infostring"
|
select_info "$infostring"
|
||||||
;;
|
;;
|
||||||
-i=*|--info=*)
|
-i=*|--info=*)
|
||||||
select_info "$(echo "$1" | sed -r "s/^(-i|--info)=//")"
|
select_info "$(echo "$1" | sed -r "s/^(-i|--info)=//")"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
# Evaluate info
|
# Evaluate info
|
||||||
|
@ -295,32 +295,32 @@ let info_key_max_length=0
|
||||||
let info_val_max_length=0
|
let info_val_max_length=0
|
||||||
function addinfo()
|
function addinfo()
|
||||||
{
|
{
|
||||||
info_values+=("${2}")
|
info_values+=("${2}")
|
||||||
local key_length=$(echo "$1" | wc -c)
|
local key_length=$(echo "$1" | wc -c)
|
||||||
local val_length=$(echo "${2}" | wc -c)
|
local val_length=$(echo "${2}" | wc -c)
|
||||||
[ $key_length -gt $info_key_max_length ] && info_key_max_length=$key_length;
|
[ $key_length -gt $info_key_max_length ] && info_key_max_length=$key_length;
|
||||||
[ $val_length -gt $info_val_max_length ] && info_val_max_length=$val_length;
|
[ $val_length -gt $info_val_max_length ] && info_val_max_length=$val_length;
|
||||||
}
|
}
|
||||||
for info in ${INFO[*]}
|
for info in ${INFO[*]}
|
||||||
do
|
do
|
||||||
if [ "$(type -t ponyget_${info})" = "function" ]
|
if [ "$(type -t ponyget_${info})" = "function" ]
|
||||||
then
|
then
|
||||||
addinfo $info "$(ponyget_${info})"
|
addinfo $info "$(ponyget_${info})"
|
||||||
else
|
else
|
||||||
addinfo $info "unsupported"
|
addinfo $info "unsupported"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$PONY" = nopony ]
|
if [ "$PONY" = nopony ]
|
||||||
then
|
then
|
||||||
ponyfile=/dev/null
|
ponyfile=/dev/null
|
||||||
else
|
else
|
||||||
ponydir=$(get_data_file "rendered/ansi/")
|
ponydir=$(get_data_file "rendered/ansi/")
|
||||||
ponyfile="$ponydir/$PONY.ansi"
|
ponyfile="$ponydir/$PONY.ansi"
|
||||||
if [ -n "$ponydir" -a '(' \! -f "$ponyfile" -o "$PONY" = random ')' ]
|
if [ -n "$ponydir" -a '(' \! -f "$ponyfile" -o "$PONY" = random ')' ]
|
||||||
then
|
then
|
||||||
ponyfile="$(find "$ponydir" -name '*.ansi' | shuf | head -n 1)"
|
ponyfile="$(find "$ponydir" -name '*.ansi' | shuf | head -n 1)"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,53 +353,53 @@ info_firsty[trixie]=16
|
||||||
|
|
||||||
if [ -f "$ponyfile" ]
|
if [ -f "$ponyfile" ]
|
||||||
then
|
then
|
||||||
lines=$(cat "$ponyfile" | wc -l) # cat to avoid printing file name
|
lines=$(cat "$ponyfile" | wc -l) # cat to avoid printing file name
|
||||||
let info_index=0
|
let info_index=0
|
||||||
COLUMNS=$(tput cols || echo 1024)
|
COLUMNS=$(tput cols || echo 1024)
|
||||||
|
|
||||||
|
|
||||||
if [ "${info_firstx[$PONY]}" ]
|
if [ "${info_firstx[$PONY]}" ]
|
||||||
then
|
then
|
||||||
info_x=${info_firstx[$PONY]}
|
info_x=${info_firstx[$PONY]}
|
||||||
else
|
else
|
||||||
info_x=80
|
info_x=80
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${info_firsty[$PONY]}" ]
|
if [ "${info_firsty[$PONY]}" ]
|
||||||
then
|
then
|
||||||
start_line=${info_firsty[$PONY]}
|
start_line=${info_firsty[$PONY]}
|
||||||
else
|
else
|
||||||
let start_line=($lines-${#INFO[@]})/2
|
let start_line=($lines-${#INFO[@]})/2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let current_line=1
|
let current_line=1
|
||||||
while IFS= read -r line
|
while IFS= read -r line
|
||||||
do
|
do
|
||||||
if [ $info_index -lt ${#INFO[@]} -a $current_line -ge $start_line ]
|
if [ $info_index -lt ${#INFO[@]} -a $current_line -ge $start_line ]
|
||||||
then
|
then
|
||||||
let msgsize="$COLUMNS - $info_x - $info_key_max_length - 4"
|
let msgsize="$COLUMNS - $info_x - $info_key_max_length - 4"
|
||||||
line="$(truncate_color "$line" $info_x)"
|
line="$(truncate_color "$line" $info_x)"
|
||||||
printf "%s \x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s %s\n" \
|
printf "%s \x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s %s\n" \
|
||||||
"$line$backspaces" \
|
"$line$backspaces" \
|
||||||
"${INFO[$info_index]}" \
|
"${INFO[$info_index]}" \
|
||||||
"$(truncate_color "${info_values[$info_index]}" $msgsize)"
|
"$(truncate_color "${info_values[$info_index]}" $msgsize)"
|
||||||
let info_index++
|
let info_index++
|
||||||
else
|
else
|
||||||
echo -n "$line"
|
echo -n "$line"
|
||||||
echo -e "\x1b[0m"
|
echo -e "\x1b[0m"
|
||||||
fi
|
fi
|
||||||
let current_line++
|
let current_line++
|
||||||
done < "$ponyfile"
|
done < "$ponyfile"
|
||||||
else
|
else
|
||||||
let info_index=0
|
let info_index=0
|
||||||
while [ $info_index -lt ${#INFO[@]} ]
|
while [ $info_index -lt ${#INFO[@]} ]
|
||||||
do
|
do
|
||||||
printf "\x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s\n" \
|
printf "\x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s\n" \
|
||||||
"${INFO[$info_index]}" \
|
"${INFO[$info_index]}" \
|
||||||
"${info_values[$info_index]}"
|
"${info_values[$info_index]}"
|
||||||
let info_index++
|
let info_index++
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue