summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eclass/desktop.eclass395
-rw-r--r--eclass/eutils.eclass401
2 files changed, 404 insertions, 392 deletions
diff --git a/eclass/desktop.eclass b/eclass/desktop.eclass
new file mode 100644
index 000000000000..d65b0d0bf074
--- /dev/null
+++ b/eclass/desktop.eclass
@@ -0,0 +1,395 @@
+# Copyright 1999-2017 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: desktop.eclass
+# @MAINTAINER:
+# base-system@gentoo.org
+# @BLURB: support for desktop files, menus, and icons
+
+if [[ -z ${_DESKTOP_ECLASS} ]]; then
+_DESKTOP_ECLASS=1
+
+# @FUNCTION: make_desktop_entry
+# @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
+# @DESCRIPTION:
+# Make a .desktop file.
+#
+# @CODE
+# binary: what command does the app run with ?
+# name: the name that will show up in the menu
+# icon: the icon to use in the menu entry
+# this can be relative (to /usr/share/pixmaps) or
+# a full path to an icon
+# type: what kind of application is this?
+# for categories:
+# https://specifications.freedesktop.org/menu-spec/latest/apa.html
+# if unset, function tries to guess from package's category
+# fields: extra fields to append to the desktop file; a printf string
+# @CODE
+make_desktop_entry() {
+ [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
+
+ local exec=${1}
+ local name=${2:-${PN}}
+ local icon=${3:-${PN}}
+ local type=${4}
+ local fields=${5}
+
+ if [[ -z ${type} ]] ; then
+ local catmaj=${CATEGORY%%-*}
+ local catmin=${CATEGORY##*-}
+ case ${catmaj} in
+ app)
+ case ${catmin} in
+ accessibility) type="Utility;Accessibility";;
+ admin) type=System;;
+ antivirus) type=System;;
+ arch) type="Utility;Archiving";;
+ backup) type="Utility;Archiving";;
+ cdr) type="AudioVideo;DiscBurning";;
+ dicts) type="Office;Dictionary";;
+ doc) type=Documentation;;
+ editors) type="Utility;TextEditor";;
+ emacs) type="Development;TextEditor";;
+ emulation) type="System;Emulator";;
+ laptop) type="Settings;HardwareSettings";;
+ office) type=Office;;
+ pda) type="Office;PDA";;
+ vim) type="Development;TextEditor";;
+ xemacs) type="Development;TextEditor";;
+ esac
+ ;;
+
+ dev)
+ type="Development"
+ ;;
+
+ games)
+ case ${catmin} in
+ action|fps) type=ActionGame;;
+ arcade) type=ArcadeGame;;
+ board) type=BoardGame;;
+ emulation) type=Emulator;;
+ kids) type=KidsGame;;
+ puzzle) type=LogicGame;;
+ roguelike) type=RolePlaying;;
+ rpg) type=RolePlaying;;
+ simulation) type=Simulation;;
+ sports) type=SportsGame;;
+ strategy) type=StrategyGame;;
+ esac
+ type="Game;${type}"
+ ;;
+
+ gnome)
+ type="Gnome;GTK"
+ ;;
+
+ kde)
+ type="KDE;Qt"
+ ;;
+
+ mail)
+ type="Network;Email"
+ ;;
+
+ media)
+ case ${catmin} in
+ gfx)
+ type=Graphics
+ ;;
+ *)
+ case ${catmin} in
+ radio) type=Tuner;;
+ sound) type=Audio;;
+ tv) type=TV;;
+ video) type=Video;;
+ esac
+ type="AudioVideo;${type}"
+ ;;
+ esac
+ ;;
+
+ net)
+ case ${catmin} in
+ dialup) type=Dialup;;
+ ftp) type=FileTransfer;;
+ im) type=InstantMessaging;;
+ irc) type=IRCClient;;
+ mail) type=Email;;
+ news) type=News;;
+ nntp) type=News;;
+ p2p) type=FileTransfer;;
+ voip) type=Telephony;;
+ esac
+ type="Network;${type}"
+ ;;
+
+ sci)
+ case ${catmin} in
+ astro*) type=Astronomy;;
+ bio*) type=Biology;;
+ calc*) type=Calculator;;
+ chem*) type=Chemistry;;
+ elec*) type=Electronics;;
+ geo*) type=Geology;;
+ math*) type=Math;;
+ physics) type=Physics;;
+ visual*) type=DataVisualization;;
+ esac
+ type="Education;Science;${type}"
+ ;;
+
+ sys)
+ type="System"
+ ;;
+
+ www)
+ case ${catmin} in
+ client) type=WebBrowser;;
+ esac
+ type="Network;${type}"
+ ;;
+
+ *)
+ type=
+ ;;
+ esac
+ fi
+ local slot=${SLOT%/*}
+ if [[ ${slot} == "0" ]] ; then
+ local desktop_name="${PN}"
+ else
+ local desktop_name="${PN}-${slot}"
+ fi
+ local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
+ #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
+
+ # Don't append another ";" when a valid category value is provided.
+ type=${type%;}${type:+;}
+
+ if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
+ ewarn "As described in the Icon Theme Specification, icon file extensions are not"
+ ewarn "allowed in .desktop files if the value is not an absolute path."
+ icon=${icon%.*}
+ fi
+
+ cat <<-EOF > "${desktop}"
+ [Desktop Entry]
+ Name=${name}
+ Type=Application
+ Comment=${DESCRIPTION}
+ Exec=${exec}
+ TryExec=${exec%% *}
+ Icon=${icon}
+ Categories=${type}
+ EOF
+
+ if [[ ${fields:-=} != *=* ]] ; then
+ # 5th arg used to be value to Path=
+ ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
+ fields="Path=${fields}"
+ fi
+ [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
+
+ (
+ # wrap the env here so that the 'insinto' call
+ # doesn't corrupt the env of the caller
+ insinto /usr/share/applications
+ doins "${desktop}"
+ ) || die "installing desktop file failed"
+}
+
+# @FUNCTION: make_session_desktop
+# @USAGE: <title> <command> [command args...]
+# @DESCRIPTION:
+# Make a GDM/KDM Session file. The title is the file to execute to start the
+# Window Manager. The command is the name of the Window Manager.
+#
+# You can set the name of the file via the ${wm} variable.
+make_session_desktop() {
+ [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
+ [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
+
+ local title=$1
+ local command=$2
+ local desktop=${T}/${wm:-${PN}}.desktop
+ shift 2
+
+ cat <<-EOF > "${desktop}"
+ [Desktop Entry]
+ Name=${title}
+ Comment=This session logs you into ${title}
+ Exec=${command} $*
+ TryExec=${command}
+ Type=XSession
+ EOF
+
+ (
+ # wrap the env here so that the 'insinto' call
+ # doesn't corrupt the env of the caller
+ insinto /usr/share/xsessions
+ doins "${desktop}"
+ )
+}
+
+# @FUNCTION: domenu
+# @USAGE: <menus>
+# @DESCRIPTION:
+# Install the list of .desktop menu files into the appropriate directory
+# (/usr/share/applications).
+domenu() {
+ (
+ # wrap the env here so that the 'insinto' call
+ # doesn't corrupt the env of the caller
+ local i j ret=0
+ insinto /usr/share/applications
+ for i in "$@" ; do
+ if [[ -f ${i} ]] ; then
+ doins "${i}"
+ ((ret+=$?))
+ elif [[ -d ${i} ]] ; then
+ for j in "${i}"/*.desktop ; do
+ doins "${j}"
+ ((ret+=$?))
+ done
+ else
+ ((++ret))
+ fi
+ done
+ exit ${ret}
+ )
+}
+
+# @FUNCTION: newmenu
+# @USAGE: <menu> <newname>
+# @DESCRIPTION:
+# Like all other new* functions, install the specified menu as newname.
+newmenu() {
+ (
+ # wrap the env here so that the 'insinto' call
+ # doesn't corrupt the env of the caller
+ insinto /usr/share/applications
+ newins "$@"
+ )
+}
+
+# @FUNCTION: _iconins
+# @INTERNAL
+# @DESCRIPTION:
+# function for use in doicon and newicon
+_iconins() {
+ (
+ # wrap the env here so that the 'insinto' call
+ # doesn't corrupt the env of the caller
+ local funcname=$1; shift
+ local size dir
+ local context=apps
+ local theme=hicolor
+
+ while [[ $# -gt 0 ]] ; do
+ case $1 in
+ -s|--size)
+ if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
+ size=${2%%x*}
+ else
+ size=${2}
+ fi
+ case ${size} in
+ 16|22|24|32|36|48|64|72|96|128|192|256|512)
+ size=${size}x${size};;
+ scalable)
+ ;;
+ *)
+ eerror "${size} is an unsupported icon size!"
+ exit 1;;
+ esac
+ shift 2;;
+ -t|--theme)
+ theme=${2}
+ shift 2;;
+ -c|--context)
+ context=${2}
+ shift 2;;
+ *)
+ if [[ -z ${size} ]] ; then
+ insinto /usr/share/pixmaps
+ else
+ insinto /usr/share/icons/${theme}/${size}/${context}
+ fi
+
+ if [[ ${funcname} == doicon ]] ; then
+ if [[ -f $1 ]] ; then
+ doins "${1}"
+ elif [[ -d $1 ]] ; then
+ shopt -s nullglob
+ doins "${1}"/*.{png,svg}
+ shopt -u nullglob
+ else
+ eerror "${1} is not a valid file/directory!"
+ exit 1
+ fi
+ else
+ break
+ fi
+ shift 1;;
+ esac
+ done
+ if [[ ${funcname} == newicon ]] ; then
+ newins "$@"
+ fi
+ ) || die
+}
+
+# @FUNCTION: doicon
+# @USAGE: [options] <icons>
+# @DESCRIPTION:
+# Install icon into the icon directory /usr/share/icons or into
+# /usr/share/pixmaps if "--size" is not set.
+# This is useful in conjunction with creating desktop/menu files.
+#
+# @CODE
+# options:
+# -s, --size
+# !!! must specify to install into /usr/share/icons/... !!!
+# size of the icon, like 48 or 48x48
+# supported icon sizes are:
+# 16 22 24 32 36 48 64 72 96 128 192 256 512 scalable
+# -c, --context
+# defaults to "apps"
+# -t, --theme
+# defaults to "hicolor"
+#
+# icons: list of icons
+#
+# example 1: doicon foobar.png fuqbar.svg suckbar.png
+# results in: insinto /usr/share/pixmaps
+# doins foobar.png fuqbar.svg suckbar.png
+#
+# example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
+# results in: insinto /usr/share/icons/hicolor/48x48/apps
+# doins foobar.png fuqbar.png blobbar.png
+# @CODE
+doicon() {
+ _iconins ${FUNCNAME} "$@"
+}
+
+# @FUNCTION: newicon
+# @USAGE: [options] <icon> <newname>
+# @DESCRIPTION:
+# Like doicon, install the specified icon as newname.
+#
+# @CODE
+# example 1: newicon foobar.png NEWNAME.png
+# results in: insinto /usr/share/pixmaps
+# newins foobar.png NEWNAME.png
+#
+# example 2: newicon -s 48 foobar.png NEWNAME.png
+# results in: insinto /usr/share/icons/hicolor/48x48/apps
+# newins foobar.png NEWNAME.png
+# @CODE
+newicon() {
+ _iconins ${FUNCNAME} "$@"
+}
+
+fi
diff --git a/eclass/eutils.eclass b/eclass/eutils.eclass
index 972a2138aad7..7d4193e76b51 100644
--- a/eclass/eutils.eclass
+++ b/eclass/eutils.eclass
@@ -20,7 +20,7 @@ _EUTILS_ECLASS=1
# implicitly inherited (now split) eclasses
case ${EAPI:-0} in
0|1|2|3|4|5|6)
- inherit epatch estack ltprune multilib toolchain-funcs
+ inherit desktop epatch estack ltprune multilib toolchain-funcs
;;
esac
@@ -115,397 +115,6 @@ edos2unix() {
sed -i 's/\r$//' -- "$@" || die
}
-# @FUNCTION: make_desktop_entry
-# @USAGE: make_desktop_entry(<command>, [name], [icon], [type], [fields])
-# @DESCRIPTION:
-# Make a .desktop file.
-#
-# @CODE
-# binary: what command does the app run with ?
-# name: the name that will show up in the menu
-# icon: the icon to use in the menu entry
-# this can be relative (to /usr/share/pixmaps) or
-# a full path to an icon
-# type: what kind of application is this?
-# for categories:
-# https://specifications.freedesktop.org/menu-spec/latest/apa.html
-# if unset, function tries to guess from package's category
-# fields: extra fields to append to the desktop file; a printf string
-# @CODE
-make_desktop_entry() {
- [[ -z $1 ]] && die "make_desktop_entry: You must specify the executable"
-
- local exec=${1}
- local name=${2:-${PN}}
- local icon=${3:-${PN}}
- local type=${4}
- local fields=${5}
-
- if [[ -z ${type} ]] ; then
- local catmaj=${CATEGORY%%-*}
- local catmin=${CATEGORY##*-}
- case ${catmaj} in
- app)
- case ${catmin} in
- accessibility) type="Utility;Accessibility";;
- admin) type=System;;
- antivirus) type=System;;
- arch) type="Utility;Archiving";;
- backup) type="Utility;Archiving";;
- cdr) type="AudioVideo;DiscBurning";;
- dicts) type="Office;Dictionary";;
- doc) type=Documentation;;
- editors) type="Utility;TextEditor";;
- emacs) type="Development;TextEditor";;
- emulation) type="System;Emulator";;
- laptop) type="Settings;HardwareSettings";;
- office) type=Office;;
- pda) type="Office;PDA";;
- vim) type="Development;TextEditor";;
- xemacs) type="Development;TextEditor";;
- esac
- ;;
-
- dev)
- type="Development"
- ;;
-
- games)
- case ${catmin} in
- action|fps) type=ActionGame;;
- arcade) type=ArcadeGame;;
- board) type=BoardGame;;
- emulation) type=Emulator;;
- kids) type=KidsGame;;
- puzzle) type=LogicGame;;
- roguelike) type=RolePlaying;;
- rpg) type=RolePlaying;;
- simulation) type=Simulation;;
- sports) type=SportsGame;;
- strategy) type=StrategyGame;;
- esac
- type="Game;${type}"
- ;;
-
- gnome)
- type="Gnome;GTK"
- ;;
-
- kde)
- type="KDE;Qt"
- ;;
-
- mail)
- type="Network;Email"
- ;;
-
- media)
- case ${catmin} in
- gfx)
- type=Graphics
- ;;
- *)
- case ${catmin} in
- radio) type=Tuner;;
- sound) type=Audio;;
- tv) type=TV;;
- video) type=Video;;
- esac
- type="AudioVideo;${type}"
- ;;
- esac
- ;;
-
- net)
- case ${catmin} in
- dialup) type=Dialup;;
- ftp) type=FileTransfer;;
- im) type=InstantMessaging;;
- irc) type=IRCClient;;
- mail) type=Email;;
- news) type=News;;
- nntp) type=News;;
- p2p) type=FileTransfer;;
- voip) type=Telephony;;
- esac
- type="Network;${type}"
- ;;
-
- sci)
- case ${catmin} in
- astro*) type=Astronomy;;
- bio*) type=Biology;;
- calc*) type=Calculator;;
- chem*) type=Chemistry;;
- elec*) type=Electronics;;
- geo*) type=Geology;;
- math*) type=Math;;
- physics) type=Physics;;
- visual*) type=DataVisualization;;
- esac
- type="Education;Science;${type}"
- ;;
-
- sys)
- type="System"
- ;;
-
- www)
- case ${catmin} in
- client) type=WebBrowser;;
- esac
- type="Network;${type}"
- ;;
-
- *)
- type=
- ;;
- esac
- fi
- local slot=${SLOT%/*}
- if [[ ${slot} == "0" ]] ; then
- local desktop_name="${PN}"
- else
- local desktop_name="${PN}-${slot}"
- fi
- local desktop="${T}/$(echo ${exec} | sed 's:[[:space:]/:]:_:g')-${desktop_name}.desktop"
- #local desktop=${T}/${exec%% *:-${desktop_name}}.desktop
-
- # Don't append another ";" when a valid category value is provided.
- type=${type%;}${type:+;}
-
- if [[ -n ${icon} && ${icon} != /* ]] && [[ ${icon} == *.xpm || ${icon} == *.png || ${icon} == *.svg ]]; then
- ewarn "As described in the Icon Theme Specification, icon file extensions are not"
- ewarn "allowed in .desktop files if the value is not an absolute path."
- icon=${icon%.*}
- fi
-
- cat <<-EOF > "${desktop}"
- [Desktop Entry]
- Name=${name}
- Type=Application
- Comment=${DESCRIPTION}
- Exec=${exec}
- TryExec=${exec%% *}
- Icon=${icon}
- Categories=${type}
- EOF
-
- if [[ ${fields:-=} != *=* ]] ; then
- # 5th arg used to be value to Path=
- ewarn "make_desktop_entry: update your 5th arg to read Path=${fields}"
- fields="Path=${fields}"
- fi
- [[ -n ${fields} ]] && printf '%b\n' "${fields}" >> "${desktop}"
-
- (
- # wrap the env here so that the 'insinto' call
- # doesn't corrupt the env of the caller
- insinto /usr/share/applications
- doins "${desktop}"
- ) || die "installing desktop file failed"
-}
-
-# @FUNCTION: _eutils_eprefix_init
-# @INTERNAL
-# @DESCRIPTION:
-# Initialized prefix variables for EAPI<3.
-_eutils_eprefix_init() {
- has "${EAPI:-0}" 0 1 2 && : ${ED:=${D}} ${EPREFIX:=} ${EROOT:=${ROOT}}
-}
-
-# @FUNCTION: make_session_desktop
-# @USAGE: <title> <command> [command args...]
-# @DESCRIPTION:
-# Make a GDM/KDM Session file. The title is the file to execute to start the
-# Window Manager. The command is the name of the Window Manager.
-#
-# You can set the name of the file via the ${wm} variable.
-make_session_desktop() {
- [[ -z $1 ]] && eerror "$0: You must specify the title" && return 1
- [[ -z $2 ]] && eerror "$0: You must specify the command" && return 1
-
- local title=$1
- local command=$2
- local desktop=${T}/${wm:-${PN}}.desktop
- shift 2
-
- cat <<-EOF > "${desktop}"
- [Desktop Entry]
- Name=${title}
- Comment=This session logs you into ${title}
- Exec=${command} $*
- TryExec=${command}
- Type=XSession
- EOF
-
- (
- # wrap the env here so that the 'insinto' call
- # doesn't corrupt the env of the caller
- insinto /usr/share/xsessions
- doins "${desktop}"
- )
-}
-
-# @FUNCTION: domenu
-# @USAGE: <menus>
-# @DESCRIPTION:
-# Install the list of .desktop menu files into the appropriate directory
-# (/usr/share/applications).
-domenu() {
- (
- # wrap the env here so that the 'insinto' call
- # doesn't corrupt the env of the caller
- local i j ret=0
- insinto /usr/share/applications
- for i in "$@" ; do
- if [[ -f ${i} ]] ; then
- doins "${i}"
- ((ret+=$?))
- elif [[ -d ${i} ]] ; then
- for j in "${i}"/*.desktop ; do
- doins "${j}"
- ((ret+=$?))
- done
- else
- ((++ret))
- fi
- done
- exit ${ret}
- )
-}
-
-# @FUNCTION: newmenu
-# @USAGE: <menu> <newname>
-# @DESCRIPTION:
-# Like all other new* functions, install the specified menu as newname.
-newmenu() {
- (
- # wrap the env here so that the 'insinto' call
- # doesn't corrupt the env of the caller
- insinto /usr/share/applications
- newins "$@"
- )
-}
-
-# @FUNCTION: _iconins
-# @INTERNAL
-# @DESCRIPTION:
-# function for use in doicon and newicon
-_iconins() {
- (
- # wrap the env here so that the 'insinto' call
- # doesn't corrupt the env of the caller
- local funcname=$1; shift
- local size dir
- local context=apps
- local theme=hicolor
-
- while [[ $# -gt 0 ]] ; do
- case $1 in
- -s|--size)
- if [[ ${2%%x*}x${2%%x*} == "$2" ]] ; then
- size=${2%%x*}
- else
- size=${2}
- fi
- case ${size} in
- 16|22|24|32|36|48|64|72|96|128|192|256|512)
- size=${size}x${size};;
- scalable)
- ;;
- *)
- eerror "${size} is an unsupported icon size!"
- exit 1;;
- esac
- shift 2;;
- -t|--theme)
- theme=${2}
- shift 2;;
- -c|--context)
- context=${2}
- shift 2;;
- *)
- if [[ -z ${size} ]] ; then
- insinto /usr/share/pixmaps
- else
- insinto /usr/share/icons/${theme}/${size}/${context}
- fi
-
- if [[ ${funcname} == doicon ]] ; then
- if [[ -f $1 ]] ; then
- doins "${1}"
- elif [[ -d $1 ]] ; then
- shopt -s nullglob
- doins "${1}"/*.{png,svg}
- shopt -u nullglob
- else
- eerror "${1} is not a valid file/directory!"
- exit 1
- fi
- else
- break
- fi
- shift 1;;
- esac
- done
- if [[ ${funcname} == newicon ]] ; then
- newins "$@"
- fi
- ) || die
-}
-
-# @FUNCTION: doicon
-# @USAGE: [options] <icons>
-# @DESCRIPTION:
-# Install icon into the icon directory /usr/share/icons or into
-# /usr/share/pixmaps if "--size" is not set.
-# This is useful in conjunction with creating desktop/menu files.
-#
-# @CODE
-# options:
-# -s, --size
-# !!! must specify to install into /usr/share/icons/... !!!
-# size of the icon, like 48 or 48x48
-# supported icon sizes are:
-# 16 22 24 32 36 48 64 72 96 128 192 256 512 scalable
-# -c, --context
-# defaults to "apps"
-# -t, --theme
-# defaults to "hicolor"
-#
-# icons: list of icons
-#
-# example 1: doicon foobar.png fuqbar.svg suckbar.png
-# results in: insinto /usr/share/pixmaps
-# doins foobar.png fuqbar.svg suckbar.png
-#
-# example 2: doicon -s 48 foobar.png fuqbar.png blobbar.png
-# results in: insinto /usr/share/icons/hicolor/48x48/apps
-# doins foobar.png fuqbar.png blobbar.png
-# @CODE
-doicon() {
- _iconins ${FUNCNAME} "$@"
-}
-
-# @FUNCTION: newicon
-# @USAGE: [options] <icon> <newname>
-# @DESCRIPTION:
-# Like doicon, install the specified icon as newname.
-#
-# @CODE
-# example 1: newicon foobar.png NEWNAME.png
-# results in: insinto /usr/share/pixmaps
-# newins foobar.png NEWNAME.png
-#
-# example 2: newicon -s 48 foobar.png NEWNAME.png
-# results in: insinto /usr/share/icons/hicolor/48x48/apps
-# newins foobar.png NEWNAME.png
-# @CODE
-newicon() {
- _iconins ${FUNCNAME} "$@"
-}
-
# @FUNCTION: strip-linguas
# @USAGE: [<allow LINGUAS>|<-i|-u> <directories of .po files>]
# @DESCRIPTION:
@@ -555,6 +164,14 @@ strip-linguas() {
export LINGUAS=${newls:1}
}
+# @FUNCTION: _eutils_eprefix_init
+# @INTERNAL
+# @DESCRIPTION:
+# Initialized prefix variables for EAPI<3.
+_eutils_eprefix_init() {
+ has "${EAPI:-0}" 0 1 2 && : ${ED:=${D}} ${EPREFIX:=} ${EROOT:=${ROOT}}
+}
+
# @FUNCTION: preserve_old_lib
# @USAGE: <libs to preserve> [more libs]
# @DESCRIPTION: