From ff945bb6ce31c955228ef0a2c38fb365bc3d38b7 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 14 Dec 2024 15:37:28 +0100 Subject: [PATCH 001/122] Date and Time enhancements - Support Precision Time Protocol (PTP) - time accuracy in nanoseconds - PTP requires a local time server which supports the PTP protocol - Show only the applicable fields for the selected time sync value (animated) - Add 'hints' to help the user in configuration - Do not restart time service when only date/time format is updated Note for Tom: to make PTP work the package "linuxptp-4.2-x86_64-1_BW.txz" needs to be installed with stock Unraid --- emhttp/plugins/dynamix/DateTime.page | 250 ++++++++++++++---- .../plugins/dynamix/include/DashboardApps.php | 58 ++-- .../plugins/dynamix/include/StartStopPTP.php | 4 + emhttp/plugins/dynamix/sheets/DateTime.css | 4 +- etc/rc.d/rc.M | 7 +- etc/rc.d/rc.library.source | 10 +- etc/rc.d/rc.ntpd | 43 +-- etc/rc.d/rc.ptpd | 130 +++++++++ 8 files changed, 416 insertions(+), 90 deletions(-) create mode 100644 emhttp/plugins/dynamix/include/StartStopPTP.php create mode 100644 etc/rc.d/rc.ptpd diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index 3c1c13f5a..212de12b3 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -4,8 +4,8 @@ Icon="icon-clock" Tag="clock-o" --- -
+ _(Current date and time)_: : _(Date format)_: : _(Time format)_: : _(Time zone)_: : :timezone_help: -_(Use NTP)_: -: + + + -:use_ntp_help: - +
_(NTP interval)_: -: _(Use DEFAULT setting when public NTP servers are defined)_ +: + _(Use DEFAULT setting when public NTP servers are defined)_ _(NTP server)_ 1: : - -:ntp_server1_help: + _(Input a NTP server name, NTP pool name or IP address)_ _(NTP server)_ 2: : -:ntp_server2_help: - _(NTP server)_ 3: : -:ntp_server3_help: - _(NTP server)_ 4: : -:ntp_server4_help: +
+
+_(PTP profile)_: +: PTPv2 (IEEE 1588) +_(PTP transport)_: +: + +_(PTP mode)_: +: + +
+_(PTP server)_ 1: +: + _(Input a IPv4 address)__(Input a IPv6 address)__(Input a MAC address)_ + +_(PTP server)_ 2: +: + +_(PTP server)_ 3: +: + +_(PTP server)_ 4: +: + +
+_(PTP interface)_: +: + +_(PTP clock)_: +: + +
+
_(New date and time)_: -: "> +: "> + _(Input the correct date and time manually)_ :current_time_help: +
  -: +:
diff --git a/emhttp/plugins/dynamix/include/DashboardApps.php b/emhttp/plugins/dynamix/include/DashboardApps.php index 871d29abb..d2ac16a03 100644 --- a/emhttp/plugins/dynamix/include/DashboardApps.php +++ b/emhttp/plugins/dynamix/include/DashboardApps.php @@ -1,6 +1,6 @@ 0) { $wsport = $lv->domain_get_ws_port($res); - $vmrcprotocol = $lv->domain_get_vmrc_protocol($res) ; + $vmrcprotocol = $lv->domain_get_vmrc_protocol($res); if ($vmrcprotocol == "vnc") $vmrcscale = "&resize=scale"; else $vmrcscale = ""; - $vmrcurl = autov('/plugins/dynamix.vm.manager/'.$vmrcprotocol.'.html',true).$vmrcscale.'&autoconnect=true&host=' . $_SERVER['HTTP_HOST'] ; - if ($vmrcprotocol == "spice") $vmrcurl .= '&vmname='. urlencode($vm) . '&port=/wsproxy/'.$vmrcport.'/' ; else $vmrcurl .= '&port=&path=/wsproxy/' . $wsport . '/'; + $vmrcurl = autov('/plugins/dynamix.vm.manager/'.$vmrcprotocol.'.html',true).$vmrcscale.'&autoconnect=true&host=' . $_SERVER['HTTP_HOST']; + if ($vmrcprotocol == "spice") $vmrcurl .= '&vmname='. urlencode($vm) . '&port=/wsproxy/'.$vmrcport.'/'; else $vmrcurl .= '&port=&path=/wsproxy/' . $wsport . '/'; } elseif ($vmrcport == -1 || $autoport) { - $vmrcprotocol = $lv->domain_get_vmrc_protocol($res) ; - if ($autoport == "yes") $auto = "auto" ; else $auto="manual" ; + $vmrcprotocol = $lv->domain_get_vmrc_protocol($res); + $auto = ($autoport == "yes") ? "auto" : "manual"; } elseif (!empty($arrConfig['gpu'])) { $arrValidGPUDevices = getValidGPUDevices(); foreach ($arrConfig['gpu'] as $arrGPU) { foreach ($arrValidGPUDevices as $arrDev) { if ($arrGPU['id'] == $arrDev['id']) { if (count(array_filter($arrValidGPUDevices, function($v) use ($arrDev) { return $v['name'] == $arrDev['name']; })) > 1) { - $vmrcprotocol = "VGA" ; + $vmrcprotocol = "VGA"; } else { - $vmrcprotocol = "VGA" ; + $vmrcprotocol = "VGA"; } } } } - } + } $template = $lv->_get_single_xpath_result($res, '//domain/metadata/*[local-name()=\'vmtemplate\']/@name'); if (empty($template)) $template = 'Custom'; $log = (is_file("/var/log/libvirt/qemu/$vm.log") ? "libvirt/qemu/$vm.log" : ''); - if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web" ; else $vmrcconsole = $domain_cfg["CONSOLE"] ; - if (!isset($domain_cfg["RDPOPT"])) $vmrcconsole .= ";no" ; else $vmrcconsole .= ";".$domain_cfg["RDPOPT"] ; + if (!isset($domain_cfg["CONSOLE"])) $vmrcconsole = "web"; else $vmrcconsole = $domain_cfg["CONSOLE"]; + if (!isset($domain_cfg["RDPOPT"])) $vmrcconsole .= ";no"; else $vmrcconsole .= ";".$domain_cfg["RDPOPT"]; $WebUI = html_entity_decode($arrConfig["template"]["webui"]); $menu = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log),addslashes($fstype), $vmrcconsole,false,addslashes(str_replace('"',"'",$WebUI))); $icon = $lv->domain_get_icon_url($res); @@ -153,7 +181,7 @@ if ($_POST['vms']) { #Build VM Usage array. $menuusage = sprintf("onclick=\"addVMContext('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')\"", addslashes($vm), addslashes($uuid), addslashes($template), $state, addslashes($vmrcurl), strtoupper($vmrcprotocol), addslashes($log),addslashes($fstype), $vmrcconsole,true,addslashes(str_replace('"',"'",$WebUI))); $vmusagehtml[] = "$image$vm
"._($status)."
"; - $vmusagehtml[] = "

"._("Loading")."...."; + $vmusagehtml[] = "

"._("Loading")."...."; $vmusagehtml[] = "
"._("Loading")."...."; $vmusagehtml[] = "
"._("Loading")."...."; $vmusagehtml[] = "
"._("Loading")."...."; diff --git a/emhttp/plugins/dynamix/include/StartStopPTP.php b/emhttp/plugins/dynamix/include/StartStopPTP.php new file mode 100644 index 000000000..553a8a0fe --- /dev/null +++ b/emhttp/plugins/dynamix/include/StartStopPTP.php @@ -0,0 +1,4 @@ + diff --git a/emhttp/plugins/dynamix/sheets/DateTime.css b/emhttp/plugins/dynamix/sheets/DateTime.css index b2eb5cbbe..b3012f111 100644 --- a/emhttp/plugins/dynamix/sheets/DateTime.css +++ b/emhttp/plugins/dynamix/sheets/DateTime.css @@ -1 +1,3 @@ -span.ntp{margin-left:40px} +div.extra,span.ipv4,span.ipv6,span.mac{display:none} +select,input[type=text]{margin-right:40px} +select[name=timeZone]{max-width:166px} diff --git a/etc/rc.d/rc.M b/etc/rc.d/rc.M index 2ae1f5dc8..632ca2e8a 100755 --- a/etc/rc.d/rc.M +++ b/etc/rc.d/rc.M @@ -11,7 +11,7 @@ # Heavily modified by Patrick Volkerding # # LimeTech - modified for Unraid OS -# Bergware - modified for Unraid OS, October 2023 +# Bergware - modified for Unraid OS, December 2024 # run & log functions . /etc/rc.d/rc.runlog @@ -108,6 +108,11 @@ fi # Mount any additional filesystem types that haven't already been mounted: mount -a -v 2>/dev/null | grep -v -e "already mounted" -e "ignored" | cut -f 1 -d : | tr -d ' ' | while read DEV; do mount | grep "$DEV "; done +# Start the Precision Time Protocol daemon: +if [[ -x /etc/rc.d/rc.ptpd ]]; then + /etc/rc.d/rc.ptpd start +fi + # Start the Network Time Protocol daemon: if [[ -x /etc/rc.d/rc.ntpd ]]; then /etc/rc.d/rc.ntpd start diff --git a/etc/rc.d/rc.library.source b/etc/rc.d/rc.library.source index a37043f06..3dc4bfdbf 100644 --- a/etc/rc.d/rc.library.source +++ b/etc/rc.d/rc.library.source @@ -4,12 +4,20 @@ # # Library used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces # -# Bergware - created for Unraid OS, December 2023 +# Bergware - created for Unraid OS, December 2024 WIREGUARD="/etc/wireguard" NETWORK_INI="/var/local/emhttp/network.ini" NETWORK_EXTRA="/boot/config/network-extra.cfg" +var(){ + if [[ $# -eq 3 ]]; then + [[ -r "$3" ]] && sed -n "/^\[$1\]\$/,/^\[/p" "$3" | grep -Pom1 "^$2=\"\K[^\"]+" + elif [[ $# -eq 2 ]]; then + [[ -r "$2" ]] && grep -Pom1 "^$1=\"\K[^\"]+" "$2" + fi +} + ipv(){ local t=${1//[^:]} [[ ${#t} -le 1 ]] && echo 4 || echo 6 diff --git a/etc/rc.d/rc.ntpd b/etc/rc.d/rc.ntpd index deedfedc9..532c4a033 100755 --- a/etc/rc.d/rc.ntpd +++ b/etc/rc.d/rc.ntpd @@ -5,15 +5,15 @@ # Start/stop/restart ntpd. # # LimeTech - modified to initialize ntp.conf file from config -# Bergware - modified for Unraid OS, October 2023 +# Bergware - modified for Unraid OS, December 2024 DAEMON="NTP server daemon" CALLER="ntp" NTPD="/usr/sbin/ntpd" OPTIONS="-g -u ntp:ntp" CONF="/etc/ntp.conf" +CFG="/boot/config/plugins/dynamix/dynamix.cfg" IDENT="/boot/config/ident.cfg" -CONFIG="/boot/config/plugins/dynamix/dynamix.cfg" # run & log functions . /etc/rc.d/rc.runlog @@ -39,24 +39,25 @@ ntpd_build(){ echo "interface listen $NET" >>$CONF done fi + NTP_POLL=$(var NTP POLL $CFG) # ntp poll interval may be adjusted to predefined values - if [[ -f $CONFIG ]]; then - NTP_POLL=$(grep -Po '^ntppoll="\K[^"]+' $CONFIG) - if [[ -n $NTP_POLL ]]; then - MINPOLL="minpoll $NTP_POLL" - MAXPOLL="maxpoll $NTP_POLL" - fi + if [[ -n $NTP_POLL ]]; then + MINPOLL="minpoll $NTP_POLL" + MAXPOLL="maxpoll $NTP_POLL" + fi + # allow ntp to use ptp as sync source + if [[ $(var PTP SYNC $CFG) != yes ]]; then + # add configured ntp servers or pools + for n in {1..4}; do + NTP="NTP_SERVER$n" + if [[ -n ${!NTP} ]]; then + # use either server or pool peers depending on remote ntp name + # pools use a round-robin mechanism to get a server out of the pool + [[ ${!NTP} =~ "pool" ]] && PEER=pool || PEER=server + echo "$PEER ${!NTP} iburst $MINPOLL $MAXPOLL" >>$CONF + fi + done fi - # add configured ntp servers or pools - for n in {1..4}; do - NTP="NTP_SERVER$n" - if [[ -n ${!NTP} ]]; then - # use either server or pool peers depending on remote ntp name - # pools use a round-robin mechanism to get a server out of the pool - [[ ${!NTP} =~ "pool" ]] && PEER=pool || PEER=server - echo "$PEER ${!NTP} iburst $MINPOLL $MAXPOLL" >>$CONF - fi - done } ntpd_start(){ @@ -64,7 +65,7 @@ ntpd_start(){ local REPLY # read Unraid settings [[ -r $IDENT ]] && . <(fromdos <$IDENT) - # if ntp not enabled, don't start ntp + # if time sync not enabled, don't start ntp if [[ $USE_NTP != yes ]]; then REPLY="Service not enabled" elif ntpd_running; then @@ -90,7 +91,7 @@ ntpd_stop(){ kill -HUP $(cat /var/run/ntpd.pid) rm -f /var/run/ntpd.pid else - killall --ns $$ -HUP -q ntpd + killall --ns $$ -HUP -q ntpd fi if ! ntpd_running; then REPLY="Stopped"; else REPLY="Failed"; fi fi @@ -107,7 +108,7 @@ ntpd_restart(){ } ntpd_reload(){ - killall --ns $$ -HUP -q ntpd + killall --ns $$ -HUP -q ntpd . <(fromdos <$IDENT) ntpd_build $NTPD $OPTIONS 2>/dev/null diff --git a/etc/rc.d/rc.ptpd b/etc/rc.d/rc.ptpd new file mode 100644 index 000000000..692d7529d --- /dev/null +++ b/etc/rc.d/rc.ptpd @@ -0,0 +1,130 @@ +#!/bin/bash +# +# script: rc.ptpd +# +# Start/stop/restart services ptp4l and phc2sys. +# +# Bergware - created for Unraid OS, December 2024 + +DAEMON="PTP server daemon" +CALLER="ptp" +PTPD="/usr/sbin/ptp4l" +PHC="/usr/sbin/phc2sys" +OPTIONS1="-s -l 5 -f /etc/ptp4l.conf" +OPTIONS2="-a -r -l 5" +CONF="/etc/ptp4l.conf" +CFG="/boot/config/plugins/dynamix/dynamix.cfg" +IDENT="/boot/config/ident.cfg" + +# run & log functions +. /etc/rc.d/rc.runlog + +# library functions +. /etc/rc.d/rc.library.source + +ptpd_running(){ + sleep 0.1 + [[ $(pgrep -cf $PTPD) -gt 0 ]] +} + +ptpd_build(){ + echo "[global]" >$CONF + TRANSPORT=$(var PTP TRANSPORT $CFG) + echo "network_transport $TRANSPORT" >>$CONF + echo "time_stamping $(var PTP CLOCK $CFG)" >>$CONF + [[ $(var PTP MODE $CFG) == unicast ]] && UNICAST=1 || UNICAST=0 + if [[ $UNICAST == 1 ]]; then + echo "unicast_req_duration 60" >>$CONF + echo "" >>$CONF + echo "[unicast_master_table]" >>$CONF + echo "table_id 1" >>$CONF + echo "logQueryInterval 1" >>$CONF + for n in {1..4}; do + PTP=$(var PTP "SERVER$n" $CFG) + [[ -n $PTP ]] && echo "$TRANSPORT $PTP" >>$CONF + done + fi + echo "" >>$CONF + echo "[$(var PTP PORT $CFG)]" >>$CONF + [[ $UNICAST == 1 ]] && echo "unicast_master_table 1" >>$CONF +} + +ptpd_start(){ + log "Starting $DAEMON..." + local REPLY + # read Unraid settings + [[ -r $IDENT ]] && . <(fromdos <$IDENT) + # if time sync not enabled, don't start ptp + if [[ $USE_NTP != yes ]]; then + REPLY="Service not enabled" + elif [[ $(var PTP SYNC $CFG) == yes || $FORCE == yes ]]; then + if ptpd_running; then + REPLY="Already started" + else + # generate our config file + ptpd_build + $PTPD $OPTIONS1 &>/dev/null & + if ptpd_running; then + $PHC $OPTIONS2 &>/dev/null & + REPLY="Started" + else + REPLY="Failed" + fi + fi + else + REPLY="Not started" + fi + log "$DAEMON... $REPLY." +} + +ptpd_stop(){ + log "Stopping $DAEMON..." + local REPLY + if ! ptpd_running; then + REPLY="Already stopped" + else + pkill -f $PTPD 2>/dev/null + pkill -f $PHC 2>/dev/null + if ! ptpd_running; then REPLY="Stopped"; else REPLY="Failed"; fi + fi + log "$DAEMON... $REPLY." +} + +ptpd_restart(){ + log "Restarting $DAEMON..." + ptpd_stop + sleep 1 + ptpd_start +} + +ptpd_status(){ + if ptpd_running; then + echo "$DAEMON is currently running." + else + echo "$DAEMON is not running." + exit 1 + fi +} + +case "$1" in +'start') + ptpd_start + ;; +'forcestart') + FORCE=yes + ptpd_start + ;; +'stop') + ptpd_stop + ;; +'restart') + ptpd_restart + ;; +'status') + ptpd_status + ;; +*) + echo "Usage: $BASENAME start|forcestart|stop|restart|status" + exit 1 +esac +exit 0 From 051529b33ee0ecd1deec5007383d69a5d36ce6a3 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 14 Dec 2024 15:38:51 +0100 Subject: [PATCH 002/122] Make script executable --- etc/rc.d/rc.ptpd | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 etc/rc.d/rc.ptpd diff --git a/etc/rc.d/rc.ptpd b/etc/rc.d/rc.ptpd old mode 100644 new mode 100755 From 0a66c5407a5ac9868bef8997adf5c4bc08b1e11c Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 27 Dec 2024 22:30:58 +0100 Subject: [PATCH 003/122] Date and Time enhancements - Add PTP support for bonded interfaces --- emhttp/plugins/dynamix/DateTime.page | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index 212de12b3..dbc1e0d19 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -20,9 +20,12 @@ $validIP4 = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01] $validIP6 = "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)$"; $validMAC = "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"; $tmzones = file("$docroot/webGui/include/timezones.key",FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); -$hwclock = []; +$hwclock = $members = []; -exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[0-9]*$'",$ports); +exec("ls --indicator-style=none /sys/class/net|grep -P '^bond[0-9]*$'",$ports); +foreach ($ports as $bond) $members = array_merge($members,explode(' ',exec("cat /sys/class/net/$bond/bonding/slaves"))); +exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[0-9]*$'",$eth); +foreach ($eth as $port) if (empty($members) || !in_array($port,$members)) $ports[] = $port; foreach ($ports as $port) $hwclock[$port] = exec("ethtool -T $port|grep -Pom1 '^PTP Hardware Clock: \K.+'")=='none' ? 'disabled' : ''; ?>
From 9981a9792c144088faf721063cc0a600c2ef66dc Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 10:27:20 +0100 Subject: [PATCH 004/122] Date and Time enhancements - Add PTP support for bonded interfaces --- emhttp/plugins/dynamix/DateTime.page | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index dbc1e0d19..45fecb11f 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -23,8 +23,8 @@ $tmzones = file("$docroot/webGui/include/timezones.key",FILE_IGNORE_NEW_LINES|F $hwclock = $members = []; exec("ls --indicator-style=none /sys/class/net|grep -P '^bond[0-9]*$'",$ports); -foreach ($ports as $bond) $members = array_merge($members,explode(' ',exec("cat /sys/class/net/$bond/bonding/slaves"))); exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[0-9]*$'",$eth); +foreach ($ports as $bond) $members = array_merge($members,explode(' ',exec("cat /sys/class/net/$bond/bonding/slaves"))); foreach ($eth as $port) if (empty($members) || !in_array($port,$members)) $ports[] = $port; foreach ($ports as $port) $hwclock[$port] = exec("ethtool -T $port|grep -Pom1 '^PTP Hardware Clock: \K.+'")=='none' ? 'disabled' : ''; ?> From fd7fe624f53a011f120e02fbf4ca161a0815bc39 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 12:06:15 +0100 Subject: [PATCH 005/122] Date and Time enhancements - Disable PTP for bridge interfaces (unsupported) --- emhttp/plugins/dynamix/DateTime.page | 29 ++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index 45fecb11f..ba0cb122a 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -20,12 +20,24 @@ $validIP4 = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01] $validIP6 = "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(:|([0-9a-fA-F]{1,4}:)+):(([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4})?)$"; $validMAC = "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"; $tmzones = file("$docroot/webGui/include/timezones.key",FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); -$hwclock = $members = []; +$system = "/sys/class/net"; +$hwclock = $ports = $member = []; -exec("ls --indicator-style=none /sys/class/net|grep -P '^bond[0-9]*$'",$ports); -exec("ls --indicator-style=none /sys/class/net|grep -P '^eth[0-9]*$'",$eth); -foreach ($ports as $bond) $members = array_merge($members,explode(' ',exec("cat /sys/class/net/$bond/bonding/slaves"))); -foreach ($eth as $port) if (empty($members) || !in_array($port,$members)) $ports[] = $port; +exec("ls --indicator-style=none $system|grep -P '^(br|bond|eth)[0-9]*$'",$net); +foreach ($net as $port) { + switch (preg_replace('/[0-9]+$/','',$port)) { + case 'br': + $member = array_merge($member,explode(' ',exec("ls --indicator-style=none $system/$port/brif"))); + break; + case 'bond': + if (!file_exists($system.'/'.str_replace('bond','br',$port))) $ports[] = $port; + $member = array_merge($member,explode(' ',exec("cat $system/$port/bonding/slaves"))); + break; + case 'eth': + if (!in_array($port,$member)) $ports[] = $port; + break; + } +} foreach ($ports as $port) $hwclock[$port] = exec("ethtool -T $port|grep -Pom1 '^PTP Hardware Clock: \K.+'")=='none' ? 'disabled' : ''; ?> @@ -64,7 +76,7 @@ _(Time zone)_: _(Time sync)_: : @@ -126,6 +138,7 @@ _(PTP server)_ 4: _(PTP interface)_: : - + @@ -282,7 +295,7 @@ $(function() { oldDate = form.display_date.selectedIndex; oldTime = form.display_time.selectedIndex; oldZone = form.timeZone.selectedIndex; - form.USE_NTP.selectedIndex = ; + form.USE_NTP.selectedIndex = ; updatePage(form); }); From ff8e70d627e4cebee1f3bc49a2d98c3b4920931f Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 13:22:28 +0100 Subject: [PATCH 006/122] Date and Time enhancements - Give warning when no suitable interfaces are present for PTP --- emhttp/plugins/dynamix/DateTime.page | 27 +++++++++++++++------- emhttp/plugins/dynamix/sheets/DateTime.css | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index ba0cb122a..e109c9e5d 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -23,16 +23,16 @@ $tmzones = file("$docroot/webGui/include/timezones.key",FILE_IGNORE_NEW_LINES|F $system = "/sys/class/net"; $hwclock = $ports = $member = []; -exec("ls --indicator-style=none $system|grep -P '^(br|bond|eth)[0-9]*$'",$net); +exec("ls --indicator-style=none $system|grep -P '^(bond|br|eth)[0-9]*$'",$net); foreach ($net as $port) { switch (preg_replace('/[0-9]+$/','',$port)) { - case 'br': - $member = array_merge($member,explode(' ',exec("ls --indicator-style=none $system/$port/brif"))); - break; case 'bond': if (!file_exists($system.'/'.str_replace('bond','br',$port))) $ports[] = $port; $member = array_merge($member,explode(' ',exec("cat $system/$port/bonding/slaves"))); break; + case 'br': + $member = array_merge($member,explode(' ',exec("ls --indicator-style=none $system/$port/brif"))); + break; case 'eth': if (!in_array($port,$member)) $ports[] = $port; break; @@ -76,9 +76,10 @@ _(Time zone)_: _(Time sync)_: : + _(No suitable interfaces found for PTP)_
_(NTP interval)_: @@ -146,7 +147,7 @@ _(PTP interface)_: _(PTP clock)_: : @@ -218,7 +219,7 @@ function dispatch(form) { let index = form.USE_NTP.selectedIndex; let cmd = index==1 ? (ptpd ? 'restart' : 'start') : 'stop'; save['#cfg'] = "/boot/config/plugins/dynamix/dynamix.cfg"; - save.PTP_SYNC = index==1 ? 'yes' : 'no'; + save.PTP_SYNC = index==1 ? 'yes' : 'no'; $(form).find('select[name^="display_"],select[name="NTP_POLL"],select[name^="PTP_"],input[name^="display_"],input[name^="PTP_"]').each(function(){ save[$(this).attr('name')] = $(this).val(); // exclude setting for emhttpd @@ -256,6 +257,7 @@ function updatePage(form,step) { // ntp $('#ptp-setup,#manual-setup').hide(step); $('#ntp-setup').show(step); + $('#noports').hide(); form.newDateTime.disabled=true; form.NTP_SERVER1.disabled=false; form.NTP_SERVER2.disabled=false; @@ -265,6 +267,11 @@ function updatePage(form,step) { // ptp $('#ntp-setup,#manual-setup').hide(step); $('#ptp-setup').show(step); + + $('#noports').show(); + + $('#noports').hide(); + if (form.PTP_MODE.selectedIndex==0) $('#unicast').hide(step); else $('#unicast').show(step); form.newDateTime.disabled=true; form.NTP_SERVER1.disabled=true; @@ -281,6 +288,7 @@ function updatePage(form,step) { // manual $('#ntp-setup,#ptp-setup').hide(step); $('#manual-setup').show(step); + $('#noports').hide(); form.newDateTime.disabled=false; form.NTP_SERVER1.disabled=true; form.NTP_SERVER2.disabled=true; @@ -295,7 +303,10 @@ $(function() { oldDate = form.display_date.selectedIndex; oldTime = form.display_time.selectedIndex; oldZone = form.timeZone.selectedIndex; - form.USE_NTP.selectedIndex = ; + form.USE_NTP.selectedIndex = ; + + if (form.USE_NTP.selectedIndex==1) $('#noports').show(); + updatePage(form); }); diff --git a/emhttp/plugins/dynamix/sheets/DateTime.css b/emhttp/plugins/dynamix/sheets/DateTime.css index b3012f111..22a0368b9 100644 --- a/emhttp/plugins/dynamix/sheets/DateTime.css +++ b/emhttp/plugins/dynamix/sheets/DateTime.css @@ -1,3 +1,3 @@ -div.extra,span.ipv4,span.ipv6,span.mac{display:none} +div.extra,span.ipv4,span.ipv6,span.mac,span#noports{display:none} select,input[type=text]{margin-right:40px} select[name=timeZone]{max-width:166px} From 14e36a9c553deeb0d5b223aa2a603fe2a2dc54c4 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 14:17:22 +0100 Subject: [PATCH 007/122] Date and Time enhancements - Add Time State information --- emhttp/plugins/dynamix/DateTime.page | 4 ++++ emhttp/plugins/dynamix/sheets/DateTime.css | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index e109c9e5d..c2b9d1c6a 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -73,6 +73,9 @@ _(Time zone)_: :timezone_help: +_(Time state)_: +: + _(Time sync)_: : @@ -311,6 +311,6 @@ $(function() { if (form.USE_NTP.selectedIndex==1) $('#noports').show(); updatePage(form); - setInterval(function(){$.post('/webGui/include/DashboardApps.php',{ntp:'ntp'},function(ntp){$('#timeState').html(' '+ntp);});},2000); + setInterval(function(){$.post('/webGui/include/DashboardApps.php',{ntp:'ntp'},function(ntp){$('#timeState').html(ntp);});},2000); }); From 72e7a1ad5f093f4916c283bf572429129373d2eb Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 16:41:12 +0100 Subject: [PATCH 009/122] Docker: translation corrections --- .../include/DockerContainers.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php index 0cdacd6c7..012897c17 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php @@ -240,27 +240,27 @@ foreach ($containers as $ct) { // Construct TSinfo from TSstats $TSinfo = ''; if (!$TSstats["Self"]["Online"]) { - $TSinfo .= "
"._("Online:")."
"._("Please check the logs!")."
"; + $TSinfo .= "
"._("Online").":
"._("Please check the logs")."!
"; } else { $TS_version = explode('-', $TSstats["Version"])[0]; if (!empty($TS_version)) { if (!empty($TS_latest_version)) { if ($TS_version !== $TS_latest_version) { - $TSinfo .= "
"._("Tailscale:")."v" . $TS_version . " ➔ v" . $TS_latest_version . " "._("available!")."
"; + $TSinfo .= "
"._("Tailscale").":v" . $TS_version . " ➔ v" . $TS_latest_version . " "._("available")."!
"; } else { - $TSinfo .= "
"._("Tailscale:")."v" . $TS_version . "
"; + $TSinfo .= "
"._("Tailscale").":v" . $TS_version . "
"; } } else { - $TSinfo .= "
".("Tailscale:")."v" . $TS_version . "
"; + $TSinfo .= "
".("Tailscale").":v" . $TS_version . "
"; } } - $TSinfo .= "
"._("Online:")."
"; + $TSinfo .= "
"._("Online").":
"; $TS_DNSName = $TSstats["Self"]["DNSName"]; $TS_HostNameActual = substr($TS_DNSName, 0, strpos($TS_DNSName, '.')); if (strcasecmp($TS_HostNameActual, $TShostname) !== 0 && !empty($TS_DNSName)) { - $TSinfo .= "
"._("Hostname:").""._("Real Hostname")." ➔ " . $TS_HostNameActual . "
"; + $TSinfo .= "
"._("Hostname").":"._("Real Hostname")." ➔ " . $TS_HostNameActual . "
"; } else { - $TSinfo .= "
"._("Hostname:")."" . $TShostname . "
"; + $TSinfo .= "
"._("Hostname").":" . $TShostname . "
"; } // Map region relay code to cleartext region if TS_derp_list is available if (!empty($TS_derp_list)) { @@ -271,31 +271,31 @@ foreach ($containers as $ct) { } } if (!empty($TSregion)) { - $TSinfo .= "
"._("DERP Relay:")."" . $TSregion . "
"; + $TSinfo .= "
"._("DERP Relay").":" . $TSregion . "
"; } else { - $TSinfo .= "
"._("DERP Relay:")."" . $TSstats["Self"]["Relay"] . "
"; + $TSinfo .= "
"._("DERP Relay").":" . $TSstats["Self"]["Relay"] . "
"; } } else { $TSinfo .= "
"._("DERP Relay").":" . $TSstats["Self"]["Relay"] . "
"; } if (!empty($TSstats["Self"]["TailscaleIPs"])) { - $TSinfo .= "
"._("Addresses:")."" . implode("
", $TSstats["Self"]["TailscaleIPs"]) . "
"; + $TSinfo .= "
"._("Addresses").":" . implode("
", $TSstats["Self"]["TailscaleIPs"]) . "
"; } if (!empty($TSstats["Self"]["PrimaryRoutes"])) { - $TSinfo .= "
"._("Routes:")."" . implode("
", $TSstats["Self"]["PrimaryRoutes"]) . "
"; + $TSinfo .= "
"._("Routes").":" . implode("
", $TSstats["Self"]["PrimaryRoutes"]) . "
"; } if ($TSstats["Self"]["ExitNodeOption"]) { - $TSinfo .= "
"._("Is Exit Node:")."
"; + $TSinfo .= "
"._("Is Exit Node").":
"; } else { if (!empty($TSstats["ExitNodeStatus"])) { $TS_exit_node_status = ($TSstats["ExitNodeStatus"]["Online"]) ? "✅" : "❌"; - $TSinfo .= "
"._("Exit Node:")."" . strstr($TSstats["ExitNodeStatus"]["TailscaleIPs"][0], '/', true) . " | Status: " . $TS_exit_node_status ."
"; + $TSinfo .= "
"._("Exit Node").":" . strstr($TSstats["ExitNodeStatus"]["TailscaleIPs"][0], '/', true) . " | Status: " . $TS_exit_node_status ."
"; } else { - $TSinfo .= "
"._("Is Exit Node:")."
"; + $TSinfo .= "
"._("Is Exit Node").":
"; } } if (!empty($TSwebGui)) { - $TSinfo .= "
"._("URL:")."" . $TSwebGui . "
"; + $TSinfo .= "
"._("URL").":" . $TSwebGui . "
"; } if (!empty($TSstats["Self"]["KeyExpiry"])) { $TS_expiry = new DateTime($TSstats["Self"]["KeyExpiry"]); @@ -303,9 +303,9 @@ foreach ($containers as $ct) { $TS_expiry_formatted = $TS_expiry->format('Y-m-d'); $TS_expiry_diff = $current_Date->diff($TS_expiry); if ($TS_expiry_diff->invert) { - $TSinfo .= "
"._("Key Expiry:")."❌ "._("Expired! Renew/Disable key expiry!")."
"; + $TSinfo .= "
"._("Key Expiry").":❌ "._("Expired! Renew/Disable key expiry!")."
"; } else { - $TSinfo .= "
"._("Key Expiry:")."" . $TS_expiry_formatted . " (" . $TS_expiry_diff->days . " days)
"; + $TSinfo .= "
"._("Key Expiry").":" . $TS_expiry_formatted . " (" . $TS_expiry_diff->days . " days)
"; } } } @@ -313,7 +313,7 @@ foreach ($containers as $ct) { $TS_status = "
Tailscale
"; } else { // Display message to refresh page if Tailscale in the container wasn't maybe ready to get the data - $TS_status = "
Tailscale
"; + $TS_status = "
Tailscale
"; } } else { // Display message that container isn't running From 08a6c70743d108e98780dc647173552f28067580 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Dec 2024 22:29:34 +0100 Subject: [PATCH 010/122] Date and Time enhancements - Better time state handling --- emhttp/plugins/dynamix/DateTime.page | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index 19ec80e0f..b3a5af9e1 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -74,7 +74,7 @@ _(Time zone)_: :timezone_help: _(Time state)_: -: - +: _(Time sync)_: : class="narrow" title="_(define if migratable)_"> @@ -539,8 +539,8 @@ } ?> - - _(Max)_ _(Memory)_: + + _(Max)_ _(Memory)_: >_(Enable USB boot)_: @@ -1046,7 +1046,7 @@ $arrShare) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; @@ -1062,11 +1062,11 @@ _(Unraid Share)_: @@ -1181,7 +1181,7 @@ ?> _(Multifunction)_: @@ -1202,10 +1202,10 @@ @@ -1404,7 +1404,7 @@ 'network' => $domain_bridge, 'mac' => "", 'model' => 'virtio-net' - ] ; + ]; } foreach ($arrConfig['nic'] as $i => $arrNic) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; @@ -1543,7 +1543,7 @@ />         />      style="width: 50px;" name="usbboot[]" title="_(Boot order)_" value="" > ()
- + $arrDev) { $bootdisable = $extra = $pciboot = ''; - if ($arrDev["typeid"] != "0108" && substr($arrDev["typeid"],0,2) != "02") $bootdisable = ' disabled="disabled"' ; + if ($arrDev["typeid"] != "0108" && substr($arrDev["typeid"],0,2) != "02") $bootdisable = ' disabled="disabled"'; if (count($pcidevice=array_filter($arrConfig['pci'], function($arr) use ($arrDev) { return ($arr['id'] == $arrDev['id']); }))) { $extra .= ' checked="checked"'; - foreach ($pcidevice as $pcikey => $pcidev) $pciboot = $pcidev["boot"]; ; + foreach ($pcidevice as $pcikey => $pcidev) $pciboot = $pcidev["boot"]; } elseif (!in_array($arrDev['driver'], ['pci-stub', 'vfio-pci'])) { //$extra .= ' disabled="disabled"'; @@ -1637,7 +1637,7 @@ _(QEMU Command Line)_: @@ -1654,8 +1654,8 @@ _(Clocks)_ _(Clocks Offset)_: - - id="clockoffset" class="narrow" title="_(Clock Offset)_" > - $arrTimer) { - if ($i =="offset") continue ; - if ($clockcount == 0) $clocksourcetext = _("Timer Source").":" ;else $clocksourcetext = "" ; + if ($i =="offset") continue; + if ($clockcount == 0) $clocksourcetext = _("Timer Source").":"; else $clocksourcetext = ""; ?> : _(Present)_: - id="clock[][present]" class="narrow" title="_(Clock Offset)_" > _(Tickpolicy)_: - id="clock[][tickpolicy]" class="narrow" title="_(Clock Offset)_" > @@ -1777,15 +1777,15 @@

Grab
- All grabs all input devices instead of just one + All grabs all input devices instead of just one

Repeat
- Repeat with value 'on'/'off' to enable/disable auto-repeat events + Repeat with value 'on'/'off' to enable/disable auto-repeat events

-

+

GrabToggle
GrabToggle with values ctrl-ctrl, alt-alt, shift-shift, meta-meta, scrolllock or ctrl-scrolllock to change the grab key combination

@@ -1867,7 +1867,7 @@ _(Other XML)_: @@ -1919,15 +1919,15 @@ function ShareChange(share) { var text = share.options[share.selectedIndex].text; var strArray = text.split(":"); var index = share.name.indexOf("]") + 1; - var name = share.name.substr(0,index) ; + var name = share.name.substr(0,index); if (strArray[0] === "User") { - var path = "/mnt/user/" + strArray[1] ; + var path = "/mnt/user/" + strArray[1]; } else { - var path = "/mnt/" + strArray[1] ; + var path = "/mnt/" + strArray[1]; } if (strArray[0] != "Manual") { - document.getElementById(name+"[target]").value = strArray[1] ; - document.getElementById(name+"[source]").value = path ; + document.getElementById(name+"[target]").value = strArray[1]; + document.getElementById(name+"[source]").value = path; document.getElementById(name+"[target]").setAttribute("disabled","disabled"); document.getElementById(name+"[source]").setAttribute("disabled","disabled"); } else { @@ -1939,7 +1939,7 @@ function ShareChange(share) { function BusChange(bus) { var value = bus.value; var index = bus.name.indexOf("]") + 1; - var name = bus.name.substr(0,index) ; + var name = bus.name.substr(0,index); if (value == "virtio" || value == "usb" ) { document.getElementById(name+"[rotatetext]").style.visibility="hidden"; document.getElementById(name+"[rotation]").style.visibility="hidden"; @@ -1954,7 +1954,7 @@ function BusChange(bus) { function updateSSDCheck(ssd) { var value = ssd.value; var index = ssd.name.indexOf("]") + 1; - var name = ssd.name.substr(0,index) ; + var name = ssd.name.substr(0,index); if (document.getElementById(name+"[rotation]").checked) ssd.value = "1"; else ssd.value = "0"; } @@ -1983,12 +1983,12 @@ function QEMUChgCmd(qemu) { function HypervChgNew(hyperv) { var value = hyperv.value; if (value == "0") { - var clockdefault = "windows" ; - document.getElementById("clock[rtc][present]").value = "" ; - document.getElementById("clock[pit][present]").value = "" ; + var clockdefault = "windows"; + document.getElementById("clock[rtc][present]").value = ""; + document.getElementById("clock[pit][present]").value = ""; } else { - var clockdefault = "hyperv" ; - document.getElementById("clock[rtc][present]").value = "" ; + var clockdefault = "hyperv"; + document.getElementById("clock[rtc][present]").value = ""; document.getElementById("clock[pit][present]").value = ""; } } @@ -2003,16 +2003,16 @@ function SetBootorderfields(usbbootvalue) { } var bootelements = document.getElementsByClassName("pcibootorder"); const bootpcidevs = $arrDev) { - if ($arrDev["typeid"] != "0108" && substr($arrDev["typeid"],0,2) != "02") $devlist[$arrDev['id']] = "N" ; else $devlist[$arrDev['id']] = "Y" ; + if ($arrDev["typeid"] != "0108" && substr($arrDev["typeid"],0,2) != "02") $devlist[$arrDev['id']] = "N"; else $devlist[$arrDev['id']] = "Y"; } - echo json_encode($devlist) ; + echo json_encode($devlist); ?> for(var i = 0; i < bootelements.length; i++) { - let bootpciid = bootelements[i].name.split('[') ; - bootpciid= bootpciid[1].replace(']', '') ; + let bootpciid = bootelements[i].name.split('['); + bootpciid= bootpciid[1].replace(']', ''); if (usbbootvalue == "Yes") { bootelements[i].value = ""; @@ -2056,8 +2056,8 @@ function get_storage_fstype(item) { function USBBootChange(usbboot) { // Remove all boot orders if changed to Yes - var value = usbboot.value ; - SetBootorderfields(value) ; + var value = usbboot.value; + SetBootorderfields(value); } function AutoportChange(autoport) { @@ -2067,7 +2067,7 @@ function AutoportChange(autoport) { document.getElementById("wsport").style.visibility="hidden"; document.getElementById("WSPorttext").style.visibility="hidden"; } else { - var protocol = document.getElementById("protocol").value ; + var protocol = document.getElementById("protocol").value; document.getElementById("port").style.display="inline"; document.getElementById("port").style.visibility="visible"; document.getElementById("Porttext").style.display="inline"; @@ -2085,7 +2085,7 @@ function AutoportChange(autoport) { } function ProtocolChange(protocol) { - var autoport = document.getElementById("autoport").value ; + var autoport = document.getElementById("autoport").value; if (autoport == "yes") { document.getElementById("port").style.visibility="hidden"; document.getElementById("Porttext").style.visibility="hidden"; @@ -2154,7 +2154,7 @@ $(function() { hintOptions: {schemaInfo: getLibvirtSchema()} }); - SetBootorderfields("") ; + SetBootorderfields(""); function resetForm() { $("#vmform .domain_vcpu").change(); // restore the cpu checkbox disabled states @@ -2198,7 +2198,7 @@ $(function() { var $disk_serial = $table.find('.disk_serial'); var $disk_driver = $table.find('.disk_driver').val(); var $disk_ext = "img"; - if ($disk_driver == "raw") $disk_ext = "img"; + if ($disk_driver == "raw") $disk_ext = "img"; else if(disk_select != 'manual') $disk_ext = $disk_driver; if (disk_select == 'manual') { @@ -2281,7 +2281,7 @@ $(function() { if (disk_select !== '') { // Auto disk serial - var auto_serial = 'vdisk' + (index+1) ; + var auto_serial = 'vdisk' + (index+1); $disk_serial.val(auto_serial); } @@ -2336,7 +2336,7 @@ $(function() { $("#vmform").on("spawn_section", function spawnSectionEvent(evt, section, sectiondata) { if (sectiondata.category == 'vDisk') { regenerateDiskPreview(sectiondata.index); - setDiskserial(sectiondata.index) ; + setDiskserial(sectiondata.index); } if (sectiondata.category == 'Graphics_Card') { $(section).find(".gpu").change(); @@ -2377,8 +2377,8 @@ $(function() { $("#vmform").on("change", ".cpu", function changeCPUEvent() { var myvalue = $(this).val(); var mylabel = $(this).children('option:selected').text(); - var cpumigrate = document.getElementById("domain_cpumigrate_text") ; - var cpumigrate_text = document.getElementById("domain_cpumigrate") ; + var cpumigrate = document.getElementById("domain_cpumigrate_text"); + var cpumigrate_text = document.getElementById("domain_cpumigrate"); if (myvalue == "custom") { document.getElementById("domain_cpumigrate_text").style.visibility="hidden"; document.getElementById("domain_cpumigrate").style.visibility="hidden"; @@ -2389,7 +2389,7 @@ $(function() { document.getElementById("domain_cpumigrate").style.visibility="visible"; } - }) ; + }); $("#vmform").on("change", ".gpu", function changeGPUEvent() { var myvalue = $(this).val(); @@ -2401,13 +2401,13 @@ $(function() { if (myvalue == 'virtual') { $vnc_sections.filter('.wasadvanced').removeClass('wasadvanced').addClass('advanced'); slideDownRows($vnc_sections.not(isVMAdvancedMode() ? '.basic' : '.advanced')); - var MultiSel = document.getElementById("GPUMultiSel0") ; - MultiSel.disabled = true ; + var MultiSel = document.getElementById("GPUMultiSel0"); + MultiSel.disabled = true; } else { slideUpRows($vnc_sections); $vnc_sections.filter('.advanced').removeClass('advanced').addClass('wasadvanced'); - var MultiSel = document.getElementById("GPUMultiSel0") ; - if (myvalue=="nogpu") MultiSel.disabled = true ; else MultiSel.disabled = false ; + var MultiSel = document.getElementById("GPUMultiSel0"); + if (myvalue=="nogpu") MultiSel.disabled = true; else MultiSel.disabled = false; } } @@ -2515,7 +2515,6 @@ $(function() { form.append(''); var createVmInput = form.find('input[name="createvm"],input[name="updatevm"]'); createVmInput.remove(); - $("#vmform .disk_select option:selected").not("[value='manual']").closest('table').each(function () { var v = $(this).find('.disk_preview').html(); @@ -2568,13 +2567,12 @@ $(function() { showCancelButton: true, closeOnConfirm: false, //animation: "slide-from-top", - inputPlaceholder: _("Leaving blank will use OS name.")_ + inputPlaceholder: "_(Leaving blank will use OS name)_." }, function(inputValue){ + postdata=postdata+"&templatename="+inputValue; - postdata=postdata+"&templatename="+inputValue; - $.post("/plugins/dynamix.vm.manager/templates/Custom.form.php", postdata, function( data ) { if (data.success) { if (data.vmrcurl) { @@ -2628,7 +2626,6 @@ $(function() { var $button = $(this); var $panel = $('.xmlview'); - editor.save(); $panel.find('input').prop('disabled', false); // enable all inputs otherwise they wont post @@ -2649,25 +2646,22 @@ $(function() { showCancelButton: true, closeOnConfirm: false, //animation: "slide-from-top", - inputPlaceholder: _("Leaving blank will use OS name.")_ - }, - function(inputValue){ - - - postdata=postdata+"&templatename="+inputValue; - - $.post("/plugins/dynamix.vm.manager/templates/Custom.form.php", postdata, function( data ) { - if (data.success) { - done(); - } - if (data.error) { - swal({title:"_(VM creation error)_",text:data.error,type:"error",confirmButtonText:"_(Ok)_"}); - $panel.find('input').prop('disabled', false); - $button.val($button.attr('readyvalue')); - resetForm(); - } - }, "json"); - }); + inputPlaceholder: "_(Leaving blank will use OS name)_." + }, + function(inputValue){ + postdata=postdata+"&templatename="+inputValue; + $.post("/plugins/dynamix.vm.manager/templates/Custom.form.php", postdata, function( data ) { + if (data.success) { + done(); + } + if (data.error) { + swal({title:"_(VM creation error)_",text:data.error,type:"error",confirmButtonText:"_(Ok)_"}); + $panel.find('input').prop('disabled', false); + $button.val($button.attr('readyvalue')); + resetForm(); + } + }, "json"); + }); }); // Fire events below once upon showing page diff --git a/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php b/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php index 10b2b95ca..681b423ff 100644 --- a/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php +++ b/emhttp/plugins/dynamix.vm.manager/templates/Custom.formold.php @@ -42,7 +42,7 @@ if (is_file($templateslocation)){ $arrAllTemplates["User-templates"] = ""; - $ut = json_decode(file_get_contents($templateslocation),true) ; + $ut = json_decode(file_get_contents($templateslocation),true); $arrAllTemplates = array_merge($arrAllTemplates, $ut); } @@ -152,7 +152,7 @@ $protocol = $lv->domain_get_vmrc_protocol($dom); $reply = ['success' => true]; if ($vmrcport > 0) { - $reply['vmrcurl'] = autov('/plugins/dynamix.vm.manager/'.$protocol.'.html',true).'&autoconnect=true&host=' . $_SERVER['HTTP_HOST'] ; + $reply['vmrcurl'] = autov('/plugins/dynamix.vm.manager/'.$protocol.'.html',true).'&autoconnect=true&host=' . $_SERVER['HTTP_HOST']; if ($protocol == "spice") $reply['vmrcurl'] .= '&port=/wsproxy/'.$vmrcport.'/'; else $reply['vmrcurl'] .= '&port=&path=/wsproxy/' . $wsport . '/'; } } else { @@ -185,9 +185,9 @@ // hot-attach any new usb devices foreach ($arrNewUSBIDs as $strNewUSBID) { - if (strpos($strNewUSBID,"#remove")) continue ; - $remove = explode('#', $strNewUSBID) ; - $strNewUSBID2 = $remove[0] ; + if (strpos($strNewUSBID,"#remove")) continue; + $remove = explode('#', $strNewUSBID); + $strNewUSBID2 = $remove[0]; foreach ($arrExistingConfig['usb'] as $arrExistingUSB) { if ($strNewUSBID2 == $arrExistingUSB['id']) continue 2; } @@ -240,7 +240,7 @@ // XML view $xml = $_POST['xmldesc']; $arrExistingConfig = custom::createArray('domain',$xml); - $newuuid = $arrExistingConfig['uuid'] ; + $newuuid = $arrExistingConfig['uuid']; $xml = str_replace($olduuid,$newuuid,$xml); } else { // form view @@ -250,7 +250,7 @@ array_update_recursive($arrExistingConfig, $arrUpdatedConfig); $arrConfig = array_replace_recursive($arrExistingConfig, $arrUpdatedConfig); $xml = custom::createXML('domain',$arrConfig)->saveXML(); - $xml = $lv->appendqemucmdline($xml,$_POST["qemucmdline"]) ; + $xml = $lv->appendqemucmdline($xml,$_POST["qemucmdline"]); } else { echo json_encode(['error' => $error]); exit; @@ -283,24 +283,24 @@ $strXML = $lv->domain_get_xml($dom); $boolNew = false; $arrConfig = array_replace_recursive($arrConfigDefaults, domain_to_config($uuid)); - $arrVMUSBs = getVMUSBs($strXML) ; + $arrVMUSBs = getVMUSBs($strXML); } else { // edit new VM $boolRunning = false; $strXML = ''; $boolNew = true; $arrConfig = $arrConfigDefaults; - $arrVMUSBs = getVMUSBs($strXML) ; + $arrVMUSBs = getVMUSBs($strXML); } // Add any custom metadata field defaults (e.g. os) if (!$arrConfig['template']['os']) { $arrConfig['template']['os'] = ($arrConfig['domain']['clock']=='localtime' ? 'windows' : 'linux'); } $os_type = ((empty($arrConfig['template']['os']) || stripos($arrConfig['template']['os'], 'windows') === false) ? 'other' : 'windows'); - if (isset($arrConfig['clocks'])) $arrClocks = json_decode($arrConfig['clocks'],true) ; else { + if (isset($arrConfig['clocks'])) $arrClocks = json_decode($arrConfig['clocks'],true); else { if ($os_type == "windows") { - if ($arrConfig['domain']['hyperv'] == 1) $arrClocks = $arrDefaultClocks['hyperv'] ; else $arrClocks = $arrDefaultClocks['windows'] ; - } else $arrClocks = $arrDefaultClocks['other'] ; + if ($arrConfig['domain']['hyperv'] == 1) $arrClocks = $arrDefaultClocks['hyperv']; else $arrClocks = $arrDefaultClocks['windows']; + } else $arrClocks = $arrDefaultClocks['other']; } if (strpos($arrConfig['template']['name'],"User-") !== false) { @@ -356,7 +356,7 @@ @@ -407,10 +407,9 @@

- @@ -425,7 +424,7 @@ @@ -493,8 +492,8 @@ } ?> - - _(Max)_ _(Memory)_: + + _(Max)_ _(Memory)_:
@@ -567,8 +566,8 @@ >_(Enable USB boot)_: @@ -778,9 +777,7 @@ } } } - } - echo mk_option($default_option, 'manual', _('Manual')); ?>
@@ -932,9 +929,7 @@ } } } - } - echo mk_option('', 'manual', _('Manual')); ?>
@@ -980,7 +975,7 @@ $arrShare) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; @@ -996,11 +991,11 @@ _(Unraid Share)_: @@ -1114,7 +1109,7 @@ ?> _(Multifunction)_: @@ -1128,10 +1123,10 @@ @@ -1164,11 +1159,11 @@ >_(VM Console Port)_: - > + > >_(VM Console WS Port)_: - > + > @@ -1329,7 +1324,7 @@ 'network' => $domain_bridge, 'mac' => "", 'model' => 'virtio-net' - ] ; + ]; } foreach ($arrConfig['nic'] as $i => $arrNic) { $strLabel = ($i > 0) ? appendOrdinalSuffix($i + 1) : ''; @@ -1419,9 +1414,7 @@
_(Machine)_:
@@ -1559,7 +1548,7 @@ @@ -1576,8 +1565,8 @@ - $arrTimer) { - if ($i =="offset") continue ; - if ($clockcount == 0) $clocksourcetext = _("Timer Source").":" ;else $clocksourcetext = "" ; + if ($i =="offset") continue; + if ($clockcount == 0) $clocksourcetext = _("Timer Source").":"; else $clocksourcetext = ""; ?> @@ -1678,8 +1667,6 @@ - -
_(QEMU Command Line)_:
_(Clocks)_
_(Clocks Offset)_: - - id="clockoffset" class="narrow" title="_(Clock Offset)_" >
: _(Present)_: - id="clock[][present]" class="narrow" title="_(Clock Offset)_" > _(Tickpolicy)_: - id="clock[][tickpolicy]" class="narrow" title="_(Clock Offset)_" >
@@ -1696,15 +1683,15 @@

Grab
- All grabs all input devices instead of just one + All grabs all input devices instead of just one

Repeat
- Repeat with value 'on'/'off' to enable/disable auto-repeat events + Repeat with value 'on'/'off' to enable/disable auto-repeat events

-

+

GrabToggle
GrabToggle with values ctrl-ctrl, alt-alt, shift-shift, meta-meta, scrolllock or ctrl-scrolllock to change the grab key combination

@@ -1758,7 +1745,6 @@ - @@ -1819,82 +1805,82 @@ - + +
_(Interface)_ eth0
+ +
+ +
+_(IPv4 DNS server assignment)_: +: + +:eth_ipv4_dns_server_assignment_help: + +
+_(IPv4 DNS server)_ 1: +: + +:eth_ipv4_dns_server_help: + +_(IPv4 DNS server)_ 2: +: + +:eth_ipv4_dns_server2_help: + +_(IPv4 DNS server)_ 3: +: + +:eth_ipv4_dns_server3_help: + +
+
+
+_(IPv6 DNS server assignment)_: +: + +:eth_ipv6_dns_server_assignment_help: + +
+_(IPv6 DNS server)_ 1: +: + +:eth_ipv6_dns_server_help: + +_(IPv6 DNS server)_ 2: +: + +:eth_ipv6_dns_server2_help: + +_(IPv6 DNS server)_ 3: +: + +:eth_ipv6_dns_server3_help: + +
+
+ +
+ + @@ -433,29 +509,37 @@ $(function() { + + + + + + + + + _(Interface description)_: -: - " oninput="noRun(this.form)"> +: "> + :eth_interface_description_help: -
@@ -93,4 +72,3 @@ _(Enter route + gateway + metric)_: : - diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php new file mode 100644 index 000000000..c60ef5e68 --- /dev/null +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -0,0 +1,53 @@ + +"._('missing').""; +$speed = preg_replace('/^(\d+)/','$1 ',exec("ethtool $port | awk '$1==\"Speed:\" {print $2;exit}'")) ?: $error; +$ipv4 = exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $error; +$gw4 = exec("ip -4 route show default | awk '{print \$3;exit}'") ?: $error; +$dns4 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')===false;})) ?: $error; +$domain = exec("grep -Pom1 'domain \K.*' /etc/resolv.conf") ?: '---'; + +if ($v6on) { + $ipv6 = exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $error; + $gw6 = exec("ip -6 route show default | awk '{print \$3;exit}'") ?: $error; + $dns6 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')!==false;})) ?: $error; +} + +echo "
_(Protocol)__(Route)__(Gateway)__(Metric)__(Delete)_
"; +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; +if ($v6on) { + echo ""; + echo ""; + echo ""; +} +echo ""; +echo "
  
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 default gateway').":$gw4
"._('IPv4 DNS servers').":$dns4
"._('IPv6 address').":$ipv6
"._('IPv6 default gateway').":$gw6
"._('IPv6 DNS servers').":$dns6
"._('Domain name').":$domain
"; +?> diff --git a/emhttp/plugins/dynamix/include/RoutingTable.php b/emhttp/plugins/dynamix/include/RoutingTable.php index e889769e4..7908083f5 100644 --- a/emhttp/plugins/dynamix/include/RoutingTable.php +++ b/emhttp/plugins/dynamix/include/RoutingTable.php @@ -1,6 +1,6 @@ /dev/null"); + } else { + $cmd = 'start'; + $old = []; + if (file_exists($cfg)) { + $old = parse_ini_string(preg_replace(['/^#/m',"/\r/m"],[';',''],file_get_contents($cfg))); + if (isset($old['SYSNICS'])) { + // new syntax + $ifname = ifname($set); + } else { + // legacy syntax + if ($set=='eth0') $ifname = $old['BRIDGING']=='yes' ? ($old['BRNAME'] ?? 'br0') : ($old['BONDING']=='yes' ? ($old['BONDNAME'] ?? 'bond0') : $set); + } } - } - exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null"); - if ($ini[$set]['BONDING']=='yes') { - // release additional NICs in bond - foreach (bond_nics($ini[$set],$set) as $nic) { - if (isset($old['SYSNICS'])) $nic = ifname($nic); - if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); - } - } elseif ($ini[$set]['BRIDGING']=='yes') { - // release additional NICs in bridge - foreach (bridge_nics($ini[$set],$set) as $nic) { - if (isset($old['SYSNICS'])) $nic = ifname($nic); - if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_stop")." >/dev/null"); + if ($ini[$set]['BONDING']=='yes') { + // release additional NICs in bond + foreach (bond_nics($ini[$set],$set) as $nic) { + if (isset($old['SYSNICS'])) $nic = ifname($nic); + if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + } + } elseif ($ini[$set]['BRIDGING']=='yes') { + // release additional NICs in bridge + foreach (bridge_nics($ini[$set],$set) as $nic) { + if (isset($old['SYSNICS'])) $nic = ifname($nic); + if ($nic && $nic!=$ifname) exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$nic}_stop")." >/dev/null"); + } } } } @@ -127,14 +143,14 @@ foreach ($ini as $name => $port) { $i++; } $new[] = "SYSNICS=\"$i\""; - file_put_contents($cfg,implode("\r\n",$new)."\r\n"); + // start interface with updated (new) configuration // don't execute when only interface description has changed if ($run) { - exec("/etc/rc.d/rc.inet1 {$ifname}_start &>/dev/null"); - exec("/usr/local/sbin/create_network_ini $ifname &>/dev/null &"); - update_wireguard($ifname); + exec("/etc/rc.d/rc.inet1 ".escapeshellarg("{$ifname}_{$cmd}")." >/dev/null"); + exec("/usr/local/sbin/create_network_ini ".escapeshellarg($ifname)." &>/dev/null &"); + if (!$dns) update_wireguard($ifname); } exit(0); ?> diff --git a/emhttp/plugins/dynamix/sheets/Eth0-black.css b/emhttp/plugins/dynamix/sheets/Eth0-black.css new file mode 100644 index 000000000..286010f7c --- /dev/null +++ b/emhttp/plugins/dynamix/sheets/Eth0-black.css @@ -0,0 +1 @@ +.uplift{margin-top:-30px!important} \ No newline at end of file diff --git a/emhttp/plugins/dynamix/sheets/Eth0-white.css b/emhttp/plugins/dynamix/sheets/Eth0-white.css new file mode 100644 index 000000000..286010f7c --- /dev/null +++ b/emhttp/plugins/dynamix/sheets/Eth0-white.css @@ -0,0 +1 @@ +.uplift{margin-top:-30px!important} \ No newline at end of file diff --git a/emhttp/plugins/dynamix/sheets/Eth0.css b/emhttp/plugins/dynamix/sheets/Eth0.css index 6ddcb7136..10c281e70 100644 --- a/emhttp/plugins/dynamix/sheets/Eth0.css +++ b/emhttp/plugins/dynamix/sheets/Eth0.css @@ -3,10 +3,11 @@ span.blue{color:#00529B} span.green{color:#4F8A10} span.vshift{margin-top:0!important} input.gap{margin-right:6px} -input.form{font-size:1rem;padding:5px 10px;margin-left:10px} +input.form{font-size:1rem;padding:5px 10px;margin:0 0 0 10px} div.shade-white{background-color:#ededed;margin-top:10px;padding:8px 0 3px 0} div.shade-black{background-color:#212121;margin-top:10px;padding:8px 0 3px 0} div.shade-azure{background-color:#edeaef;margin-top:10px;padding:8px 0 3px 0} div.shade-gray{background-color:#121510;margin-top:10px;padding:8px 0 3px 0} select.slim{min-width:47px;margin-left:4px} input.slim{width:32px;margin-left:8px} +.hide{display:none} diff --git a/etc/rc.d/rc.inet1 b/etc/rc.d/rc.inet1 index 8a2154885..b0aefffd2 100755 --- a/etc/rc.d/rc.inet1 +++ b/etc/rc.d/rc.inet1 @@ -7,6 +7,7 @@ # @(#)/etc/rc.d/rc.inet1 10.2 Sun Jul 24 12:45:56 PDT 2005 (pjv) # LimeTech - modified for Unraid OS +# Bergware - modified for Unraid OS, January 2025 # Adapted by Bergware for use in Unraid OS - April 2016 # - improved interface configuration @@ -72,7 +73,9 @@ # Adapted by Bergware for use in Unraid OS - February 2024 # - revised bond interface creation for linux kernel 6.6.14 and later point releases -# Bergware - modified for Unraid OS, February 2024 +# Adapted by Bergware for use in Unraid OS - January 2025 +# - added 'renew' command to restart interface without reconfiguring +# - fixed dns assigment may be missing in some cases ########### # LOGGING # @@ -337,21 +340,23 @@ ipv6_addr(){ # function to assign IP address ipaddr_up(){ - # disable IPv6 per interface when IPv4 only - [[ $IP == ipv4 ]] && DISABLE6=1 || DISABLE6=0 - [[ -d $CONF6/$IFACE ]] && echo $DISABLE6 >$CONF6/$IFACE/disable_ipv6 - [[ -d $CONF6/$VHOST ]] && echo $DISABLE6 >$CONF6/$VHOST/disable_ipv6 - # repeat action on related interfaces - if [[ ${IFACE:0:4} == bond ]]; then - ipv6_up bond br eth $DISABLE6 - elif [[ ${IFACE:0:2} == br ]]; then - ipv6_up br bond eth $DISABLE6 - else - ipv6_up eth bond br $DISABLE6 + if [[ -z $RENEW ]]; then + # disable IPv6 per interface when IPv4 only + [[ $IP == ipv4 ]] && DISABLE6=1 || DISABLE6=0 + [[ -d $CONF6/$IFACE ]] && echo $DISABLE6 >$CONF6/$IFACE/disable_ipv6 + [[ -d $CONF6/$VHOST ]] && echo $DISABLE6 >$CONF6/$VHOST/disable_ipv6 + # repeat action on related interfaces + if [[ ${IFACE:0:4} == bond ]]; then + ipv6_up bond br eth $DISABLE6 + elif [[ ${IFACE:0:2} == br ]]; then + ipv6_up br bond eth $DISABLE6 + else + ipv6_up eth bond br $DISABLE6 + fi fi if [[ $DHCP == yes ]]; then # bring up interface using DHCP/SLAAC - ipv6_addr 1 1 + [[ -z $RENEW ]] && ipv6_addr 1 1 DHCP_OPTIONS="-q -n -p -t ${DHCP_TIMEOUT[$i]:-10}" [[ -n $DHCP_HOSTNAME ]] && DHCP_OPTIONS="$DHCP_OPTIONS -h $DHCP_HOSTNAME" [[ $DHCP_KEEP_RESOLV == yes ]] && DHCP_OPTIONS="$DHCP_OPTIONS -C resolv.conf" @@ -436,11 +441,12 @@ ipaddr_down(){ [[ $IP == ipv6 ]] && DHCP_OPTIONS="$DHCP_OPTIONS -6" # release DHCP assigned addresses run dhcpcd $DHCP_OPTIONS $IFACE - sleep 1 fi - # release assigned addresses and routes - [[ $IP != ipv6 ]] && ipaddr_flush 4 - [[ $IP != ipv4 ]] && ipaddr_flush 6 + if [[ -z $RENEW ]]; then + # release assigned addresses and routes + [[ $IP != ipv6 ]] && ipaddr_flush 4 + [[ $IP != ipv4 ]] && ipaddr_flush 6 + fi } # function to bring up network interface @@ -452,18 +458,21 @@ if_up(){ done # exit when interface is not found [[ $i -eq $MAXNICS ]] && break - [[ -n ${BONDNICS[$i]} ]] && bond_up # create interface as bond - [[ -n ${VLANS[$i]} ]] && vlan_up # create interface VLANs - [[ -n ${BRNICS[$i]} ]] && br_up # create interface as bridge - [[ -z ${BRNICS[$i]} ]] && macvtap_up # create macvtap interfaces - # if the interface isn't in the kernel yet - # but there's an alias for it in modules.conf - # then it should be loaded first - if [[ ! -e $SYSTEM/$1 ]]; then - if modprobe -c | grep -v "^#" | grep -w "alias $1" | grep -qvw "alias $1 off"; then - run modprobe $1 - else - [[ $DEBUG_ETH_UP == yes ]] && log "interface $1 not present nor aliased, can't create" + # skip interface creation when renew only + if [[ -z $RENEW ]]; then + [[ -n ${BONDNICS[$i]} ]] && bond_up # create interface as bond + [[ -n ${VLANS[$i]} ]] && vlan_up # create interface VLANs + [[ -n ${BRNICS[$i]} ]] && br_up # create interface as bridge + [[ -z ${BRNICS[$i]} ]] && macvtap_up # create macvtap interfaces + # if the interface isn't in the kernel yet + # but there's an alias for it in modules.conf + # then it should be loaded first + if [[ ! -e $SYSTEM/$1 ]]; then + if modprobe -c | grep -v "^#" | grep -w "alias $1" | grep -qvw "alias $1 off"; then + run modprobe $1 + else + [[ $DEBUG_ETH_UP == yes ]] && log "interface $1 not present nor aliased, can't create" + fi fi fi # loop thru main and VLAN interfaces @@ -477,13 +486,15 @@ if_up(){ fi # macvtap interface name VHOST=vhost${IFACE//[^0-9.]} - # set main interface - if [[ $j -eq 0 ]]; then - # set hardware address before interface goes up - [[ -n ${HWADDR[$i]} ]] && run ip link set $1 addr ${HWADDR[$i]} - set_mtu $1 + if [[ -z $RENEW ]]; then + # set main interface + if [[ $j -eq 0 ]]; then + # set hardware address before interface goes up + [[ -n ${HWADDR[$i]} ]] && run ip link set $1 addr ${HWADDR[$i]} + set_mtu $1 + fi + run ip link set $IFACE up fi - run ip link set $IFACE up # set interface address [[ $i -eq 0 && $j -eq 0 ]] && MAIN=1 || MAIN= if [[ $IP == ipv4 ]]; then @@ -545,23 +556,27 @@ if_down(){ else [[ $j -eq 0 ]] && DHCP=${USE_DHCP[$i]} || DHCP=${USE_DHCP[$i,$j]} [[ $j -eq 0 ]] && DHCP6=${USE_DHCP6[$i]} || DHCP6=${USE_DHCP6[$i,$j]} - [[ $j -eq 0 ]] && DHCP_KEEP_RESOLV=$DHCP_KEEPRESOLV || DHCP_KEEP_RESOLV=yes + [[ -n $MAIN ]] && DHCP_KEEP_RESOLV=$DHCP_KEEPRESOLV || DHCP_KEEP_RESOLV=yes + [[ -n $MAIN ]] && DHCP6_KEEP_RESOLV=$DHCP6_KEEPRESOLV || DHCP6_KEEP_RESOLV=yes IP=ipv4 ipaddr_down IP=ipv6 DHCP=$DHCP6 - [[ $j -eq 0 ]] && DHCP_KEEP_RESOLV=$DHCP6_KEEPRESOLV || DHCP_KEEP_RESOLV=yes + DHCP_KEEP_RESOLV=$DHCP6_KEEP_RESOLV ipaddr_down fi - run ip link set $IFACE down + [[ -z $RENEW ]] && run ip link set $IFACE down else [[ $DEBUG_ETH_UP == yes ]] && log "interface $IFACE not present, can't take down" fi done - [[ -z ${BRNICS[$i]} ]] && macvtap_down # delete macvtap interfaces - [[ -n ${BRNICS[$i]} ]] && br_down # delete interface as bridge - [[ -n ${VLANS[$i]} ]] && vlan_down # delete interface VLANs - [[ -n ${BONDNICS[$i]} ]] && bond_down # delete interface as bond + # skip interface deletion when renew only + if [[ -z $RENEW ]]; then + [[ -z ${BRNICS[$i]} ]] && macvtap_down # delete macvtap interfaces + [[ -n ${BRNICS[$i]} ]] && br_down # delete interface as bridge + [[ -n ${VLANS[$i]} ]] && vlan_down # delete interface VLANs + [[ -n ${BONDNICS[$i]} ]] && bond_down # delete interface as bond + fi } ##################### @@ -717,6 +732,13 @@ restart) if_up $INTERFACE gateway_up ;; +*_renew) + RENEW=1 + INTERFACE=$(echo $1 | cut -d_ -f1) + CMD=$(echo $1 | cut -d_ -f2) + [[ $CMD == start ]] && if_up $INTERFACE + [[ $CMD == stop ]] && if_down $INTERFACE + ;; *_add) INTERFACE=$(echo $1 | cut -d_ -f1) ROUTE=$(echo $1 | cut -d_ -f2) @@ -731,11 +753,11 @@ restart) [[ $METRIC == del ]] && METRIC= route_down $INTERFACE $ROUTE $METRIC ;; - # default is to bring up the entire network status) status $2 ;; *) + # default is to bring up the entire network start esac exit 0 From f3bc7aed71d6053a9e6b6e8b3601b0b940ad3c78 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 03:08:36 +0100 Subject: [PATCH 029/122] style corrections --- emhttp/plugins/dynamix/styles/default-black.css | 8 ++++---- emhttp/plugins/dynamix/styles/default-white.css | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/emhttp/plugins/dynamix/styles/default-black.css b/emhttp/plugins/dynamix/styles/default-black.css index fbf0f1706..89504eba4 100644 --- a/emhttp/plugins/dynamix/styles/default-black.css +++ b/emhttp/plugins/dynamix/styles/default-black.css @@ -60,8 +60,8 @@ div.title span.right{font-size:1.4rem;padding-top:2px;padding-right:10px;float:r div.title span img{padding-right:4px} div.title.shift{margin-top:-30px} #menu{position:absolute;top:90px;left:0;right:0;display:grid;grid-template-columns:auto max-content;z-index:101} -.nav-tile{height:4rem;line-height:4rem;padding:0;margin:0;font-size:1.2rem;letter-spacing:1.8px;background-color:#f2f2f2;white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin} -.nav-tile::-webkit-scrollbar{height:5px} +.nav-tile{height:4rem;line-height:4rem;padding:0;margin:0;font-size:1.2rem;letter-spacing:1.8px;background-color:#f2f2f2;white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-height:4px} +.nav-tile::-webkit-scrollbar{height:4px} .nav-tile.right{text-align:right} .nav-item,.nav-user{position:relative;display:inline-block;text-align:center;margin:0} .nav-item a{min-width:0} @@ -204,8 +204,8 @@ a.list{text-decoration:none;color:inherit} div.content{position:absolute;top:0;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both} div.content.shift{margin-top:1px} label+.content{margin-top:86px} -div.tabs{position:relative;margin:130px 0 0 0} -div.tab{float:left;margin-top:30px} +div.tabs{position:relative;margin:120px 0 0 0} +div.tab{float:left;margin-top:32px} div.tab input[id^="tab"]{display:none} div.tab [type=radio]+label:hover{background-color:transparent;border:1px solid #ff8c2f;border-bottom:none;cursor:pointer;opacity:1} div.tab [type=radio]:checked+label{cursor:default;background-color:transparent;border:1px solid #ff8c2f;border-bottom:none;opacity:1} diff --git a/emhttp/plugins/dynamix/styles/default-white.css b/emhttp/plugins/dynamix/styles/default-white.css index 3c7509976..eb67de492 100644 --- a/emhttp/plugins/dynamix/styles/default-white.css +++ b/emhttp/plugins/dynamix/styles/default-white.css @@ -60,8 +60,8 @@ div.title span.right{font-size:1.4rem;padding-top:2px;padding-right:10px;float:r div.title span img{padding-right:4px} div.title.shift{margin-top:-30px} #menu{position:absolute;top:90px;left:0;right:0;display:grid;grid-template-columns:auto max-content;z-index:101} -.nav-tile{height:4rem;line-height:4rem;padding:0;margin:0;font-size:1.2rem;letter-spacing:1.8px;background-color:#1c1b1b;white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:thin} -.nav-tile::-webkit-scrollbar{height:5px} +.nav-tile{height:4rem;line-height:4rem;padding:0;margin:0;font-size:1.2rem;letter-spacing:1.8px;background-color:#1c1b1b;white-space:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-height:4px} +.nav-tile::-webkit-scrollbar{height:4px} .nav-tile.right{text-align:right} .nav-item,.nav-user{position:relative;display:inline-block;text-align:center;margin:0} .nav-item a{min-width:0} @@ -204,8 +204,8 @@ a.list{text-decoration:none;color:inherit} div.content{position:absolute;top:0;left:0;width:100%;padding-bottom:30px;z-index:-1;clear:both} div.content.shift{margin-top:1px} label+.content{margin-top:86px} -div.tabs{position:relative;margin:130px 0 0 0} -div.tab{float:left;margin-top:30px} +div.tabs{position:relative;margin:120px 0 0 0} +div.tab{float:left;margin-top:32px} div.tab input[id^="tab"]{display:none} div.tab [type=radio]+label:hover{background-color:transparent;border:1px solid #ff8c2f;border-bottom:none;cursor:pointer;opacity:1} div.tab [type=radio]:checked+label{cursor:default;background-color:transparent;border:1px solid #ff8c2f;border-bottom:none;opacity:1} From b14a636043470f8f45235e0a38ed81952971082c Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 10:21:49 +0100 Subject: [PATCH 030/122] Network enhancements - visual updates --- emhttp/plugins/dynamix/Eth0.page | 25 ++++++++++++------------ emhttp/plugins/dynamix/EthX.page | 2 +- emhttp/plugins/dynamix/NetworkExtra.page | 2 +- emhttp/plugins/dynamix/NetworkRules.page | 2 +- emhttp/plugins/dynamix/RoutingTable.page | 2 +- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index 9a295fc6d..3505bdb6f 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -141,7 +141,7 @@ function prepareSettings(form) { $(form).find('input[name^="METRIC:"]').each(function(){if($(this).val()>0) metrics.push($(this).val());}); $(form).find('input[name^="METRIC6:"]').each(function(){if($(this).val()>0) metrics6.push($(this).val());}); if (metrics.same() || metrics6.same()) { - swal({title:'Duplicate metrics',text:'List of default gateways contains duplicate metric values',type:'error',html:true,confirmButtonText:"_(Ok)_"}); + swal({title:'Duplicate metrics',text:'List of default gateways contains duplicate metric values',animation:'none',type:'error',html:true,confirmButtonText:"_(Ok)_"}); return false; } if (form.TYPE.value == 'access') { @@ -162,7 +162,7 @@ function prepareSettings(form) { var vlans = []; $(form).find('input[name^="VLANID:"]').each(function(){vlans.push($(this).val());}); if (vlans.same()) { - swal({title:"_(VLAN assignment mismatch)_",text:"_(List of VLANs contains duplicate VLAN numbers)_",type:'error',html:true,confirmButtonText:"_(Ok)_"}); + swal({title:"_(VLAN assignment mismatch)_",text:"_(List of VLANs contains duplicate VLAN numbers)_",animation:'none',type:'error',html:true,confirmButtonText:"_(Ok)_"}); return false; } } @@ -432,13 +432,12 @@ $(function() { function networkInfo(port) { $.post('/webGui/include/NetworkInfo.php',{port:port},function(text) { - swal({title:"_(Network Info)_", text:text, html:true, confirmButtonText:"_(Ok)_"}); + swal({title:"_(Network Info)_",text:text,animation:'none',html:true,confirmButtonText:"_(Ok)_"}); }); } -
_(Interface)_ eth0
- +
 
@@ -509,14 +508,14 @@ _(IPv6 DNS server)_ 3: - - - - - - - - + + + + + + + + _(Interface description)_: : "> diff --git a/emhttp/plugins/dynamix/EthX.page b/emhttp/plugins/dynamix/EthX.page index 1ff77fa48..5e078150f 100644 --- a/emhttp/plugins/dynamix/EthX.page +++ b/emhttp/plugins/dynamix/EthX.page @@ -71,7 +71,7 @@ $(function() { }); -
_(Interface)_ ethX
+
 
diff --git a/emhttp/plugins/dynamix/NetworkExtra.page b/emhttp/plugins/dynamix/NetworkExtra.page index 5e89c2ad5..f607b6de1 100644 --- a/emhttp/plugins/dynamix/NetworkExtra.page +++ b/emhttp/plugins/dynamix/NetworkExtra.page @@ -59,7 +59,7 @@ $(function(){ }); -
_(Interface Extra)_
+
 
diff --git a/emhttp/plugins/dynamix/NetworkRules.page b/emhttp/plugins/dynamix/NetworkRules.page index cb1a509b8..0bd8bcd62 100644 --- a/emhttp/plugins/dynamix/NetworkRules.page +++ b/emhttp/plugins/dynamix/NetworkRules.page @@ -54,7 +54,7 @@ function update_info(id,mac) { $('#info-'+id).html(info['_'+mac.replace(/:/g,'')]); } -
_(Interface Rules)_
+
 
diff --git a/emhttp/plugins/dynamix/RoutingTable.page b/emhttp/plugins/dynamix/RoutingTable.page index 6ee01d3a5..610f296f8 100644 --- a/emhttp/plugins/dynamix/RoutingTable.page +++ b/emhttp/plugins/dynamix/RoutingTable.page @@ -52,7 +52,7 @@ $(function(){ routeTable(); }); -
_(Routing Table)_
+
 
From 39516fc07905a5e44e565135e9beb6ecbe22a86f Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 10:24:04 +0100 Subject: [PATCH 031/122] Update RoutingTable.page --- emhttp/plugins/dynamix/RoutingTable.page | 1 - 1 file changed, 1 deletion(-) diff --git a/emhttp/plugins/dynamix/RoutingTable.page b/emhttp/plugins/dynamix/RoutingTable.page index 610f296f8..76ba85e23 100644 --- a/emhttp/plugins/dynamix/RoutingTable.page +++ b/emhttp/plugins/dynamix/RoutingTable.page @@ -52,7 +52,6 @@ $(function(){ routeTable(); }); -
 
_(Protocol)__(Route)__(Gateway)__(Metric)__(Delete)_
From b735e89086aabca32160100d8c47f6258433c411 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 11:43:19 +0100 Subject: [PATCH 032/122] Fix regression errors --- emhttp/plugins/dynamix/Eth0.page | 26 ++++++++++++-------------- emhttp/plugins/dynamix/EthX.page | 4 ++-- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index 3505bdb6f..c9d9493f9 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -168,7 +168,7 @@ function prepareSettings(form) { } $(form).find('select[name^="PROTOCOL:"]').each(function() { var protocol = $(this).val() || 'ipv4'; - var i = $(this).attr('name').split(':')[1]; + var i = $(this).prop('name').split(':')[1]; if (protocol == 'ipv6') { $(form).find('input[name="IPADDR:'+i+'"]').prop('disabled',false).val(''); $(form).find('select[name="NETMASK:'+i+'"]').prop('disabled',false).val(''); @@ -184,7 +184,7 @@ function prepareSettings(form) { } }); $(form).find('select[name^="USE_DHCP:"]').each(function() { - var i = $(this).attr('name').split(':')[1]; + var i = $(this).prop('name').split(':')[1]; var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4'; var metric = $(form).find('input[name="METRIC:'+i+'"]').val(); if (protocol != 'ipv6' && $(this).val()=='yes') { @@ -193,7 +193,7 @@ function prepareSettings(form) { } }); $(form).find('select[name^="USE_DHCP6:"]').each(function() { - var i = $(this).attr('name').split(':')[1]; + var i = $(this).prop('name').split(':')[1]; var protocol = $(form).find('select[name="PROTOCOL:'+i+'"]').val() || 'ipv4'; var metric = $(form).find('input[name="METRIC6:'+i+'"]').val(); if (protocol != 'ipv4' && $(this).val()=='yes') { @@ -240,12 +240,12 @@ function selectProtocol(form,index,step) { var more4 = $('.'+'more-ipv4-'+port+'-'+index); var more6 = $('.'+'more-ipv6-'+port+'-'+index); switch (protocol) { - case 'ipv4': net4.show(step); net6.hide(step); $('#dns4').show(step); $('#dns6').hide(step); break; - case 'ipv6': net4.hide(step); net6.show(step); $('#dns4').hide(step); $('#dns6').show(step); break; - case 'ipv4+ipv6': net4.show(step); net6.show(step); $('#dns4').show(step); $('#dns6').show(step); break; + case 'ipv4': net4.show(step); net6.hide(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').hide(step);} break; + case 'ipv6': net4.hide(step); net6.show(step); if (port=='eth0') {$('#dns4').hide(step); $('#dns6').show(step);} break; + case 'ipv4+ipv6': net4.show(step); net6.show(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').show(step);} break; } - if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()=='no') more4.show(step); else more4.hide(step); - if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()=='no') more6.show(step); else more6.hide(step); + if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()) more4.show(step); else more4.hide(step); + if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()) more6.show(step); else more6.hide(step); checkNetworkSettings(form,index); } } @@ -355,11 +355,11 @@ function addVLAN(port) { var template = $($('
').loadTemplate($('#network-template-'+port)).html().replace(/INDEX/g,index)); var element = $('[id^="index-'+port+'-"]').last(); $(element).after(template); - $('form[name="'+$(element).parent().attr('name')+'"]').find('select').first().trigger('change'); + $('form[name="'+$(element).parent().parent().prop('name')+'"]').find('select').first().trigger('change'); } function removeVLAN(element) { - var id = $(element).attr('id').split('-'); + var id = $(element).prop('id').split('-'); $(element).remove(); $('#view-'+id[1]).find('select').first().trigger('change'); } @@ -677,7 +677,7 @@ _(Enable VLANs)_: :eth_enable_vlans_help:
-
+
_(Interface description)_: @@ -705,9 +705,7 @@ _(IPv4 address assignment)_: : :eth_ipv4_address_assignment_help: @@ -804,7 +802,7 @@ _(Network protocol)_: -
+
_(IPv4 address assignment)_: : -
+
_(IPv4 address assignment)_: : "> + )"> :eth_interface_description_help: diff --git a/emhttp/plugins/dynamix/EthX.page b/emhttp/plugins/dynamix/EthX.page index d36bcae82..8a4c7e5a2 100644 --- a/emhttp/plugins/dynamix/EthX.page +++ b/emhttp/plugins/dynamix/EthX.page @@ -256,6 +256,7 @@ _(Enable VLANs)_:
_(Interface description)_: : "> + )"> :eth_interface_description_help: diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index c60ef5e68..770283efd 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -22,23 +22,29 @@ function port($eth) { return file_exists("$sys/br{$x}") ? "br${x}" : (file_exists("$sys/bond{$x}") ? "bond{$x}" : "eth{$x}"); } exec("grep -Po 'nameserver \K.*' /etc/resolv.conf",$dns); -$port = port($_POST['port']); +$eth = $_POST['port']; +$vlan = $_POST['vlan']; +$port = port($eth).($vlan ? ".$vlan" : ""); $v6on = @file_get_contents("/proc/sys/net/ipv6/conf/$port/disable_ipv6")!=1; -$error = ""._('missing').""; -$speed = preg_replace('/^(\d+)/','$1 ',exec("ethtool $port | awk '$1==\"Speed:\" {print $2;exit}'")) ?: $error; -$ipv4 = exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $error; -$gw4 = exec("ip -4 route show default | awk '{print \$3;exit}'") ?: $error; +$none = _('None'); +$error = ""._('Missing').""; +$note = $eth=='eth0' && !$vlan ? $error : $none; +$link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." (".exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'").")"; +$speed = _(preg_replace(['/^(\d+)/','/!/'],['$1 ',''],exec("ethtool $eth | awk '$1==\"Speed:\" {print $2;exit}'"))); +$ipv4 = exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $note; +$gw4 = exec("ip -4 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns4 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')===false;})) ?: $error; $domain = exec("grep -Pom1 'domain \K.*' /etc/resolv.conf") ?: '---'; if ($v6on) { - $ipv6 = exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $error; - $gw6 = exec("ip -6 route show default | awk '{print \$3;exit}'") ?: $error; + $ipv6 = exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $note; + $gw6 = exec("ip -6 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns6 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')!==false;})) ?: $error; } echo "
_(Protocol)__(Route)__(Gateway)__(Metric)__(Delete)_
"; echo ""; +echo ""; echo ""; echo ""; echo ""; From 0ec700e17333b1519387887e629959aa5c6453e8 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 13:22:43 +0100 Subject: [PATCH 034/122] Update NetworkInfo.php --- emhttp/plugins/dynamix/include/NetworkInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index 770283efd..a9e720c70 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -44,7 +44,7 @@ if ($v6on) { echo "
  
"._('Link detected').":$link
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 default gateway').":$gw4
"; echo ""; -echo ""; +echo ""; echo ""; echo ""; echo ""; From f803bf7563567aa38245a6da68bf62d12ca873d6 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 13:23:47 +0100 Subject: [PATCH 035/122] Update NetworkInfo.php --- emhttp/plugins/dynamix/include/NetworkInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index a9e720c70..abf89acd4 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -44,7 +44,7 @@ if ($v6on) { echo "
  
"._('Link detected').":$link
"._('Interface detected').":$link
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 default gateway').":$gw4
"; echo ""; -echo ""; +echo ""; echo ""; echo ""; echo ""; From 69c18369aaf1ec2ae83e805d75442b903469ef00 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 13:29:32 +0100 Subject: [PATCH 036/122] Update NetworkInfo.php --- emhttp/plugins/dynamix/include/NetworkInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index abf89acd4..6efa669cf 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -44,7 +44,7 @@ if ($v6on) { echo "
  
"._('Interface detected').":$link
"._('Interface up').":$link
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 default gateway').":$gw4
"; echo ""; -echo ""; +echo ""; echo ""; echo ""; echo ""; From 51a0a19572c63d56cdc2c7b2784bc0882a513975 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 13:50:55 +0100 Subject: [PATCH 037/122] Update NetworkInfo.php --- .../plugins/dynamix/include/NetworkInfo.php | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index 6efa669cf..e5c0dd9fb 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -21,7 +21,7 @@ function port($eth) { $x = preg_replace('/[^0-9]/','',$eth); return file_exists("$sys/br{$x}") ? "br${x}" : (file_exists("$sys/bond{$x}") ? "bond{$x}" : "eth{$x}"); } -exec("grep -Po 'nameserver \K.*' /etc/resolv.conf",$dns); +exec("grep -Po 'nameserver \K.*' /etc/resolv.conf",$ns); $eth = $_POST['port']; $vlan = $_POST['vlan']; $port = port($eth).($vlan ? ".$vlan" : ""); @@ -31,28 +31,44 @@ $error = ""._('Missing').""; $note = $eth=='eth0' && !$vlan ? $error : $none; $link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." (".exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'").")"; $speed = _(preg_replace(['/^(\d+)/','/!/'],['$1 ',''],exec("ethtool $eth | awk '$1==\"Speed:\" {print $2;exit}'"))); -$ipv4 = exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $note; +$ipv4 = explode(' ',exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs")); $gw4 = exec("ip -4 route show default dev $port | awk '{print \$3;exit}'") ?: $note; -$dns4 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')===false;})) ?: $error; +$dns4 = array_filter($ns,function($ns){return strpos($ns,':')===false;}); $domain = exec("grep -Pom1 'domain \K.*' /etc/resolv.conf") ?: '---'; if ($v6on) { - $ipv6 = exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs") ?: $note; + $ipv6 = explode(' ',exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs")); $gw6 = exec("ip -6 route show default dev $port | awk '{print \$3;exit}'") ?: $note; - $dns6 = implode(' ',array_filter($dns,function($ns){return strpos($ns,':')!==false;})) ?: $error; + $dns6 = array_filter($ns,function($ns){return strpos($ns,':')!==false;}); } echo "
  
"._('Interface up').":$link
"._('Interface link').":$link
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 default gateway').":$gw4
"; echo ""; echo ""; echo ""; -echo ""; +if (count($ipv4)) foreach ($ipv4 as $ip) { + echo ""; +} else { + echo ""; +} echo ""; -echo ""; +if (count($dns4)) foreach ($dns4 as $dns) { + echo ""; +} else { + echo ""; +} if ($v6on) { - echo ""; + if (count($ipv6)) foreach ($ipv6 as $ip) { + echo ""; + } else { + echo ""; + } echo ""; - echo ""; + if (count($dns6)) foreach ($dns6 as $dns) { + echo ""; + } else { + echo ""; + } } echo ""; echo "
  
"._('Interface link').":$link
"._('Interface speed').":$speed
"._('IPv4 address').":$ipv4
"._('IPv4 address').":$ip
"._('IPv4 address').":$note
"._('IPv4 default gateway').":$gw4
"._('IPv4 DNS servers').":$dns4
"._('IPv4 DNS server').":$dns
"._('IPv4 DNS server').":$error
"._('IPv6 address').":$ipv6
"._('IPv6 address').":$ip
"._('IPv6 address').":$note
"._('IPv6 default gateway').":$gw6
"._('IPv6 DNS servers').":$dns6
"._('IPv6 DNS server').":$dns
"._('IPv6 DNS server').":$error
"._('Domain name').":$domain
"; From bd30462c565ab375172a7cb74dd6bcdebf1a7220 Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 13:55:00 +0100 Subject: [PATCH 038/122] Update NetworkInfo.php --- emhttp/plugins/dynamix/include/NetworkInfo.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index e5c0dd9fb..5460fec5d 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -31,13 +31,13 @@ $error = ""._('Missing').""; $note = $eth=='eth0' && !$vlan ? $error : $none; $link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." (".exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'").")"; $speed = _(preg_replace(['/^(\d+)/','/!/'],['$1 ',''],exec("ethtool $eth | awk '$1==\"Speed:\" {print $2;exit}'"))); -$ipv4 = explode(' ',exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs")); +$ipv4 = array_filter(explode(' ',exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); $gw4 = exec("ip -4 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns4 = array_filter($ns,function($ns){return strpos($ns,':')===false;}); $domain = exec("grep -Pom1 'domain \K.*' /etc/resolv.conf") ?: '---'; if ($v6on) { - $ipv6 = explode(' ',exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g' | xargs")); + $ipv6 = array_filter(explode(' ',exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); $gw6 = exec("ip -6 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns6 = array_filter($ns,function($ns){return strpos($ns,':')!==false;}); } From b21ee4e45b82a34ff0f8ace2010aaeb217f2724d Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 14:20:31 +0100 Subject: [PATCH 039/122] Fix regression errors --- emhttp/plugins/dynamix/Eth0.page | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index 151ce8b00..750d83988 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -229,8 +229,13 @@ function selectProtocol(form,index,step) { case 'ipv6': net4.hide(); net6.show(); break; case 'ipv4+ipv6': net4.show(); net6.show(); break; } - if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()=='no') more4.show(); else more4.hide(); - if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()=='no') more6.show(); else more6.hide(); + + more4.hide(); + more6.hide(); + + if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()!='yes') more4.show(); else more4.hide(); + if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()!='yes') more6.show(); else more6.hide(); + checkNetworkSettings(form,i); }); } else { @@ -244,8 +249,8 @@ function selectProtocol(form,index,step) { case 'ipv6': net4.hide(step); net6.show(step); if (port=='eth0') {$('#dns4').hide(step); $('#dns6').show(step);} break; case 'ipv4+ipv6': net4.show(step); net6.show(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').show(step);} break; } - if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()) more4.show(step); else more4.hide(step); - if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()) more6.show(step); else more6.hide(step); + if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()!='yes') more4.show(step); else more4.hide(step); + if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()!='yes') more6.show(step); else more6.hide(step); checkNetworkSettings(form,index); } } From f2ed0eaef4ede8bbe3949e6b11461b6e72c9379e Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 14:40:47 +0100 Subject: [PATCH 040/122] Update NetworkInfo.php --- emhttp/plugins/dynamix/include/NetworkInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index 5460fec5d..c07534b48 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -29,7 +29,7 @@ $v6on = @file_get_contents("/proc/sys/net/ipv6/conf/$port/disable_ipv6")!=1; $none = _('None'); $error = ""._('Missing').""; $note = $eth=='eth0' && !$vlan ? $error : $none; -$link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." (".exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'").")"; +$link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." ("._(exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'")).")"; $speed = _(preg_replace(['/^(\d+)/','/!/'],['$1 ',''],exec("ethtool $eth | awk '$1==\"Speed:\" {print $2;exit}'"))); $ipv4 = array_filter(explode(' ',exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); $gw4 = exec("ip -4 route show default dev $port | awk '{print \$3;exit}'") ?: $note; From 51f1c40d737651d4557931190841d884c7d9217b Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 14 Jan 2025 17:05:37 +0100 Subject: [PATCH 041/122] Fix regression bug --- emhttp/plugins/dynamix/Eth0.page | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index 750d83988..7e73a1223 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -233,8 +233,8 @@ function selectProtocol(form,index,step) { more4.hide(); more6.hide(); - if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()!='yes') more4.show(); else more4.hide(); - if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()!='yes') more6.show(); else more6.hide(); + if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()=='no') more4.show(); else more4.hide(); + if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()=='no') more6.show(); else more6.hide(); checkNetworkSettings(form,i); }); @@ -249,8 +249,8 @@ function selectProtocol(form,index,step) { case 'ipv6': net4.hide(step); net6.show(step); if (port=='eth0') {$('#dns4').hide(step); $('#dns6').show(step);} break; case 'ipv4+ipv6': net4.show(step); net6.show(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').show(step);} break; } - if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()!='yes') more4.show(step); else more4.hide(step); - if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()!='yes') more6.show(step); else more6.hide(step); + if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()=='no') more4.show(step); else more4.hide(step); + if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()=='no') more6.show(step); else more6.hide(step); checkNetworkSettings(form,index); } } From 8bf934c98864915ec304a8fe9aca41c22d4b8c53 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 17 Jan 2025 23:07:55 +0100 Subject: [PATCH 042/122] IPv6 corrections --- emhttp/plugins/dynamix/Eth0.page | 9 +++++++-- emhttp/plugins/dynamix/EthX.page | 2 ++ emhttp/plugins/dynamix/include/NetworkInfo.php | 4 ++-- etc/rc.d/rc.library.source | 2 +- sbin/create_network_ini | 8 ++++---- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index 7e73a1223..b76243fac 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -224,6 +224,7 @@ function selectProtocol(form,index,step) { var net6 = $('.'+'ipv6-'+port+'-'+i); var more4 = $('.'+'more-ipv4-'+port+'-'+i); var more6 = $('.'+'more-ipv6-'+port+'-'+i); + var priv6 = $('.'+'priv-ipv6-'+port+'-'+i); switch (protocol) { case 'ipv4': net4.show(); net6.hide(); break; case 'ipv6': net4.hide(); net6.show(); break; @@ -232,9 +233,10 @@ function selectProtocol(form,index,step) { more4.hide(); more6.hide(); + priv6.hide(); if ($(form).find('select[name="USE_DHCP:'+i+'"]').val()=='no') more4.show(); else more4.hide(); - if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()=='no') more6.show(); else more6.hide(); + if ($(form).find('select[name="USE_DHCP6:'+i+'"]').val()=='no') {more6.show(); priv6.hide();} else {more6.hide(); priv6.show();} checkNetworkSettings(form,i); }); @@ -244,13 +246,14 @@ function selectProtocol(form,index,step) { var net6 = $('.'+'ipv6-'+port+'-'+index); var more4 = $('.'+'more-ipv4-'+port+'-'+index); var more6 = $('.'+'more-ipv6-'+port+'-'+index); + var priv6 = $('.'+'priv-ipv6-'+port+'-'+index); switch (protocol) { case 'ipv4': net4.show(step); net6.hide(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').hide(step);} break; case 'ipv6': net4.hide(step); net6.show(step); if (port=='eth0') {$('#dns4').hide(step); $('#dns6').show(step);} break; case 'ipv4+ipv6': net4.show(step); net6.show(step); if (port=='eth0') {$('#dns4').show(step); $('#dns6').show(step);} break; } if ($(form).find('select[name="USE_DHCP:'+index+'"]').val()=='no') more4.show(step); else more4.hide(step); - if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()=='no') more6.show(step); else more6.hide(step); + if ($(form).find('select[name="USE_DHCP6:'+index+'"]').val()=='no') {more6.show(step); priv6.hide(step);} else {more6.hide(step); priv6.show(step);} checkNetworkSettings(form,index); } } @@ -657,6 +660,8 @@ _(IPv6 default gateway)_: :eth_ipv6_default_gateway_help: +
+
_(IPv6 privacy extensions)_: : diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index c07534b48..2d86d3f82 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -31,13 +31,13 @@ $error = ""._('Missing').""; $note = $eth=='eth0' && !$vlan ? $error : $none; $link = _(ucfirst(exec("ethtool $eth | awk '$1==\"Link\" {print $3;exit}'")))." ("._(exec("ethtool $eth | grep -Pom1 '^\s+Port: \K.*'")).")"; $speed = _(preg_replace(['/^(\d+)/','/!/'],['$1 ',''],exec("ethtool $eth | awk '$1==\"Speed:\" {print $2;exit}'"))); -$ipv4 = array_filter(explode(' ',exec("ip -4 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); +$ipv4 = array_filter(explode(' ',exec("ip -4 -br addr show $port scope global | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); $gw4 = exec("ip -4 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns4 = array_filter($ns,function($ns){return strpos($ns,':')===false;}); $domain = exec("grep -Pom1 'domain \K.*' /etc/resolv.conf") ?: '---'; if ($v6on) { - $ipv6 = array_filter(explode(' ',exec("ip -6 -br addr show scope global $port | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); + $ipv6 = array_filter(explode(' ',exec("ip -6 -br addr show $port scope global -temporary | awk '{\$1=\$2=\"\";print;exit}' | sed -r 's/ metric [0-9]+//g; s/\/[0-9]+//g'"))); $gw6 = exec("ip -6 route show default dev $port | awk '{print \$3;exit}'") ?: $note; $dns6 = array_filter($ns,function($ns){return strpos($ns,':')!==false;}); } diff --git a/etc/rc.d/rc.library.source b/etc/rc.d/rc.library.source index 3dc4bfdbf..9c2f35c0b 100644 --- a/etc/rc.d/rc.library.source +++ b/etc/rc.d/rc.library.source @@ -159,7 +159,7 @@ check(){ fi [[ $(ipv $ADDR) == 4 ]] && IPV4=yes || IPV6=yes done - done <<< $(ip -br addr show scope global | awk '$1~"^(br|bond|eth|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort) + done <<< $(ip -br addr show scope global -temporary | awk '$1~"^(br|bond|eth|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort) # add loopback interface if [[ "smb nfs" =~ "$CALLER" ]]; then [[ $IPV4 == yes ]] && BIND+=(127.0.0.1) diff --git a/sbin/create_network_ini b/sbin/create_network_ini index 8be9969cd..49533211d 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -241,11 +241,11 @@ if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then # find management interface [[ -e /sys/class/net/bond0 ]] && dev=bond0 || dev=eth0 [[ -e /sys/class/net/br0 ]] && dev=br0 - IPv4=$(ip -br -4 addr show $dev scope global|sed -r 's/metric [0-9]+//g'|awk '{print $3;exit}') - IPv6=$(ip -br -6 addr show $dev scope global|sed -r 's/metric [0-9]+//g'|awk '{print $NF;exit}') + IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $1=$2="";print;exit}' | xargs) + IPv6=$(ip -br -6 addr show $dev scope global -temporary | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{$1=$2="";print;exit}' | xargs) # show current IP assignment - [[ -n $IPv4 ]] && echo " IPv4 address: ${IPv4%/*}" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue - [[ -n $IPv6 ]] && echo " IPv6 address: ${IPv6%/*}" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue + [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue + [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue echo >>/etc/issue fi exit 0 From fb5ec8f6c19b5c76995a2df2ca3fa055b9534df7 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 17 Jan 2025 23:16:45 +0100 Subject: [PATCH 043/122] IPv6 corrections --- emhttp/plugins/dynamix/Eth0.page | 4 ++++ emhttp/plugins/dynamix/EthX.page | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/emhttp/plugins/dynamix/Eth0.page b/emhttp/plugins/dynamix/Eth0.page index b76243fac..f3a0e0523 100644 --- a/emhttp/plugins/dynamix/Eth0.page +++ b/emhttp/plugins/dynamix/Eth0.page @@ -776,6 +776,8 @@ _(IPv6 default gateway)_: :eth_ipv6_default_gateway_help: +
+
_(IPv6 privacy extensions)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* +
+
_(IPv6 privacy extensions)_: : @@ -429,6 +431,8 @@ _(IPv6 default gateway)_: : " pattern="" title="_(IPv6 address nnnn:xxxx::yyyy)_"> " class="slim"> *_(optional metric (lowest is preferred, 0 is no default gateway))_* +
+
_(IPv6 privacy extensions)_: : > - **_(DHCP pool)_:**: -/ "; - echo ""; -?> @@ -422,10 +414,6 @@ _(IPv6 custom network on interface)_ (_(optional)_): **_(Gateway)_:**" title="_(IPv6 address nnnn:xxxx::yyyy)_"> - > - **_(DHCP pool)_:**>/ - @@ -528,7 +516,6 @@ if (isset($dockercfg[$docker_dhcp6]) || empty($dockercfg["DOCKER_AUTO_$net"])):? _(IPv6 custom network on interface)_ : : **_(Subnet)_:** **_(Gateway)_:** - **_(DHCP pool)_:** @@ -551,7 +538,7 @@ if (!$vlan) { _(IPv6 custom network on interface)_ : : **_(Subnet)_:** / **_(Gateway)_:** - **_(DHCP pool)_:** +
diff --git a/etc/rc.d/rc.docker b/etc/rc.d/rc.docker index dfe398e62..03fcc79d6 100755 --- a/etc/rc.d/rc.docker +++ b/etc/rc.d/rc.docker @@ -323,16 +323,13 @@ docker_network_start(){ RANGE=${!DHCP} GATEWAY=$(ip -4 route show default dev $NETWORK | awk '{print $3;exit}') fi - SUBNET6=; GATEWAY6=; SERVER6=; RANGE6=; + SUBNET6=; GATEWAY6=; SERVER6=; IPV6=$(ip -6 -br addr show $NETWORK scope global nodad | awk '{print $3;exit}') [[ -z $IPV6 ]] && IPV6=$(ip -6 -br addr show $NETWORK scope global dynamic | awk '{print $3;exit}') if [[ -n $IPV6 ]]; then # get IPV6 subnet, preset to /64 if single host address is given [[ ${IPV6#*/} == 128 ]] && SUBNET6=$(echo $IPV6 | sed -r 's/^([^:]+):([^:]+):([^:]+):([^:]+).*$/\1:\2:\3:\4::\/64/') || SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}') SERVER6=${IPV6%/*} - DHCP6=${NETWORK/./_} - DHCP6=DOCKER_DHCP6_${DHCP6^^} - RANGE6=${!DHCP6} GATEWAY6=$(ip -6 route show default dev $NETWORK | awk '{print $3;exit}') # replace link local address for first address in subnet [[ ${GATEWAY6:0:4} == fe80 ]] && GATEWAY6=${SUBNET6%/*}1 @@ -354,8 +351,6 @@ docker_network_start(){ GATEWAY6=DOCKER_GATEWAY6_$DEVICE GATEWAY6=${!GATEWAY6} SERVER6=; - RANGE6=DOCKER_RANGE6_$DEVICE - RANGE6=${!RANGE6} fi # custom network already existing and changed? if [[ $NETWORKS =~ "$NETWORK " ]]; then @@ -375,7 +370,7 @@ docker_network_start(){ [[ -n ${SERVERS[1]} && ${SERVERS[1]} =~ '.' ]] && SERVER0=${SERVERS[1]} || SERVER1=${SERVERS[1]} # check for changes [[ $SUBNET != $SUBNET0 || $SUBNET6 != $SUBNET1 ]] && UPDATE=1 - [[ $RANGE != $RANGE0 || $RANGE6 != $RANGE1 ]] && UPDATE=1 + [[ $RANGE != $RANGE0 ]] && UPDATE=1 [[ (-n $GATEWAY && $GATEWAY != $GATEWAY0) || (-n $GATEWAY6 && $GATEWAY6 != $GATEWAY1) ]] && UPDATE=1 [[ (-n $SERVER && $SERVER != $SERVER0) || (-n $SERVER6 && $SERVER6 != $SERVER1) ]] && UPDATE=1 if [[ -z $UPDATE ]]; then @@ -388,20 +383,19 @@ docker_network_start(){ fi # set parameters for custom network creation N4=$SUBNET; R4=$RANGE; - N6=$SUBNET6; R6=$RANGE6; + N6=$SUBNET6; [[ -n $SUBNET && -n $GATEWAY ]] && GATEWAY="--gateway=$GATEWAY" || GATEWAY=; [[ -n $SUBNET && -n $SERVER ]] && SERVER="--aux-address=server=$SERVER" || SERVER=; [[ -n $SUBNET && -n $RANGE ]] && RANGE="--ip-range=$RANGE" || RANGE=; [[ -n $SUBNET ]] && SUBNET="--subnet=$SUBNET" [[ -n $SUBNET6 && -n $GATEWAY6 ]] && GATEWAY6="--gateway=$GATEWAY6" || GATEWAY6=; [[ -n $SUBNET6 && -n $SERVER6 ]] && SERVER6="--aux-address=server6=$SERVER6" || SERVER6=; - [[ -n $SUBNET6 && -n $RANGE6 ]] && RANGE6="--ip-range=$RANGE6" || RANGE6=; [[ -n $SUBNET6 ]] && SUBNET6="--ipv6 --subnet=$SUBNET6" if [[ -n $SUBNET || -n $SUBNET6 ]]; then TYPE=${NETWORK//[0-9.]/} driver $TYPE [[ $TYPE == br ]] && VHOST=$NETWORK || VHOST=vhost${NETWORK//[^0-9.]/} - docker network create -d $ATTACH $SUBNET $GATEWAY $SERVER $RANGE $SUBNET6 $GATEWAY6 $SERVER6 $RANGE6 -o parent=$VHOST $NETWORK | xargs docker network inspect -f "created network $ATTACH {{.Name}} with subnets: {{range .IPAM.Config}}{{.Subnet}}; {{end}}" 2>/dev/null | log + docker network create -d $ATTACH $SUBNET $GATEWAY $SERVER $RANGE $SUBNET6 $GATEWAY6 $SERVER6 -o parent=$VHOST $NETWORK | xargs docker network inspect -f "created network $ATTACH {{.Name}} with subnets: {{range .IPAM.Config}}{{.Subnet}}; {{end}}" 2>/dev/null | log # connect containers to this new network for CONNECT in ${NETRESTORE[$NETWORK]}; do CONTAINER=${CONNECT%,*} From 074a9daf7d701e34dd83b33f8dbea9a1e98bb0af Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 05:04:25 +0100 Subject: [PATCH 047/122] Docker IPv6 corrections --- emhttp/plugins/dynamix.docker.manager/DockerSettings.page | 2 +- etc/rc.d/rc.docker | 2 +- etc/rc.d/rc.library.source | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/DockerSettings.page b/emhttp/plugins/dynamix.docker.manager/DockerSettings.page index 7d6c11b39..5f4a34435 100644 --- a/emhttp/plugins/dynamix.docker.manager/DockerSettings.page +++ b/emhttp/plugins/dynamix.docker.manager/DockerSettings.page @@ -53,7 +53,7 @@ $wide = false; foreach ($custom as $network) { if (in_array($network,$slaves)) continue; $ip4 = exec("ip -4 -br addr show $network | awk '{print $3;exit}'"); - $ip6 = exec("ip -6 -br addr show $network scope global -temporary | awk '{print $3;exit}'"); + $ip6 = exec("ip -6 -br addr show $network scope global -temporary -deprecated | awk '{print $3;exit}'"); $gw4 = $ip4 ? exec("ip -4 route show dev $network default | awk '{print $3;exit}'") : ''; $gw6 = $ip6 ? exec("ip -6 route show dev $network default | awk '{print $3;exit}'") : ''; $route4 = $ip4 ? exec("ip -4 route show dev $network $ip4 | awk '{print $1;exit}'") : ''; diff --git a/etc/rc.d/rc.docker b/etc/rc.d/rc.docker index 03fcc79d6..52bc7142d 100755 --- a/etc/rc.d/rc.docker +++ b/etc/rc.d/rc.docker @@ -325,7 +325,7 @@ docker_network_start(){ fi SUBNET6=; GATEWAY6=; SERVER6=; IPV6=$(ip -6 -br addr show $NETWORK scope global nodad | awk '{print $3;exit}') - [[ -z $IPV6 ]] && IPV6=$(ip -6 -br addr show $NETWORK scope global dynamic | awk '{print $3;exit}') + [[ -z $IPV6 ]] && IPV6=$(ip -6 -br addr show $NETWORK scope global dynamic -temporary -deprecated | awk '{print $3;exit}') if [[ -n $IPV6 ]]; then # get IPV6 subnet, preset to /64 if single host address is given [[ ${IPV6#*/} == 128 ]] && SUBNET6=$(echo $IPV6 | sed -r 's/^([^:]+):([^:]+):([^:]+):([^:]+).*$/\1:\2:\3:\4::\/64/') || SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}') diff --git a/etc/rc.d/rc.library.source b/etc/rc.d/rc.library.source index 9c2f35c0b..e1f0ee0cd 100644 --- a/etc/rc.d/rc.library.source +++ b/etc/rc.d/rc.library.source @@ -159,7 +159,7 @@ check(){ fi [[ $(ipv $ADDR) == 4 ]] && IPV4=yes || IPV6=yes done - done <<< $(ip -br addr show scope global -temporary | awk '$1~"^(br|bond|eth|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort) + done <<< $(ip -br addr show scope global -temporary -deprecated | awk '$1~"^(br|bond|eth|wg)[0-9]+(.[0-9]+)?" && $3!="" {gsub("@.+","",$1);$2="";print}' | sed -r 's/ metric [0-9]+//g' | sort) # add loopback interface if [[ "smb nfs" =~ "$CALLER" ]]; then [[ $IPV4 == yes ]] && BIND+=(127.0.0.1) From 1eb7c535d689ce47576538a42209aec621edf488 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 05:20:31 +0100 Subject: [PATCH 048/122] Docker IPv6 corrections --- etc/rc.d/rc.docker | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/etc/rc.d/rc.docker b/etc/rc.d/rc.docker index 52bc7142d..6cd0ed19b 100755 --- a/etc/rc.d/rc.docker +++ b/etc/rc.d/rc.docker @@ -324,8 +324,7 @@ docker_network_start(){ GATEWAY=$(ip -4 route show default dev $NETWORK | awk '{print $3;exit}') fi SUBNET6=; GATEWAY6=; SERVER6=; - IPV6=$(ip -6 -br addr show $NETWORK scope global nodad | awk '{print $3;exit}') - [[ -z $IPV6 ]] && IPV6=$(ip -6 -br addr show $NETWORK scope global dynamic -temporary -deprecated | awk '{print $3;exit}') + IPV6=$(ip -6 -br addr show $NETWORK scope global -temporary -deprecated | awk '{print $3;exit}') if [[ -n $IPV6 ]]; then # get IPV6 subnet, preset to /64 if single host address is given [[ ${IPV6#*/} == 128 ]] && SUBNET6=$(echo $IPV6 | sed -r 's/^([^:]+):([^:]+):([^:]+):([^:]+).*$/\1:\2:\3:\4::\/64/') || SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}') From 4fbf016c69ad2c8f292d94ed3469973547ad4d7b Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 05:31:35 +0100 Subject: [PATCH 049/122] Docker IPv6 corrections --- etc/rc.d/rc.docker | 2 +- sbin/create_network_ini | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/rc.d/rc.docker b/etc/rc.d/rc.docker index 6cd0ed19b..e233fa6c8 100755 --- a/etc/rc.d/rc.docker +++ b/etc/rc.d/rc.docker @@ -314,7 +314,7 @@ docker_network_start(){ fi # add auto defined networks SUBNET=; GATEWAY=; SERVER=; RANGE=; - IPV4=$(ip -4 -br addr show $NETWORK | awk '{print $3;exit}') + IPV4=$(ip -4 -br addr show $NETWORK scope global | awk '{print $3;exit}') if [[ -n $IPV4 ]]; then SUBNET=$(ip -4 route show $IPV4 dev $NETWORK | awk '{print $1;exit}') SERVER=${IPV4%/*} diff --git a/sbin/create_network_ini b/sbin/create_network_ini index 49533211d..f7d4b9217 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -241,8 +241,8 @@ if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then # find management interface [[ -e /sys/class/net/bond0 ]] && dev=bond0 || dev=eth0 [[ -e /sys/class/net/br0 ]] && dev=br0 - IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $1=$2="";print;exit}' | xargs) - IPv6=$(ip -br -6 addr show $dev scope global -temporary | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{$1=$2="";print;exit}' | xargs) + IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show $dev scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') # show current IP assignment [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue From 3f67aad40b2b12af1642fb2958cf193e9a133589 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 05:43:20 +0100 Subject: [PATCH 050/122] Fix regression error --- emhttp/plugins/dynamix.docker.manager/DockerSettings.page | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix.docker.manager/DockerSettings.page b/emhttp/plugins/dynamix.docker.manager/DockerSettings.page index 5f4a34435..f3dc6215c 100644 --- a/emhttp/plugins/dynamix.docker.manager/DockerSettings.page +++ b/emhttp/plugins/dynamix.docker.manager/DockerSettings.page @@ -52,7 +52,7 @@ $include = $include6 = $address = $address6 = $gateway = $gateway6 = $unset = $p $wide = false; foreach ($custom as $network) { if (in_array($network,$slaves)) continue; - $ip4 = exec("ip -4 -br addr show $network | awk '{print $3;exit}'"); + $ip4 = exec("ip -4 -br addr show $network scope global | awk '{print $3;exit}'"); $ip6 = exec("ip -6 -br addr show $network scope global -temporary -deprecated | awk '{print $3;exit}'"); $gw4 = $ip4 ? exec("ip -4 route show dev $network default | awk '{print $3;exit}'") : ''; $gw6 = $ip6 ? exec("ip -6 route show dev $network default | awk '{print $3;exit}'") : ''; From ebfbaec3dc6e23d8064f30054a36f97284a663cd Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 12:49:52 +0100 Subject: [PATCH 051/122] Add "Move To End" icon --- .../dynamix/include/DefaultPageLayout.php | 90 +++++++++---------- .../dynamix/styles/defaultpagelayout.css | 3 +- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 1c3de385d..7a1f71d5c 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -252,7 +252,7 @@ function openWindow(cmd,title,height,width) { } function openTerminal(tag,name,more) { if (/MSIE|Edge/.test(navigator.userAgent)) { - swal({title:"_(Unsupported Feature)_",text:"_(Sorry, this feature is not supported by MSIE/Edge)_.
_(Please try a different browser)_",type:'error',html:true,confirmButtonText:"_(Ok)_"}); + swal({title:"_(Unsupported Feature)_",text:"_(Sorry, this feature is not supported by MSIE/Edge)_.
_(Please try a different browser)_",type:'error',html:true,animation:'none',confirmButtonText:"_(Ok)_"}); return; } // open terminal window (run in background) @@ -409,7 +409,7 @@ function openDone(data) { if (data == '_DONE_') { $('div.spinner.fixed').hide(); $('button.confirm').text("").prop('disabled',false).show(); - if ( typeof ca_done_override !== 'undefined' ) { + if (typeof ca_done_override !== 'undefined') { if (ca_done_override == true) { $("button.confirm").trigger("click"); ca_done_override = false; @@ -529,7 +529,7 @@ function hideUpgrade(set) { /** @note can likely be removed, not used in webgui } function confirmUpgrade(confirm) { if (confirm) { - swal({title:" Unraid OS",text:"?",type:'warning',html:true,showCancelButton:true,closeOnConfirm:false,confirmButtonText:"",cancelButtonText:""},function(){ + swal({title:" Unraid OS",text:"?",type:'warning',html:true,animation:'none',showCancelButton:true,closeOnConfirm:false,confirmButtonText:"",cancelButtonText:""},function(){ openPlugin("plugin update unRAIDServer.plg"," Unraid OS"); }); } else { @@ -654,6 +654,7 @@ $.ajaxPrefilter(function(s, orig, xhr){
+ backtotopoffset) { - $('.back_to_top').fadeIn(backtotopduration); + if ($(this).scrollTop() > scrollOffset) { + $('.back_to_top').fadeIn(scrollDuration); } else { - $('.back_to_top').fadeOut(backtotopduration); + $('.back_to_top').fadeOut(scrollDuration); } var top = $('div#header').height()-1; // header height has 1 extra pixel to cover overlap @@ -1049,9 +1050,16 @@ $(window).scroll(function() { $('div.upgrade_notice').css($(this).scrollTop() > 24 ? {position:'fixed',top:'0'} : {position:'absolute',top:'24px'}); }); + +$('.move_to_end').click(function(event) { + event.preventDefault(); + $('html,body').animate({scrollTop:$(document).height()},scrollDuration); + return false; +}); + $('.back_to_top').click(function(event) { event.preventDefault(); - $('html,body').animate({scrollTop:0},backtotopduration); + $('html,body').animate({scrollTop:0},scrollDuration); return false; }); @@ -1128,6 +1136,7 @@ $(function() { }); } $('form').append($('').attr({type:'hidden', name:'csrf_token', value:csrf_token})); + setTimeout(function(){if ($(document).height() > $(window).height()) $('.move_to_end').fadeIn(scrollDuration);},2000); }); var gui_pages_available = []; @@ -1147,56 +1156,43 @@ function isValidURL(url) { } } -$('body').on("click","a,.ca_href", function(e) { - if ($(this).hasClass("ca_href") ) { +$('body').on('click','a,.ca_href', function(e) { + if ($(this).hasClass('ca_href') ) { var ca_href = true; - var href=$(this).attr("data-href"); - var target=$(this).attr("data-target"); + var href=$(this).attr('data-href'); + var target=$(this).attr('data-target'); } else { var ca_href = false; - var href = $(this).attr("href"); - var target = $(this).attr("target"); + var href = $(this).attr('href'); + var target = $(this).attr('target'); } - if ( href ) { + if (href) { href = href.trim(); - if ( href.match('https?://[^\.]*.(my)?unraid.net/') || href.indexOf("https://unraid.net/") == 0 || href == "https://unraid.net" || href.indexOf("http://lime-technology.com") == 0) { - if ( ca_href ) { - window.open(href,target); - } + if (href.match('https?://[^\.]*.(my)?unraid.net/') || href.indexOf('https://unraid.net/') == 0 || href == 'https://unraid.net' || href.indexOf('http://lime-technology.com') == 0) { + if (ca_href) window.open(href,target); return; } - - if (href !== "#" && href.indexOf("javascript") !== 0) { + if (href !== '#' && href.indexOf('javascript') !== 0) { var dom = isValidURL(href); - if ( dom == false ) { - if ( href.indexOf("/") == 0 ) { // all internal links start with "/" - return; + if (dom == false) { + if (href.indexOf('/') == 0) return; // all internal links start with "/" + var baseURLpage = href.split('/'); + if (gui_pages_available.includes(baseURLpage[0])) return; } - var baseURLpage = href.split("/"); - if ( gui_pages_available.includes(baseURLpage[0]) ) { - return; - } - } - if ( $(this).hasClass("localURL") ) { - return; - } - + if ($(this).hasClass('localURL')) return; try { - var domainsAllowed = JSON.parse($.cookie("allowedDomains")); + var domainsAllowed = JSON.parse($.cookie('allowedDomains')); } catch(e) { var domainsAllowed = new Object(); } - $.cookie("allowedDomains",JSON.stringify(domainsAllowed),{expires:3650}); // rewrite cookie to further extend expiration by 400 days - - if ( domainsAllowed[dom.hostname] ) { - return; - } - + $.cookie('allowedDomains',JSON.stringify(domainsAllowed),{expires:3650}); // rewrite cookie to further extend expiration by 400 days + if (domainsAllowed[dom.hostname]) return; e.preventDefault(); swal({ title: "", text: "

"+href+"

"+dom.hostname+"
", html: true, + animation: 'none', type: 'warning', showCancelButton: true, showConfirmButton: true, @@ -1204,16 +1200,14 @@ $('body').on("click","a,.ca_href", function(e) { confirmButtonText: "" },function(isConfirm) { if (isConfirm) { - if ( $("#Link_Always_Allow").is(":checked") ) { + if ($('#Link_Always_Allow').is(':checked')) { domainsAllowed[dom.hostname] = true; - $.cookie("allowedDomains",JSON.stringify(domainsAllowed),{expires:3650}); + $.cookie('allowedDomains',JSON.stringify(domainsAllowed),{expires:3650}); } var popupOpen = window.open(href,target); - if ( !popupOpen || popupOpen.closed || typeof popupOpen == "undefined" ) { - var popupWarning = addBannerWarning(""); - setTimeout(function() { - removeBannerWarning(popupWarning);} - ,10000); + if (!popupOpen || popupOpen.closed || typeof popupOpen == 'undefined') { + var popupWarning = addBannerWarning(""); + setTimeout(function(){removeBannerWarning(popupWarning);},10000); } } }); diff --git a/emhttp/plugins/dynamix/styles/defaultpagelayout.css b/emhttp/plugins/dynamix/styles/defaultpagelayout.css index 70548d17b..425744b1f 100644 --- a/emhttp/plugins/dynamix/styles/defaultpagelayout.css +++ b/emhttp/plugins/dynamix/styles/defaultpagelayout.css @@ -3,7 +3,8 @@ .upgrade_notice.done{color:#4f8a10;background-color:#dff2bf;border-color:#4f8a10} .upgrade_notice.alert{color:#f0000c;background-color:#ff9e9e;border-color:#f0000c} .upgrade_notice i{float:right;cursor:pointer} -.back_to_top{display:none;position:fixed;bottom:30px;right:12px;color:#e22828;font-size:2.5rem;z-index:999} +.move_to_end{display:none;position:fixed;bottom:24px;right:12px;color:#e22828;font-size:2.5rem;z-index:999} +.back_to_top{display:none;position:fixed;bottom:24px;right:40px;color:#e22828;font-size:2.5rem;z-index:999} span.big.blue-text{cursor:pointer} span.strong.tour{margin-left:5px;padding-left:0} i.abortOps{font-size:2rem;float:right;margin-right:20px;margin-top:8px;cursor:pointer} From e6d7b0bf88625ea1f4e0e9a608560d3afa7f2bec Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 13:00:54 +0100 Subject: [PATCH 052/122] Add "Move To End" icon --- emhttp/plugins/dynamix/include/DefaultPageLayout.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 7a1f71d5c..0d7fe8ff7 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -1035,10 +1035,9 @@ nchan_vmaction.on('message', function(data) { box.scrollTop(box[0].scrollHeight); }); -const scrollOffset = 250; const scrollDuration = 500; $(window).scroll(function() { - if ($(this).scrollTop() > scrollOffset) { + if ($(this).scrollTop() > 0) { $('.back_to_top').fadeIn(scrollDuration); } else { $('.back_to_top').fadeOut(scrollDuration); From d2c608fe7b8a295dc5940c57a570661604187615 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 13:40:03 +0100 Subject: [PATCH 053/122] Update DefaultPageLayout.php --- emhttp/plugins/dynamix/include/DefaultPageLayout.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 0d7fe8ff7..495362b02 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -1156,7 +1156,7 @@ function isValidURL(url) { } $('body').on('click','a,.ca_href', function(e) { - if ($(this).hasClass('ca_href') ) { + if ($(this).hasClass('ca_href')) { var ca_href = true; var href=$(this).attr('data-href'); var target=$(this).attr('data-target'); @@ -1170,7 +1170,7 @@ $('body').on('click','a,.ca_href', function(e) { if (href.match('https?://[^\.]*.(my)?unraid.net/') || href.indexOf('https://unraid.net/') == 0 || href == 'https://unraid.net' || href.indexOf('http://lime-technology.com') == 0) { if (ca_href) window.open(href,target); return; - } + } if (href !== '#' && href.indexOf('javascript') !== 0) { var dom = isValidURL(href); if (dom == false) { From 83d735c10dd8d04512720f6299052cb5a4e3b36e Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 14:49:05 +0100 Subject: [PATCH 054/122] Add "Move To End" icon --- emhttp/plugins/dynamix/include/DefaultPageLayout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 495362b02..5ff596d5d 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -1135,7 +1135,7 @@ $(function() { }); } $('form').append($('').attr({type:'hidden', name:'csrf_token', value:csrf_token})); - setTimeout(function(){if ($(document).height() > $(window).height()) $('.move_to_end').fadeIn(scrollDuration);},2000); + setInterval(function(){if ($(document).height() > $(window).height()) $('.move_to_end').fadeIn(scrollDuration);},250); }); var gui_pages_available = []; From 7ddc5fa544f1320f6dcab6df04906a269ff88c15 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 18 Jan 2025 14:49:25 +0100 Subject: [PATCH 055/122] Tools page: fix javascript error --- emhttp/plugins/dynamix/Tools.page | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/Tools.page b/emhttp/plugins/dynamix/Tools.page index be69cff4a..51dcd005b 100644 --- a/emhttp/plugins/dynamix/Tools.page +++ b/emhttp/plugins/dynamix/Tools.page @@ -5,9 +5,9 @@ Code="e909" --- diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index efe725f40..2a33a45fc 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -721,7 +721,7 @@ if (isset($myPage['Load']) && $myPage['Load']>0) echo "\n @@ -67,7 +68,7 @@ $(function(){ _(Current listening interfaces)_: -: +:
_(Include listening interfaces)_: diff --git a/emhttp/plugins/dynamix/include/NetworkInfo.php b/emhttp/plugins/dynamix/include/NetworkInfo.php index afc8e217e..186e1ff50 100644 --- a/emhttp/plugins/dynamix/include/NetworkInfo.php +++ b/emhttp/plugins/dynamix/include/NetworkInfo.php @@ -16,6 +16,10 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); $_SERVER['REQUEST_URI'] = 'settings'; require_once "$docroot/webGui/include/Translations.php"; +if (isset($_POST['listen'])) { + die(exec("$docroot/webGui/scripts/show_interfaces")?:_('Any')); +} + function port($eth) { $sys = "/sys/class/net"; if (substr($eth,0,4)=='wlan') return $eth; From 932279f05aaf912858b932b0b42d817fdc3069c6 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 31 Jan 2025 15:00:01 +0100 Subject: [PATCH 074/122] add wireless info (if present) at startup message --- sbin/create_network_ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sbin/create_network_ini b/sbin/create_network_ini index f7d4b9217..5643fd321 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -246,6 +246,13 @@ if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then # show current IP assignment [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue + if [[ -e /sys/class/net/wlan0 ]] then + echo "Wireless network:" >>/etc/issue + IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue + [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue + fi echo >>/etc/issue fi exit 0 From 8eb9e77958bb3ad7a0f0500c6851fa938517f0c4 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 31 Jan 2025 15:00:21 +0100 Subject: [PATCH 075/122] Update create_network_ini --- sbin/create_network_ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/create_network_ini b/sbin/create_network_ini index 5643fd321..8bc79ce76 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -246,7 +246,7 @@ if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then # show current IP assignment [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue - if [[ -e /sys/class/net/wlan0 ]] then + if [[ -e /sys/class/net/wlan0 ]]; then echo "Wireless network:" >>/etc/issue IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') From 45f3ea24eb8f50beea1d0be4a37fe56b339d880b Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 31 Jan 2025 15:02:08 +0100 Subject: [PATCH 076/122] Update create_network_ini --- sbin/create_network_ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/create_network_ini b/sbin/create_network_ini index 8bc79ce76..fb5a1bd55 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -235,7 +235,7 @@ if [[ -n $DATA && -e /var/run/nginx.socket ]]; then fi # generate our welcome text (management interface only) -if [[ -z $interface || "eth0 br0 bond0" =~ $interface ]]; then +if [[ -z $interface || "eth0 br0 bond0 wlan0" =~ $interface ]]; then . /etc/unraid-version echo -e "Unraid Server OS version: $version" >/etc/issue # find management interface From 80e60637a9e5dd5dca51482530d1b4d31845e6b4 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 00:40:22 +0100 Subject: [PATCH 077/122] Add wireless monitor in status bar --- .../dynamix/include/DefaultPageLayout.php | 11 +++++++ emhttp/plugins/dynamix/nchan/wlan0 | 29 +++++++++++++++++++ .../dynamix/styles/defaultpagelayout.css | 1 + 3 files changed, 41 insertions(+) create mode 100644 emhttp/plugins/dynamix/nchan/wlan0 diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 2a33a45fc..a9f2086cd 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -20,6 +20,7 @@ $themes2 = in_array($theme,['gray','azure']); $config = "/boot/config"; $entity = $notify['entity'] & 1 == 1; $alerts = '/tmp/plugins/my_alerts.txt'; +$wlan0 = file_exists('/sys/class/net/wlan0'); // adjust the text color in docker log window $fgcolor = in_array($theme,['white','azure']) ? '#1c1c1c' : '#f2f2f2'; @@ -77,6 +78,7 @@ html{font-size:%} ",_('Array Started'),"$progress"; break; } echo ""; +if ($wlan0) echo ""; echo "Unraid® webGui ©2024, Lime Technology, Inc."; echo " "._('manual').""; echo "
"; @@ -924,6 +927,14 @@ defaultPage.on('message', function(msg,meta) { } }); + +var nchan_wlan0 = new NchanSubscriber('/sub/wlan0',{subscriber:'websocket'}); +nchan_wlan0.on('message', function(color) { + $('#wlan0').removeClass().addClass(color); +}); +nchan_wlan0.start(); + + var nchan_plugins = new NchanSubscriber('/sub/plugins',{subscriber:'websocket'}); nchan_plugins.on('message', function(data) { if (!data || openDone(data)) return; diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 new file mode 100644 index 000000000..ebc5e03be --- /dev/null +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -0,0 +1,29 @@ +#!/usr/bin/php -q + + diff --git a/emhttp/plugins/dynamix/styles/defaultpagelayout.css b/emhttp/plugins/dynamix/styles/defaultpagelayout.css index 425744b1f..32471e7f1 100644 --- a/emhttp/plugins/dynamix/styles/defaultpagelayout.css +++ b/emhttp/plugins/dynamix/styles/defaultpagelayout.css @@ -9,3 +9,4 @@ span.big.blue-text{cursor:pointer} span.strong.tour{margin-left:5px;padding-left:0} i.abortOps{font-size:2rem;float:right;margin-right:20px;margin-top:8px;cursor:pointer} pre#swalbody p{margin-block-end:1em} +span#wlan0{float:right;margin-right:10px} \ No newline at end of file From 964598ad72abae4d7c0eeb4c263136c77638b1a5 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 00:40:50 +0100 Subject: [PATCH 078/122] Make script executable --- emhttp/plugins/dynamix/nchan/wlan0 | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 emhttp/plugins/dynamix/nchan/wlan0 diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 old mode 100644 new mode 100755 From 169c03aedf76b553dc710bb924bebf60887d9fd6 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 01:19:08 +0100 Subject: [PATCH 079/122] Code corrections --- emhttp/plugins/dynamix/include/DefaultPageLayout.php | 2 ++ emhttp/plugins/dynamix/include/StartStopPTP.php | 2 +- emhttp/plugins/dynamix/include/Wireless.php | 4 ++-- emhttp/plugins/dynamix/scripts/wireless | 2 +- emhttp/plugins/dynamix/styles/default-black.css | 2 +- emhttp/plugins/dynamix/styles/default-white.css | 2 +- etc/rc.d/rc.wireless | 4 ++-- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index a9f2086cd..5a3816fb9 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -1178,6 +1178,8 @@ $('body').on('click','a,.ca_href', function(e) { } if (href) { href = href.trim(); + // Sanitize href to prevent XSS + href = href.replace(/[<>"]/g, ''); if (href.match('https?://[^\.]*.(my)?unraid.net/') || href.indexOf('https://unraid.net/') == 0 || href == 'https://unraid.net' || href.indexOf('http://lime-technology.com') == 0) { if (ca_href) window.open(href,target); return; diff --git a/emhttp/plugins/dynamix/include/StartStopPTP.php b/emhttp/plugins/dynamix/include/StartStopPTP.php index 553a8a0fe..87f371405 100644 --- a/emhttp/plugins/dynamix/include/StartStopPTP.php +++ b/emhttp/plugins/dynamix/include/StartStopPTP.php @@ -1,4 +1,4 @@ diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 513a03ac9..b1e9eef18 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -35,7 +35,7 @@ require_once "$docroot/webGui/include/Helpers.php"; function scanWifi($port) { $wlan = []; - exec("iw $port scan | grep -P '^BSS|signal:|SSID:|Authentication'",$scan); + exec("iw ".escapeshellarg($port)." scan | grep -P '^BSS|signal:|SSID:|Authentication'",$scan); $n = -1; for ($i=0; $i/dev/null | grep -Pom1 '^\s+psk=\K.+') From a68c1baff383bca51adb3e596814c26593d8c91d Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 10:55:07 +0100 Subject: [PATCH 080/122] Update key management --- emhttp/plugins/dynamix/include/OpenSSL.php | 17 ----------------- emhttp/plugins/dynamix/include/Wireless.php | 2 +- .../plugins/dynamix/include/update.wireless.php | 3 +-- etc/rc.d/rc.ssl.input | 3 +++ etc/rc.d/rc.wireless | 16 ++++++---------- 5 files changed, 11 insertions(+), 30 deletions(-) delete mode 100644 emhttp/plugins/dynamix/include/OpenSSL.php create mode 100644 etc/rc.d/rc.ssl.input diff --git a/emhttp/plugins/dynamix/include/OpenSSL.php b/emhttp/plugins/dynamix/include/OpenSSL.php deleted file mode 100644 index 377c8f2ac..000000000 --- a/emhttp/plugins/dynamix/include/OpenSSL.php +++ /dev/null @@ -1,17 +0,0 @@ - - diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index b1e9eef18..5ba1ed617 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -114,7 +114,7 @@ case 'list': echo json_encode($echo); break; case 'join': - require_once "$docroot/webGui/include/OpenSSL.php"; + extract(parse_ini_file("/etc/rc.d/rc.ssl.input")); $token = parse_ini_file($var)['csrf_token']; $ssid = rawurldecode($_POST['ssid']); $drop = $_POST['task']==1; diff --git a/emhttp/plugins/dynamix/include/update.wireless.php b/emhttp/plugins/dynamix/include/update.wireless.php index 7226b2d7c..80786c3d0 100644 --- a/emhttp/plugins/dynamix/include/update.wireless.php +++ b/emhttp/plugins/dynamix/include/update.wireless.php @@ -11,8 +11,7 @@ */ ?> /dev/null) - [[ -n $PASSWORD ]] && PASSWORD=$(echo $PASSWORD | openssl $(get cipher) -a -d -K $(hex key) -iv $(hex iv) 2>/dev/null) +# get SSL keys + . $SSLINPUT + [[ -n $USERNAME ]] && USERNAME=$(echo $USERNAME | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) + [[ -n $PASSWORD ]] && PASSWORD=$(echo $PASSWORD | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) SECURITY=${SECURITY:-$ATTR3} if [[ -z $SECURITY || ${SECURITY^^} == "OPEN" ]]; then # open network From 788e12a535eec357f95d1fa5e02c530d0e592822 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 11:40:36 +0100 Subject: [PATCH 081/122] Add title and reference to WiFi icon in bottom status bar --- .../dynamix/include/DefaultPageLayout.php | 12 ++++-- emhttp/plugins/dynamix/nchan/wlan0 | 41 +++++++++++++++++-- .../dynamix/styles/defaultpagelayout.css | 2 +- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout.php b/emhttp/plugins/dynamix/include/DefaultPageLayout.php index 5a3816fb9..b8f39ce4a 100644 --- a/emhttp/plugins/dynamix/include/DefaultPageLayout.php +++ b/emhttp/plugins/dynamix/include/DefaultPageLayout.php @@ -823,7 +823,7 @@ default: echo " ",_('Array Started'),"$progress"; break; } echo ""; -if ($wlan0) echo ""; +if ($wlan0) echo ""; echo "Unraid® webGui ©2024, Lime Technology, Inc."; echo " "._('manual').""; echo ""; @@ -928,9 +928,15 @@ defaultPage.on('message', function(msg,meta) { }); +function wlanSettings() { + $.cookie('one','tab'); + window.location = '/Settings/NetworkSettings'; +} + var nchan_wlan0 = new NchanSubscriber('/sub/wlan0',{subscriber:'websocket'}); -nchan_wlan0.on('message', function(color) { - $('#wlan0').removeClass().addClass(color); +nchan_wlan0.on('message', function(msg) { + var wlan = JSON.parse(msg); + $('#wlan0').removeClass().addClass(wlan.color).attr('title',wlan.title); }); nchan_wlan0.start(); diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index ebc5e03be..383693f73 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -13,17 +13,50 @@ ?> diff --git a/emhttp/plugins/dynamix/styles/defaultpagelayout.css b/emhttp/plugins/dynamix/styles/defaultpagelayout.css index 32471e7f1..1621c5a76 100644 --- a/emhttp/plugins/dynamix/styles/defaultpagelayout.css +++ b/emhttp/plugins/dynamix/styles/defaultpagelayout.css @@ -9,4 +9,4 @@ span.big.blue-text{cursor:pointer} span.strong.tour{margin-left:5px;padding-left:0} i.abortOps{font-size:2rem;float:right;margin-right:20px;margin-top:8px;cursor:pointer} pre#swalbody p{margin-block-end:1em} -span#wlan0{float:right;margin-right:10px} \ No newline at end of file +span#wlan0{float:right;margin-right:10px;cursor:pointer} \ No newline at end of file From 76d2c09b68a54d1ec92a0b878a21460b7afe8401 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 11:48:46 +0100 Subject: [PATCH 082/122] Code fixes --- emhttp/plugins/dynamix/include/Wireless.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 5ba1ed617..1fea9b688 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -35,7 +35,7 @@ require_once "$docroot/webGui/include/Helpers.php"; function scanWifi($port) { $wlan = []; - exec("iw ".escapeshellarg($port)." scan | grep -P '^BSS|signal:|SSID:|Authentication'",$scan); + exec("iw ".escapeshellarg($port)." scan | grep -P '^BSS|signal:|SSID:|Authentication suites:'",$scan); $n = -1; for ($i=0; $i"._('IPv6 address').":/"; echo ""._('IPv6 default gateway').":"; echo ""._('IPv6 DNS assignment').":"; echo ""._('DNSv6 server').":"; echo " "; From 81aa739ac52678655a762c05a5e993b8e379265d Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 11:57:25 +0100 Subject: [PATCH 083/122] Code fixes --- emhttp/plugins/dynamix/nchan/wlan0 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index 383693f73..fa5616507 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -41,15 +41,17 @@ function update_translation($locale) { } } -$echo = []; +$echo = []; +$wlan0 = '/sys/class/net/wlan0/carrier' +$ini = '/var/local/emhttp/wireless.ini'; while (true) { extract(parse_plugin_cfg('dynamix',true)); if (_var($display,'locale') != $locale_init) { $locale_init = _var($display,'locale'); update_translation($locale_init); } - if (file_exists('/var/local/emhttp/wireless.ini')) { - $up = file_get_contents('/sys/class/net/wlan0/carrier')==1; + if (file_exists($ini) && file_exists($wlan0)) { + $up = file_get_contents($wlan0)==1; $echo['color'] = $up ? 'blue-text' : 'red-text'; $echo['title'] = $up ? _('WiFi connected') : _('WiFi disconnected'); } else { From 7014d77f1d489dbca02c5a1c2b5551140a699dfe Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 12:21:49 +0100 Subject: [PATCH 084/122] Code fixes --- emhttp/plugins/dynamix/include/Wireless.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 1fea9b688..be37dd17a 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -76,11 +76,12 @@ switch ($cmd) { case 'list': $title = _('Connect to WiFi network'); $port = array_key_first($wifi); + $carrier = "/sys/class/net/$port/carrier"; $wlan = scanWifi($port); $echo = []; $index = 0; if (count(array_column($wlan,'ssid'))) { - $up = file_get_contents("/sys/class/net/$port/carrier") == 1; + $up = file_exists($carrier) && file_get_contents($carrier)==1; $alive = $up ? exec("iw ".escapeshellarg($port)." link | grep -Pom1 'SSID: \K.+'") : ''; $state = $up ? _('Connected') : _('Disconnected'); $color = $up ? 'blue' : 'red'; From 95696b606afa12ba5f0097c1581e7f7ab3cc94fa Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 12:35:25 +0100 Subject: [PATCH 085/122] Update Wireless.php --- emhttp/plugins/dynamix/include/Wireless.php | 1 - 1 file changed, 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index be37dd17a..8fc8de5ad 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -15,7 +15,6 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); $var = '/var/local/emhttp/var.ini'; $cfg = '/boot/config/wireless.cfg'; -$ini = '/var/local/emhttp/wireless.ini'; $tmp = '/var/tmp/attr'; $wifi = (array)@parse_ini_file($cfg,true); $attr = (array)@parse_ini_file($tmp,true); From 5374a363b4fe3ad237e5e27701154c330577f09a Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 15:41:22 +0100 Subject: [PATCH 086/122] security update --- emhttp/plugins/dynamix/include/Wireless.php | 6 +++--- emhttp/plugins/dynamix/nchan/wlan0 | 2 +- etc/rc.d/rc.ssl.input | 3 --- etc/rc.d/rc.wireless | 12 ++++++++++++ 4 files changed, 16 insertions(+), 7 deletions(-) delete mode 100644 etc/rc.d/rc.ssl.input diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 8fc8de5ad..2f5363642 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -114,13 +114,13 @@ case 'list': echo json_encode($echo); break; case 'join': - extract(parse_ini_file("/etc/rc.d/rc.ssl.input")); + extract((array)@parse_ini_file("/etc/rc.d/rc.ssl.input")); $token = parse_ini_file($var)['csrf_token']; $ssid = rawurldecode($_POST['ssid']); $drop = $_POST['task']==1; $manual = $_POST['task']==3; - $user = _var($wifi[$ssid],'USERNAME') ? openssl_decrypt($wifi[$ssid]['USERNAME'],$cipher,$key,0,$iv) : ''; - $passwd = _var($wifi[$ssid],'PASSWORD') ? openssl_decrypt($wifi[$ssid]['PASSWORD'],$cipher,$key,0,$iv) : ''; + $user = _var($wifi[$ssid],'USERNAME') && isset($cipher) ? openssl_decrypt($wifi[$ssid]['USERNAME'],$cipher,$key,0,$iv) : ''; + $passwd = _var($wifi[$ssid],'PASSWORD') && isset($cipher) ? openssl_decrypt($wifi[$ssid]['PASSWORD'],$cipher,$key,0,$iv) : ''; $join = _var($wifi[$ssid],'AUTOJOIN','no'); $dhcp4 = _var($wifi[$ssid],'DHCP4','yes'); $dns4 = _var($wifi[$ssid],'DNS4','no'); diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index fa5616507..7ad24f319 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -42,7 +42,7 @@ function update_translation($locale) { } $echo = []; -$wlan0 = '/sys/class/net/wlan0/carrier' +$wlan0 = '/sys/class/net/wlan0/carrier'; $ini = '/var/local/emhttp/wireless.ini'; while (true) { extract(parse_plugin_cfg('dynamix',true)); diff --git a/etc/rc.d/rc.ssl.input b/etc/rc.d/rc.ssl.input deleted file mode 100644 index a8933c793..000000000 --- a/etc/rc.d/rc.ssl.input +++ /dev/null @@ -1,3 +0,0 @@ -cipher=aes-256-cbc -key=UnraidEncryptionKey -iv=12345678910111213 \ No newline at end of file diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index d8d7bdbc6..f8596feb9 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -172,6 +172,15 @@ wifi_start(){ log "Starting $DAEMON..." local REPLY if [[ -e $SYSTEM/$PORT ]]; then + if [[ ! -e $SSLINPUT ]]; then + [[ -e /boot/config/ident.cfg ]] && KEY=$(grep -Pom1 '^NAME="\K[^"]+' /boot/config/ident.cfg) + [[ -e /boot/config/ident.cfg ]] && IV=$(grep -Pom1 '^timeZone="\K[^"]+' /boot/config/ident.cfg) + KEY="${KEY}ABCDEFGH" + IV="${IV}1234567890123456" + echo "cipher=aes-256-cbc" >$SSLINPUT + echo "key=$KEY" >>$SSLINPUT + echo "iv=${IV:0:16}" >>$SSLINPUT + fi ip link set $PORT up # start active SSID $STARTWIFI @@ -222,6 +231,9 @@ wifi_join(){ fi # get SSL keys . $SSLINPUT + echo $cipher + echo $key + echo $iv [[ -n $USERNAME ]] && USERNAME=$(echo $USERNAME | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) [[ -n $PASSWORD ]] && PASSWORD=$(echo $PASSWORD | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) SECURITY=${SECURITY:-$ATTR3} From 373485256e7907f942113a63dc7c2f09a26615b4 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 16:12:18 +0100 Subject: [PATCH 087/122] improve security --- etc/rc.d/rc.wireless | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index f8596feb9..ebe9474fa 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -10,6 +10,7 @@ DAEMON="WiFi network" CALLER="wifi" INI="/var/local/emhttp/wireless.ini" CFG="/boot/config/wireless.cfg" +IDENT="/boot/config/ident.cfg" SSLINPUT="/etc/rc.d/rc.ssl.input" STARTWIFI="/usr/local/emhttp/webGui/scripts/wireless" WPA="/etc/wpa_supplicant.conf" @@ -41,6 +42,17 @@ unzero6(){ echo -n $(for Q in ${A//:/ }; do [[ $Q != - ]] && printf "$M%x" "0x$Q" || printf ":"; M=:; done) } +# function to initialize openSSL variables +ssl_init(){ + [[ -e $IDENT ]] && KEY=$(grep -Pom1 '^NAME="\K[^"]+' $IDENT) + [[ -e $IDENT ]] && IV=$(grep -Pom1 '^timeZone="\K[^"]+' $IDENT) + KEY="${KEY}ABCDEFGH" + IV="${IV}1234567890123456" + echo "cipher=aes-256-cbc" >$SSLINPUT + echo "key=$KEY" >>$SSLINPUT + echo "iv=${IV:0:16}" >>$SSLINPUT +} + # function to convert text to hex hex(){ echo -n $1 | od -An -tx1 | tr -d ' \n' @@ -172,16 +184,8 @@ wifi_start(){ log "Starting $DAEMON..." local REPLY if [[ -e $SYSTEM/$PORT ]]; then - if [[ ! -e $SSLINPUT ]]; then - [[ -e /boot/config/ident.cfg ]] && KEY=$(grep -Pom1 '^NAME="\K[^"]+' /boot/config/ident.cfg) - [[ -e /boot/config/ident.cfg ]] && IV=$(grep -Pom1 '^timeZone="\K[^"]+' /boot/config/ident.cfg) - KEY="${KEY}ABCDEFGH" - IV="${IV}1234567890123456" - echo "cipher=aes-256-cbc" >$SSLINPUT - echo "key=$KEY" >>$SSLINPUT - echo "iv=${IV:0:16}" >>$SSLINPUT - fi ip link set $PORT up + ssl_init # start active SSID $STARTWIFI if ! carrier_up $PORT; then @@ -229,11 +233,9 @@ wifi_join(){ log "$DAEMON... No configuration." return fi + [[ -e $SSLINPUT ]] || ssl_init # get SSL keys . $SSLINPUT - echo $cipher - echo $key - echo $iv [[ -n $USERNAME ]] && USERNAME=$(echo $USERNAME | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) [[ -n $PASSWORD ]] && PASSWORD=$(echo $PASSWORD | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) SECURITY=${SECURITY:-$ATTR3} From 4059d6f7ef970528380b6cebcfefdf869a0c4293 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 16:27:44 +0100 Subject: [PATCH 088/122] Code fixing --- emhttp/plugins/dynamix/include/Wireless.php | 11 ++++++----- emhttp/plugins/dynamix/include/update.wireless.php | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 2f5363642..68b9a126a 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -15,9 +15,10 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); $var = '/var/local/emhttp/var.ini'; $cfg = '/boot/config/wireless.cfg'; +$ssl = '/etc/rc.d/rc.ssl.input'; $tmp = '/var/tmp/attr'; -$wifi = (array)@parse_ini_file($cfg,true); -$attr = (array)@parse_ini_file($tmp,true); +$wifi = is_readable($cfg) ? (array)parse_ini_file($cfg,true) : []; +$attr = is_readable($tmp) ? (array)parse_ini_file($tmp,true) : []; $md5 = md5(json_encode($attr),true); $cmd = $_POST['cmd']; $masks = [ @@ -114,13 +115,13 @@ case 'list': echo json_encode($echo); break; case 'join': - extract((array)@parse_ini_file("/etc/rc.d/rc.ssl.input")); + if (is_readable($ssl)) extract(parse_ini_file($ssl)); $token = parse_ini_file($var)['csrf_token']; $ssid = rawurldecode($_POST['ssid']); $drop = $_POST['task']==1; $manual = $_POST['task']==3; - $user = _var($wifi[$ssid],'USERNAME') && isset($cipher) ? openssl_decrypt($wifi[$ssid]['USERNAME'],$cipher,$key,0,$iv) : ''; - $passwd = _var($wifi[$ssid],'PASSWORD') && isset($cipher) ? openssl_decrypt($wifi[$ssid]['PASSWORD'],$cipher,$key,0,$iv) : ''; + $user = _var($wifi[$ssid],'USERNAME') && isset($cipher,$key,$iv) ? openssl_decrypt($wifi[$ssid]['USERNAME'],$cipher,$key,0,$iv) : _var($wifi[$ssid],'USERNAME'); + $passwd = _var($wifi[$ssid],'PASSWORD') && isset($cipher,$key,$iv) ? openssl_decrypt($wifi[$ssid]['PASSWORD'],$cipher,$key,0,$iv) : _var($wifi[$ssid],'PASSWORD'); $join = _var($wifi[$ssid],'AUTOJOIN','no'); $dhcp4 = _var($wifi[$ssid],'DHCP4','yes'); $dns4 = _var($wifi[$ssid],'DNS4','no'); diff --git a/emhttp/plugins/dynamix/include/update.wireless.php b/emhttp/plugins/dynamix/include/update.wireless.php index 80786c3d0..898f4b163 100644 --- a/emhttp/plugins/dynamix/include/update.wireless.php +++ b/emhttp/plugins/dynamix/include/update.wireless.php @@ -11,11 +11,12 @@ */ ?> $val) if (isset($val['GROUP'])) $keys[$key]['GROUP'] = 'saved'; From d5e611d8e30488583e3910dc069e36d6f4c29c5a Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 17:29:25 +0100 Subject: [PATCH 089/122] Update rc.wireless --- etc/rc.d/rc.wireless | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index ebe9474fa..3cd2f454f 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -233,7 +233,7 @@ wifi_join(){ log "$DAEMON... No configuration." return fi - [[ -e $SSLINPUT ]] || ssl_init + ssl_init # get SSL keys . $SSLINPUT [[ -n $USERNAME ]] && USERNAME=$(echo $USERNAME | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) From cce3a423014af3e60aa302da60a5ca60c4e158ee Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 17:43:10 +0100 Subject: [PATCH 090/122] Revert "Update rc.wireless" This reverts commit d5e611d8e30488583e3910dc069e36d6f4c29c5a. --- etc/rc.d/rc.wireless | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index 3cd2f454f..ebe9474fa 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -233,7 +233,7 @@ wifi_join(){ log "$DAEMON... No configuration." return fi - ssl_init + [[ -e $SSLINPUT ]] || ssl_init # get SSL keys . $SSLINPUT [[ -n $USERNAME ]] && USERNAME=$(echo $USERNAME | openssl $cipher -a -d -K $(hex $key) -iv $(hex $iv) 2>/dev/null) From efc1a747a4e4714e636c66052d7b84039e27013c Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 18:07:51 +0100 Subject: [PATCH 091/122] security update --- etc/rc.d/rc.wireless | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index ebe9474fa..8c290fef8 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -10,7 +10,6 @@ DAEMON="WiFi network" CALLER="wifi" INI="/var/local/emhttp/wireless.ini" CFG="/boot/config/wireless.cfg" -IDENT="/boot/config/ident.cfg" SSLINPUT="/etc/rc.d/rc.ssl.input" STARTWIFI="/usr/local/emhttp/webGui/scripts/wireless" WPA="/etc/wpa_supplicant.conf" @@ -44,10 +43,8 @@ unzero6(){ # function to initialize openSSL variables ssl_init(){ - [[ -e $IDENT ]] && KEY=$(grep -Pom1 '^NAME="\K[^"]+' $IDENT) - [[ -e $IDENT ]] && IV=$(grep -Pom1 '^timeZone="\K[^"]+' $IDENT) - KEY="${KEY}ABCDEFGH" - IV="${IV}1234567890123456" + KEY="$(dmidecode -qt1 | grep -Pom1 'Manufacturer: \K.+')ABCDEFGH" + IV="$(dmidecode -qt1 | grep -Pom1 'Product Name: \K.+')1234567890123456" echo "cipher=aes-256-cbc" >$SSLINPUT echo "key=$KEY" >>$SSLINPUT echo "iv=${IV:0:16}" >>$SSLINPUT From 1e29ccbdaa191dd79b7fcaa589d3425be44b3639 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 18:09:08 +0100 Subject: [PATCH 092/122] security update --- etc/rc.d/rc.wireless | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index 8c290fef8..31b5f2d6d 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -46,7 +46,7 @@ ssl_init(){ KEY="$(dmidecode -qt1 | grep -Pom1 'Manufacturer: \K.+')ABCDEFGH" IV="$(dmidecode -qt1 | grep -Pom1 'Product Name: \K.+')1234567890123456" echo "cipher=aes-256-cbc" >$SSLINPUT - echo "key=$KEY" >>$SSLINPUT + echo "key=${KEY:0:63}" >>$SSLINPUT echo "iv=${IV:0:16}" >>$SSLINPUT } From f669191c4fff7865b85ecd2faae80fc05c59c5fd Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 18:31:53 +0100 Subject: [PATCH 093/122] security update --- etc/rc.d/rc.wireless | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index 31b5f2d6d..b5d5d1eec 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -43,8 +43,8 @@ unzero6(){ # function to initialize openSSL variables ssl_init(){ - KEY="$(dmidecode -qt1 | grep -Pom1 'Manufacturer: \K.+')ABCDEFGH" - IV="$(dmidecode -qt1 | grep -Pom1 'Product Name: \K.+')1234567890123456" + KEY="$(dmidecode -qt1 | grep -Pom1 'Manufacturer: \K.+' | sed 's/ /_/g')ABCDEFGH" + IV="$(dmidecode -qt1 | grep -Pom1 'Product Name: \K.+' | sed 's/ /_/g')1234567890123456" echo "cipher=aes-256-cbc" >$SSLINPUT echo "key=${KEY:0:63}" >>$SSLINPUT echo "iv=${IV:0:16}" >>$SSLINPUT From 444912543a32c1ee43cf704c83cae76cc3c35b7b Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 18:43:05 +0100 Subject: [PATCH 094/122] Make join more resilient --- etc/rc.d/rc.wireless | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index b5d5d1eec..1c01646ff 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -245,6 +245,7 @@ wifi_join(){ else # WPA encryption wpa_configuration "$SECURITY" + [[ -n $(pgrep wpa_supplicant) ]] && pkill wpa_supplicant wpa_supplicant -B -i $PORT -c $WPA fi # IPv4 address assignment From f28808e0954a186be337cd1bd1c3d38a468b007f Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 19:22:32 +0100 Subject: [PATCH 095/122] Better update services control --- emhttp/plugins/dynamix/scripts/wireless | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/emhttp/plugins/dynamix/scripts/wireless b/emhttp/plugins/dynamix/scripts/wireless index b35e1b253..c91c2ae5b 100755 --- a/emhttp/plugins/dynamix/scripts/wireless +++ b/emhttp/plugins/dynamix/scripts/wireless @@ -21,7 +21,7 @@ $cfg = '/boot/config/wireless.cfg'; $wifi = is_file($cfg) ? (array)parse_ini_file($cfg,true) : []; $port = array_key_first($wifi); $text = ["PORT=\"$port\""]; -$renew = false; + if (!$arg) { foreach ($wifi as $network => $block) { if ($network == $port) continue; @@ -29,7 +29,6 @@ if (!$arg) { $text[] = "SSID=\"$network\""; unset($block['GROUP']); foreach ($block as $key => $value) $text[] = "$key=\"$value\""; - if ($block['DHCP4']=='no' || $block['DHCP6']=='no') $renew = true; } } } elseif (!in_array($arg,['no','yes'])) { @@ -39,16 +38,18 @@ if (!$arg) { $text[] = "SSID=\"$network\""; unset($block['GROUP']); foreach ($block as $key => $value) $text[] = "$key=\"$value\""; - if ($block['DHCP4']=='no' || $block['DHCP6']=='no') $renew = true; } } } -exec("/etc/rc.d/rc.wireless stop"); if ($arg == 'yes') { exec("/etc/rc.d/rc.wireless start &>/dev/null &"); +} elseif ($arg == 'no') { + exec("/etc/rc.d/rc.wireless stop"); + exec("$docroot/webGui/scripts/update_services 5"); } elseif (count($text)>2) { + exec("/etc/rc.d/rc.wireless stop"); file_put_contents_atomic($ini,implode("\n",$text)."\n"); exec("/etc/rc.d/rc.wireless join &>/dev/null &"); - if ($renew) exec("/usr/local/emhttp/webGui/scripts/update_services 25"); + exec("$docroot/webGui/scripts/update_services 20"); } ?> From 19bf71530a7f43be675c3ab348608ce650854efc Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 19:42:15 +0100 Subject: [PATCH 096/122] Code refacturing --- emhttp/plugins/dynamix/scripts/wireless | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/emhttp/plugins/dynamix/scripts/wireless b/emhttp/plugins/dynamix/scripts/wireless index c91c2ae5b..e1187c037 100755 --- a/emhttp/plugins/dynamix/scripts/wireless +++ b/emhttp/plugins/dynamix/scripts/wireless @@ -16,31 +16,22 @@ $docroot = $_SERVER['DOCUMENT_ROOT'] ?: "/usr/local/emhttp"; require_once "$docroot/plugins/dynamix/include/Wrappers.php"; $arg = $argv[1] ?? ''; +$state = $arg ? 'saved' : 'active'; $ini = '/var/local/emhttp/wireless.ini'; $cfg = '/boot/config/wireless.cfg'; $wifi = is_file($cfg) ? (array)parse_ini_file($cfg,true) : []; $port = array_key_first($wifi); $text = ["PORT=\"$port\""]; -if (!$arg) { - foreach ($wifi as $network => $block) { - if ($network == $port) continue; - if ($block['GROUP'] == 'active') { - $text[] = "SSID=\"$network\""; - unset($block['GROUP']); - foreach ($block as $key => $value) $text[] = "$key=\"$value\""; - } - } -} elseif (!in_array($arg,['no','yes'])) { - foreach ($wifi as $network => $block) { - if ($network == $port) continue; - if ($block['GROUP'] == 'saved' && $network == $arg) { - $text[] = "SSID=\"$network\""; - unset($block['GROUP']); - foreach ($block as $key => $value) $text[] = "$key=\"$value\""; - } +if (!in_array($arg,['no','yes'])) foreach ($wifi as $network => $block) { + if ($network == $port) continue; + if ($block['GROUP'] == $state && (!$arg || $arg == $network)) { + $text[] = "SSID=\"$network\""; + unset($block['GROUP']); + foreach ($block as $key => $value) $text[] = "$key=\"$value\""; } } + if ($arg == 'yes') { exec("/etc/rc.d/rc.wireless start &>/dev/null &"); } elseif ($arg == 'no') { From 48d708e7385ae9e7a8883b57c1ce5256c1e0a1d5 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 19:45:16 +0100 Subject: [PATCH 097/122] Code refacturing --- emhttp/plugins/dynamix/scripts/wireless | 29 +++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/emhttp/plugins/dynamix/scripts/wireless b/emhttp/plugins/dynamix/scripts/wireless index e1187c037..2b522f62f 100755 --- a/emhttp/plugins/dynamix/scripts/wireless +++ b/emhttp/plugins/dynamix/scripts/wireless @@ -23,24 +23,25 @@ $wifi = is_file($cfg) ? (array)parse_ini_file($cfg,true) : []; $port = array_key_first($wifi); $text = ["PORT=\"$port\""]; -if (!in_array($arg,['no','yes'])) foreach ($wifi as $network => $block) { - if ($network == $port) continue; - if ($block['GROUP'] == $state && (!$arg || $arg == $network)) { - $text[] = "SSID=\"$network\""; - unset($block['GROUP']); - foreach ($block as $key => $value) $text[] = "$key=\"$value\""; - } -} - if ($arg == 'yes') { exec("/etc/rc.d/rc.wireless start &>/dev/null &"); } elseif ($arg == 'no') { exec("/etc/rc.d/rc.wireless stop"); exec("$docroot/webGui/scripts/update_services 5"); -} elseif (count($text)>2) { - exec("/etc/rc.d/rc.wireless stop"); - file_put_contents_atomic($ini,implode("\n",$text)."\n"); - exec("/etc/rc.d/rc.wireless join &>/dev/null &"); - exec("$docroot/webGui/scripts/update_services 20"); +} else { + foreach ($wifi as $network => $block) { + if ($network == $port) continue; + if ($block['GROUP'] == $state && (!$arg || $arg == $network)) { + $text[] = "SSID=\"$network\""; + unset($block['GROUP']); + foreach ($block as $key => $value) $text[] = "$key=\"$value\""; + } + } + if (count($text)>2) { + exec("/etc/rc.d/rc.wireless stop"); + file_put_contents_atomic($ini,implode("\n",$text)."\n"); + exec("/etc/rc.d/rc.wireless join &>/dev/null &"); + exec("$docroot/webGui/scripts/update_services 20"); + } } ?> From 3fb353548443ed58c42b2ca18291bc003b8cb7bd Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 20:07:42 +0100 Subject: [PATCH 098/122] Update rc.library.source --- etc/rc.d/rc.library.source | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/rc.d/rc.library.source b/etc/rc.d/rc.library.source index 9b6f309a1..99861be3b 100644 --- a/etc/rc.d/rc.library.source +++ b/etc/rc.d/rc.library.source @@ -4,7 +4,8 @@ # # Library used by nfsd, ntpd, rpc, samba, nginx, sshd, avahidaemon, show_interfaces # -# Bergware - created for Unraid OS, December 2024 +# Bergware - created for Unraid OS, December 2023 +# Bergware - updated January 2025 WIREGUARD="/etc/wireguard" NETWORK_INI="/var/local/emhttp/network.ini" From f6d8532dd683fc8c08f1205df58a142bd046b6f2 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 20:08:53 +0100 Subject: [PATCH 099/122] Update DateTime.page --- emhttp/plugins/dynamix/DateTime.page | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DateTime.page b/emhttp/plugins/dynamix/DateTime.page index b3a5af9e1..6edddfdeb 100644 --- a/emhttp/plugins/dynamix/DateTime.page +++ b/emhttp/plugins/dynamix/DateTime.page @@ -4,8 +4,8 @@ Icon="icon-clock" Tag="clock-o" --- Date: Sat, 1 Feb 2025 20:12:01 +0100 Subject: [PATCH 100/122] Update DashboardApps.php --- emhttp/plugins/dynamix/include/DashboardApps.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DashboardApps.php b/emhttp/plugins/dynamix/include/DashboardApps.php index aa49190a6..c976a0ea6 100644 --- a/emhttp/plugins/dynamix/include/DashboardApps.php +++ b/emhttp/plugins/dynamix/include/DashboardApps.php @@ -1,6 +1,6 @@ domain_get_icon_url($res); switch ($state) { case 'running': From 945c91c21d962779b23d1d7bdbbe0593cf77d2d6 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 1 Feb 2025 20:18:00 +0100 Subject: [PATCH 101/122] Revert "Update DashboardApps.php" This reverts commit e560c0458a48b70e0f3293434cfdecee634d93b0. --- emhttp/plugins/dynamix/include/DashboardApps.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix/include/DashboardApps.php b/emhttp/plugins/dynamix/include/DashboardApps.php index c976a0ea6..aa49190a6 100644 --- a/emhttp/plugins/dynamix/include/DashboardApps.php +++ b/emhttp/plugins/dynamix/include/DashboardApps.php @@ -1,6 +1,6 @@ domain_get_icon_url($res); switch ($state) { case 'running': From 1bb791f7ec2ab5ee66378eaacc451729406ae558 Mon Sep 17 00:00:00 2001 From: bergware Date: Sun, 2 Feb 2025 18:43:00 +0100 Subject: [PATCH 102/122] Make dashboard view permanent across browsers - settings are now saved on flash instead of cookies --- emhttp/plugins/dynamix/DashStats.page | 239 ++++++++++++------ emhttp/plugins/dynamix/default.cfg | 1 + emhttp/plugins/dynamix/include/InitCharts.php | 8 +- 3 files changed, 163 insertions(+), 85 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index b50fed0f6..beb2474cc 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -55,25 +55,25 @@ exec("sed -ri 's/^\.logLine\{color:#......;/.logLine{color:$fgcolor;/' $docroot/ exec("/etc/rc.d/rc.docker status >/dev/null",$dummy,$dockerd); exec("/etc/rc.d/rc.libvirt status >/dev/null",$dummy,$libvirtd); -$dockerd = $dockerd==0; -$libvirtd = $libvirtd==0; -$apcupsd = file_exists('/var/run/apcupsd.pid'); -$conf = glob('/etc/wireguard/wg*.conf'); -$wireguard = is_executable('/usr/bin/wg') && count($conf); -$started = _var($var,'fsState')=='Started'; -$sleep = isset($display['sleep']); +$dockerd = $dockerd==0; +$libvirtd = $libvirtd==0; +$apcupsd = file_exists('/var/run/apcupsd.pid'); +$cookie = '/boot/config/cookie.json'; +$conf = glob('/etc/wireguard/wg*.conf'); +$wireguard = is_executable('/usr/bin/wg') && count($conf); +$started = _var($var,'fsState')=='Started'; +$sleep = isset($display['sleep']); $poolsOnly = (_var($var,'SYS_ARRAY_SLOTS') == 0 ) ? true : false; $array_size = $array_used = 0; $extra_size = $extra_used = 0; $cache_size = $cache_used = []; $cache_type = $cache_rate = []; - -$parity = _var($var,'mdResync'); -$mover = file_exists('/var/run/mover.pid'); -$btrfs = exec('pgrep --ns $$ -cf /sbin/btrfs'); -$vdisk = exec("grep -Pom1 '^DOCKER_IMAGE_TYPE=\"\\K[^\"]+' /boot/config/docker.cfg 2>/dev/null")!='folder' ? _('Docker vdisk') : _('Docker folder'); -$dot = _var($display,'number','.,')[0]; -$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';})); +$parity = _var($var,'mdResync'); +$mover = file_exists('/var/run/mover.pid'); +$btrfs = exec('pgrep --ns $$ -cf /sbin/btrfs'); +$vdisk = exec("grep -Pom1 '^DOCKER_IMAGE_TYPE=\"\\K[^\"]+' /boot/config/docker.cfg 2>/dev/null")!='folder' ? _('Docker vdisk') : _('Docker folder'); +$dot = _var($display,'number','.,')[0]; +$zfs = count(array_filter(array_column($disks,'fsType'),function($fs){return str_replace('luks:','',$fs??'')=='zfs';})); $domain_cfgfile = "/boot/config/domain.cfg"; $domain_cfg = parse_ini_file($domain_cfgfile); @@ -673,10 +673,11 @@ function hideShow() { if (count['db-box2']>0) $('div#tile2').show(); else $('div#tile2').hide(); if (count['db-box3']>0) $('div#tile3').show(); else $('div#tile3').hide(); if (inactive.length>0) { - $.cookie('inactive_content',inactive.join(';'),{expires:3650}); + cookie.inactive_content = inactive.join(';'); } else { - $.removeCookie('inactive_content'); + delete cookie.inactive_content; } + saveCookie(); }
@@ -753,8 +754,8 @@ String.prototype.md5 = function(){ return rh(a)+rh(b)+rh(c)+rh(d); } jQuery.prototype.hideMe = function() { - var hidden = $.cookie('hidden_content'); - hidden = hidden==null ? [] : hidden.split(';'); + var hidden = cookie.hidden_content; + hidden = hidden ? hidden.split(';') : []; if (hidden.indexOf(this.attr('sort'))>=0) this.find('tr:gt(0)').hide(); } jQuery.prototype.mixedView = function(s) { @@ -779,29 +780,12 @@ jQuery.prototype.mixedView = function(s) { }); } } -function sanitizeMultiCookie(cookieName, delimiter, removeDuplicates = false) { - // Some browser states leave multi-value cookies with nulls, empties or duplicates. - // This function cleans up any such cookies so that they do not break functionality. - try { - var uncleanCookie = $.cookie(cookieName); - if (uncleanCookie) { - uncleanCookie = uncleanCookie.split(delimiter); - var cleanCookie = uncleanCookie.filter(n => n); - if (removeDuplicates) { cleanCookie = [...new Set(cleanCookie)]; } - if (JSON.stringify(uncleanCookie) !== JSON.stringify(cleanCookie)) { - $.cookie(cookieName,cleanCookie.join(delimiter),{expires:3650}); - return true; - } else { - return false; - } - } else { - return false; - } - } catch (ex) { - return false; - } -} + +var cookie = JSON.parse(''); + +var cookie = {}; + var colors = ['','','#d77e0d','#d4ac0d','#cd5c5c','#ffc0cb','#e6e6fa','#9370db','#7cfc00','#228b22','#00ffff','#4682b4']; var blue = '#486dba'; // fallback color when too many graph elements exist var ports = []; @@ -810,8 +794,8 @@ var rxd = []; var txd = []; var cputime = 0; var nettime = 0; -var cpuline = $.cookie('cpuline')||30; -var netline = $.cookie('netline')||30; +var cpuline = cookie.cpuline||30; +var netline = cookie.netline||30; var update2 = true; var box = null; var startup = true; @@ -849,8 +833,38 @@ var options_net = { var cpuchart = new ApexCharts(document.querySelector('#cpuchart'), options_cpu); var netchart = new ApexCharts(document.querySelector('#netchart'), options_net); -if ($.cookie('port_select')!=null && !ports.includes($.cookie('port_select'))) $.removeCookie('port_select'); -var port_select = $.cookie('port_select')||ports[0]; +if (cookie.port_select!=null && !ports.includes(cookie.port_select)) { + delete cookie.port_select; + saveCookie(); +} +var port_select = cookie.port_select||ports[0]; + +function saveCookie() { + $.post('/webGui/include/InitCharts.php',{cmd:'cookie',data:JSON.stringify(cookie)}); +} + +function sanitizeMultiCookie(cookieName, delimiter, removeDuplicates=false) { + // Some browser states leave multi-value cookies with nulls, empties or duplicates. + // This function cleans up any such cookies so that they do not break functionality. + try { + var uncleanCookie = $.cookie(cookieName); + if (uncleanCookie) { + uncleanCookie = uncleanCookie.split(delimiter); + var cleanCookie = uncleanCookie.filter(n => n); + if (removeDuplicates) { cleanCookie = [...new Set(cleanCookie)]; } + if (JSON.stringify(uncleanCookie) !== JSON.stringify(cleanCookie)) { + $.cookie(cookieName,cleanCookie.join(delimiter),{expires:3650}); + return true; + } else { + return false; + } + } else { + return false; + } + } catch (ex) { + return false; + } +} function initCharts(clear) { $.post('/webGui/include/InitCharts.php',{cmd:'get'},function(data) { @@ -879,12 +893,14 @@ function initCharts(clear) { nettime = x + 1; }); } + function resetCharts() { // prevent unlimited graph growing cpu = cpu.slice(-cpuline); rxd = rxd.slice(-netline); txd = txd.slice(-netline); } + function addChartCpu(load) { cputime++; var i = cpu.length - cpuline; @@ -895,6 +911,7 @@ function addChartCpu(load) { } cpu.push({x:cputime, y:load}); } + function addChartNet(rx, tx) { nettime++; var i = rxd.length - netline; @@ -908,6 +925,7 @@ function addChartNet(rx, tx) { rxd.push({x:nettime, y:rx}); txd.push({x:nettime, y:tx}); } + function toggleVPN(id,vtun) { var up = $('#vpn-active'); @@ -928,23 +946,28 @@ function toggleVPN(id,vtun) { } } + function noApps() { if ($('span.outer.apps:visible').length==0) $('#no_apps').show(); else $('#no_apps').hide(); } + function noVMs() { if ($('span.outer.vms:visible').length==0) $('#no_vms').show(); else $('#no_vms').hide(); } + function loadlist(init) { if (init) { - $('#apps').switchButton({labels_placement:'right', off_label:"_(All Apps)_", on_label:"_(Started only)_", checked:$.cookie('my_apps')=='startedOnly'}); - $('#vms').switchButton({labels_placement:'right', off_label:"_(All VMs)_", on_label:"_(Started only)_", checked:$.cookie('my_vms')=='startedOnly'}); + $('#apps').switchButton({labels_placement:'right', off_label:"_(All Apps)_", on_label:"_(Started only)_", checked:cookie.my_apps=='startedOnly'}); + $('#vms').switchButton({labels_placement:'right', off_label:"_(All VMs)_", on_label:"_(Started only)_", checked:cookie.my_vms=='startedOnly'}); $('#apps').change(function(){ $('span.outer.apps.stopped').finish().toggle('fast',function(){noApps();}) - $('#apps').is(':checked') ? $.cookie('my_apps','startedOnly',{expires:3650}) : $.removeCookie('my_apps'); + $('#apps').is(':checked') ? cookie.my_apps = 'startedOnly' : delete cookie.my_apps; + saveCookie(); }); $('#vms').change(function(){ $('span.outer.vms.stopped').finish().toggle('fast',function(){noVMs();}); - $('#vms').is(':checked') ? $.cookie('my_vms','startedOnly',{expires:3650}) : $.removeCookie('my_vms'); + $('#vms').is(':checked') ? cookie.my_vms = 'startedOnly' : delete cookie.my_vms; + saveCookie(); }); } $.post('/webGui/include/DashboardApps.php',{docker:'',vms:'',vmusage:''},function(d) { @@ -963,10 +986,11 @@ function loadlist(init) { $('#vm_view_usage').append(data[2]).hideMe(); $('.apps.switch').html("_(Containers)_ -- _(Started)_: "+started_apps+", _(Stopped)_: "+stopped_apps+", _(Paused)_: "+paused_apps); $('.vms.switch').html("_(VMs)_ -- _(Started)_: "+started_vms+", _(Stopped)_: "+stopped_vms+", _(Paused)_: "+paused_vms); - if ($.cookie('my_apps')!=null) $('span.apps.stopped').hide(0,noApps()); - if ($.cookie('my_vms')!=null) $('span.vms.stopped').hide(0,noVMs()); + if (cookie.my_apps!=null) $('span.apps.stopped').hide(0,noApps()); + if (cookie.my_vms!=null) $('span.vms.stopped').hide(0,noVMs()); }); } + function getCase() { $.post('/webGui/include/SelectCase.php',{mode:'get',file:''},function(model){ if (!model) { @@ -979,8 +1003,10 @@ function getCase() { } }); } + function changeMode(item) { - if (item==0) $.removeCookie('enter_share'); else $.cookie('enter_share',item,{expires:3650}); + if (item==0) delete cookie.enter_share; else cookie.enter_share = item; + saveCookie(); if (startup || $('.smb.share1').parent().find('tr:eq(1)').is(':visible')) { if (item==0) $('.smb.share1').show(); else $('.smb.share1').hide(); @@ -999,23 +1025,30 @@ function changeMode(item) { $('select[name="enter_user"]').val(item); } + function changeView(item) { - if (item==0) $.removeCookie('enter_view'); else $.cookie('enter_view',item,{expires:3650}); + if (item==0) delete cookie.enter_view; else cookie.enter_view = item; if (item==0) $('.view1').show(); else $('.view1').hide(); if (item==1) $('.view2').show(); else $('.view2').hide(); if (item==2) $('.view3').show(); else $('.view3').hide(); if (item==3) $('.view4').show(); else $('.view4').hide(); + saveCookie(); } + function changeCPUline(val) { cpuline = val; - if (val==30) $.removeCookie('cpuline'); else $.cookie('cpuline',val,{expires:3650}); + if (val==30) delete cookie.cpuline; else cookie.cpuline = val; + saveCookie(); cpuchart.updateOptions({xaxis:{range:cpuline-1}}); } + function changeNetline(val) { netline = val; - if (val==30) $.removeCookie('netline'); else $.cookie('netline',val,{expires:3650}); + if (val==30) delete cookie.netline; else cookie.netline = val; + saveCookie(); netchart.updateOptions({xaxis:{range:netline-1}}); } + function smartMenu(table) { $(table).find('[id^="smart-"]').each(function() { var opts = []; @@ -1037,6 +1070,7 @@ function smartMenu(table) { context.attach(id,opts); }); } + function portMenu() { var select = 'select[name="port_select"]'; var option = $(select+' option'); @@ -1044,11 +1078,14 @@ function portMenu() { if (option[i].value == port_select) {option[i].selected = true; break;} } } + function portSelect(name) { - $.cookie('port_select',name,{expires:3650}); + cookie.port_select = name; + saveCookie(); initCharts(true); port_select = name; } + function moreInfo(data,table) { var info = []; if (data[1]>0) info.push(data[1]+' '+(data[1]==1 ? "_(device warning)_" : "_(device warnings)_")); @@ -1057,6 +1094,7 @@ function moreInfo(data,table) { if (data[4]>0) info.push(data[4]+' '+(data[4]==1 ? "_(utilization warning)_" : "_(utilization warnings)_")); return info.length ? "
"+table+" _(has)_ "+info.join('. ')+".
" : ""; } + function autoscale(value,text,size,kilo) { if (kilo==null) kilo = 1000; var unit = kilo==1024 ? ['','ki','Mi','Gi','Ti','Pi','Ei'] : ['','k','M','G','T','P','E']; @@ -1066,42 +1104,50 @@ function autoscale(value,text,size,kilo) { if (data==0) base=0; return ((Math.round(scale*data)/scale)+' '+unit[base]+text).replace(".",""); } + function update900() { // prevent chart overflowing, reset every 15 minutes resetCharts(); setTimeout(update900,900000); } + function attributes(page,disk) { var tab = page=='New' ? 'tab2' : 'tab3'; $.cookie('one',tab); location.replace('/Dashboard/'+page+'?name='+disk); } + function capabilities(page,disk) { var tab = page=='New' ? 'tab3' : 'tab4'; $.cookie('one',tab); location.replace('/Dashboard/'+page+'?name='+disk); } + function identity(page,disk) { var tab = page=='New' ? 'tab4' : 'tab5'; $.cookie('one',tab); location.replace('/Dashboard/'+page+'?name='+disk); } + function acknowledge(id,disk) { $.post('/webGui/include/Acknowledge.php',{disk:disk},function(){ $(id).removeClass('fa-thumbs-o-down orange-text').addClass('fa-thumbs-o-up green-text');$(id.replace('smart','text')).text(""); }); } + function dropdown(menu) { var select = 'select[name="'+menu+'"]'; var size = $(select+' option').length; - var option = $.cookie(menu)||0; + var option = cookie[menu]||0; if (option >= size) option = 0; $(select+' option')[option].selected = true; $(select).change(); } + function toggleCPU(init) { - if (!init) {if ($.cookie('cpu')==null) $.cookie('cpu','close',{expires:3650}); else $.removeCookie('cpu');} - if ($.cookie('cpu')==null) { + if (!init) {if (!cookie.cpu) cookie.cpu = 'close'; else delete cookie.cpu;} + saveCookie(); + if (!cookie.cpu) { $('.cpu_open').show(); $('.cpu_close').text("_(Hide details)_"); } else { @@ -1110,13 +1156,15 @@ function toggleCPU(init) { } setTimeout(function(){toggleChart(true);}); } + function toggleChart(init) { - if (!init) {if ($.cookie('cpu-chart')==null) $.cookie('cpu-chart','close',{expires:3650}); else $.removeCookie('cpu-chart');} + if (!init) {if (!cookie.cpu_chart) cookie.cpu_chart = 'close'; else delete cookie.cpu_chart;} + saveCookie(); $('#cpu_main').removeClass('last'); $('.cpu_open:last').removeClass('last'); - if ($.cookie('cpu-chart')==null) { - var hidden = $.cookie('hidden_content'); - hidden = hidden==null ? [] : hidden.split(';'); + if (!cookie.cpu_chart) { + var hidden = cookie.hidden_content; + hidden = hidden ? hidden.split(';') : []; if (hidden.indexOf($('#cpu_main').parent().attr('sort'))==-1) { $('#cpu_chart').show(); $('#cpuline').show(); @@ -1130,6 +1178,7 @@ function toggleChart(init) { if ($('.cpu_open').is(':visible')) $('.cpu_open:last').addClass('last'); else $('#cpu_main').addClass('last'); } } + function StopArray() { swal({title:"_(Proceed)_?",text:"_(This will stop the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){StopArrayNow();}); @@ -1137,10 +1186,12 @@ function StopArray() { StopArrayNow(); } + function StopArrayNow() { $('span.hand').prop('onclick',null).off('click').addClass('busy').css({'cursor':'default'}); $.post('/update.htm',{startState:'', cmdStop:'Stop'},function(){refresh();}); } + function StartArray() { swal({title:"_(Proceed)_?",text:"_(This will start the array)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){StartArrayNow();}); @@ -1148,10 +1199,12 @@ function StartArray() { StartArrayNow(); } + function StartArrayNow() { $('span.hand').prop('onclick',null).off('click').addClass('busy').css({'cursor':'default'}); $.post('/update.htm',{startState:'', cmdStart:'Start'},function(){refresh();}); } + function Reboot() { swal({title:"_(Proceed)_?",text:"_(This will reboot the system)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){RebootNow();}); @@ -1159,10 +1212,12 @@ function Reboot() { RebootNow(); } + function RebootNow() { document.boot.cmd.value = 'reboot'; document.boot.submit(); } + function Shutdown() { swal({title:"_(Proceed)_?",text:"_(This will shutdown the system)_",type:'warning',html:true,showCancelButton:true,confirmButtonText:"_(Proceed)_",cancelButtonText:"_(Cancel)_"},function(){ShutdownNow();}); @@ -1170,10 +1225,12 @@ function Shutdown() { ShutdownNow(); } + function ShutdownNow() { document.boot.cmd.value = 'shutdown'; document.boot.submit(); } + function Sleep() { @@ -1182,16 +1239,17 @@ function Sleep() { SleepNow(); } + function SleepNow() { $('#statusraid').append(' • System in sleep mode'); $.get('/plugins/dynamix.s3.sleep/include/SleepMode.php',function(){refresh();}); } + function sortTables() { $('table.dashboard').each(function(){ var table = $(this); - sanitizeMultiCookie(table.prop('id'), ';', true); - var index = $.cookie(table.prop('id')); + var index = cookie[table.prop('id')]; // sorting list exists if (index != null) { index = index.split(';'); @@ -1211,6 +1269,7 @@ function sortTables() { }); $('table.dashboard tbody').before(stopgap); } + function addProperties() { $('div.frame tbody.system').addClass('sortable').attr('sort','_system_information_'.md5()); $('div.frame tbody.system').find('td:first').prepend(""); @@ -1233,10 +1292,10 @@ function addProperties() { function(){if ($(this)[0].offsetWidth < $(this)[0].scrollWidth) {recall.html(recover); recall=null;}} ); } + function showContent() { var count = {'db-box1':$('table#db-box1 tbody').length, 'db-box2':$('table#db-box2 tbody').length, 'db-box3':$('table#db-box3 tbody').length} - sanitizeMultiCookie('inactive_content', ';', true); - var inactive = $.cookie('inactive_content'); + var inactive = cookie.inactive_content; if (inactive) { inactive = inactive.split(';'); for (let n=0,md5; md5=inactive[n]; n++) { @@ -1247,8 +1306,7 @@ function showContent() { tbody.prev().hide(); } } - sanitizeMultiCookie('hidden_content', ';', true); - var hidden = $.cookie('hidden_content'); + var hidden = cookie.hidden_content; if (hidden) { hidden = hidden.split(';'); for (let n=0,md5; md5=hidden[n]; n++) { @@ -1263,21 +1321,24 @@ function showContent() { if (count['db-box2']>0) $('div#tile2').show(); if (count['db-box3']>0) $('div#tile3').show(); } + function setColor(l, t1, t2) { switch (true) { case (t1 > 0 && l >= t1): return 'redbar'; case (t2 > 0 && l >= t2): return 'orangebar'; default: return '';} } + function fontColor(l, t1, t2) { switch (true) { case (t1 > 0 && l >= t1): return '#f0000c'; case (t2 > 0 && l >= t2): return '#e68a00'; default: return '#4f8a10';} } + function openClose(button) { - var hidden = $.cookie('hidden_content'); - hidden = hidden==null ? [] : hidden.split(';'); + var hidden = cookie.hidden_content; + hidden = hidden ? hidden.split(';') : []; if (button) { // show/hide single tile content var tbody = button.closest('tbody'); @@ -1290,7 +1351,8 @@ function openClose(button) { tbody.mixedView(1); hidden.splice(hidden.indexOf(tbody.attr('sort')),1); } - $.cookie('hidden_content',hidden.join(';'),{expires:3650}); + cookie.hidden_content = hidden.join(';'); + saveCookie(); } else { // show/hide all tiles content if (hidden.length==0) { @@ -1299,34 +1361,40 @@ function openClose(button) { $(this).mixedView(0); hidden.push($(this).attr('sort')); }); - $.cookie('hidden_content',hidden.join(';'),{expires:3650}); + cookie.hidden_content = hidden.join(';'); + saveCookie(); } else { $('div.frame tbody').each(function(){ $(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up'); $(this).mixedView(1); }); - $.removeCookie('hidden_content'); + delete cookie.hidden_content; + saveCookie(); } } } + function dismiss(button) { var tbody = button.closest('tbody'); var table = tbody.parent(); var tile = table.parent(); - var inactive = $.cookie('inactive_content'); + var inactive = cookie.inactive_content; tbody.hide(); tbody.prev().hide(); if (table.find('tbody:visible').length>0) tile.show(); else tile.hide(); - inactive = inactive==null ? [] : inactive.split(';'); + inactive = inactive ? inactive.split(';') : []; inactive.push(tbody.attr('sort')); - $.cookie('inactive_content',inactive.join(';'),{expires:3650}); + cookie.inactive_content = inactive.join(';'); + saveCookie(); } + function dialogStyle() { $('.ui-dialog-titlebar-close').css({'display':'none'}); $('.ui-dialog-title').css({'text-align':'center','width':'100%','font-size':'1.8rem'}); $('.ui-dialog-content').css({'padding-top':'15px','vertical-align':'bottom'}); $('.ui-button-text').css({'padding':'0px 5px'}); } + function contentMgmt() { box = $("#iframe-popup"); box.html($("#templateContentMgmt").html().build()); @@ -1338,11 +1406,12 @@ function contentMgmt() { modal: true, buttons: { "_(Reset)_": function(){ - $.removeCookie('db-box1'); - $.removeCookie('db-box2'); - $.removeCookie('db-box3'); - $.removeCookie('inactive_content'); - $.removeCookie('hidden_content'); + delete cookie['db-box1']; + delete cookie['db-box2']; + delete cookie['db-box3']; + delete cookie.inactive_content; + delete cookie.hidden_content; + saveCookie(); box.dialog('close'); location.reload(); }, @@ -1363,6 +1432,7 @@ function contentMgmt() { }); dialogStyle(); } + function VMClone(uuid, name){ box = $("#iframe-popup"); box.html($("#templateClone").html()); @@ -1399,6 +1469,7 @@ function VMClone(uuid, name){ }); dialogStyle(); } + function selectsnapshot(uuid, name ,snaps, opt, getlist, state,fstype){ box = $("#iframe-popup"); box.html($("#templatesnapshot"+opt).html()); @@ -1500,13 +1571,14 @@ function LockButton() { gap.hide(); } table.find('tbody').each(function(){index.push($(this).attr('sort'));}); - $.cookie(table.prop('id'),index.join(';'),{expires:3650}); + cookie[table.prop('id')] = index.join(';'); }, stop:function(e,ui){ var table = ui.item.parent(), index = []; if (ui.item.prev().html().search('stopgap')>0) ui.item.after(stopgap); else ui.item.before(stopgap); table.find('tbody').each(function(){index.push($(this).attr('sort'));}); - $.cookie(table.prop('id'),index.join(';'),{expires:3650}); + cookie[table.prop('id')] = index.join(';'); + saveCookie(); }}); } else { $.removeCookie('lockbutton'); @@ -1690,6 +1762,7 @@ dashboard.on('message',function(msg,meta) { break; } }); + var apcups = new NchanSubscriber('/sub/apcups',{subscriber:'websocket'}); apcups.on('message',function(msg) { diff --git a/emhttp/plugins/dynamix/default.cfg b/emhttp/plugins/dynamix/default.cfg index 500f5fa32..9096beced 100644 --- a/emhttp/plugins/dynamix/default.cfg +++ b/emhttp/plugins/dynamix/default.cfg @@ -34,6 +34,7 @@ rtl="" headermetacolor="" headerdescription="yes" showBannerGradient="yes" +favorites="yes" [parity] mode="0" hour="0 0" diff --git a/emhttp/plugins/dynamix/include/InitCharts.php b/emhttp/plugins/dynamix/include/InitCharts.php index e341a0fa6..4576fc5ae 100644 --- a/emhttp/plugins/dynamix/include/InitCharts.php +++ b/emhttp/plugins/dynamix/include/InitCharts.php @@ -1,6 +1,6 @@ From 9d0e4ccc19ce51658e6d32d76985773af6a4773f Mon Sep 17 00:00:00 2001 From: bergware Date: Sun, 2 Feb 2025 20:27:44 +0100 Subject: [PATCH 103/122] Update DashStats.page --- emhttp/plugins/dynamix/DashStats.page | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index beb2474cc..37b4718c0 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -198,7 +198,7 @@ switch ($theme) {
- +
";
-


@@ -412,7 +412,7 @@ echo "
+
_(Docker Containers)_
@@ -574,7 +574,7 @@ if (!$group) {
- +
",i.document[0]).appendTo(t)):"tr"===n?i._createTrPlaceholder(i.currentItem,t):"img"===n&&t.attr("src",i.currentItem.attr("src")),s||t.css("visibility","hidden"),t},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()&&(!o.forcePlaceholderSize||"tbody"!==n&&"tr"!==n)||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width()||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10)))}}),i.placeholder=V(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){V("",i.document[0]).attr("colspan",V(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,n,o,a,r,l,h,c=null,u=null,d=this.containers.length-1;0<=d;d--)V.contains(this.currentItem[0],this.containers[d].element[0])||(this._intersectsWith(this.containers[d].containerCache)?c&&V.contains(this.containers[d].element[0],c.element[0])||(c=this.containers[d],u=d):this.containers[d].containerCache.over&&(this.containers[d]._trigger("out",t,this._uiHash(this)),this.containers[d].containerCache.over=0));if(c)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(i=1e4,s=null,n=(l=c.floating||this._isFloating(this.currentItem))?"left":"top",o=l?"width":"height",h=l?"pageX":"pageY",e=this.items.length-1;0<=e;e--)V.contains(this.containers[u].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(a=this.items[e].item.offset()[n],r=!1,t[h]-a>this.items[e][o]/2&&(r=!0),Math.abs(t[h]-a)this.containment[2]&&(i=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(s=this.containment[3]+this.offset.click.top)),e.grid&&(t=this.originalPageY+Math.round((s-this.originalPageY)/e.grid[1])*e.grid[1],s=!this.containment||t-this.offset.click.top>=this.containment[1]&&t-this.offset.click.top<=this.containment[3]?t:t-this.offset.click.top>=this.containment[1]?t-e.grid[1]:t+e.grid[1],t=this.originalPageX+Math.round((i-this.originalPageX)/e.grid[0])*e.grid[0],i=!this.containment||t-this.offset.click.left>=this.containment[0]&&t-this.offset.click.left<=this.containment[2]?t:t-this.offset.click.left>=this.containment[0]?t-e.grid[0]:t+e.grid[0])),{top:s-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop()),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function n(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;0<=i;i--)e||s.push(n("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(n("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var s=this._super(),n=this.element;return V.each(["min","max","step"],function(t,e){var i=n.attr(e);null!=i&&i.length&&(s[e]=i)}),s},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){this.cancelBlur?delete this.cancelBlur:(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t))},mousewheel:function(t,e){var i=V.ui.safeActiveElement(this.document[0]);if(this.element[0]===i&&e){if(!this.spinning&&!this._start(t))return!1;this._spin((0").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&0e.max?e.max:null!==e.min&&t"},_buttonHtml:function(){return""}});var ct;V.ui.spinner;V.widget("ui.tabs",{version:"1.13.2",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:(ct=/#.*$/,function(t){var e=t.href.replace(ct,""),i=location.href.replace(ct,"");try{e=decodeURIComponent(e)}catch(t){}try{i=decodeURIComponent(i)}catch(t){}return 1?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,e=this.tablist.children(":has(a[href])");t.disabled=V.map(e.filter(".ui-state-disabled"),function(t){return e.index(t)}),this._processTabs(),!1!==t.active&&this.anchors.length?this.active.length&&!V.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=V()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=V()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var l=this,t=this.tabs,e=this.anchors,i=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(t){V(this).is(".ui-state-disabled")&&t.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){V(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return V("a",this)[0]}).attr({tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=V(),this.anchors.each(function(t,e){var i,s,n,o=V(e).uniqueId().attr("id"),a=V(e).closest("li"),r=a.attr("aria-controls");l._isLocal(e)?(n=(i=e.hash).substring(1),s=l.element.find(l._sanitizeSelector(i))):(n=a.attr("aria-controls")||V({}).uniqueId()[0].id,(s=l.element.find(i="#"+n)).length||(s=l._createPanel(n)).insertAfter(l.panels[t-1]||l.tablist),s.attr("aria-live","polite")),s.length&&(l.panels=l.panels.add(s)),r&&a.data("ui-tabs-aria-controls",r),a.attr({"aria-controls":n,"aria-labelledby":o}),s.attr("aria-labelledby",o)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),t&&(this._off(t.not(this.tabs)),this._off(e.not(this.anchors)),this._off(i.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(t){return V("
").attr("id",t).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(t){var e,i;for(Array.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1),i=0;e=this.tabs[i];i++)e=V(e),!0===t||-1!==V.inArray(i,t)?(e.attr("aria-disabled","true"),this._addClass(e,null,"ui-state-disabled")):(e.removeAttr("aria-disabled"),this._removeClass(e,null,"ui-state-disabled"));this.options.disabled=t,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!0===t)},_setupEvents:function(t){var i={};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,e=this.element.parent();"fill"===t?(i=e.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=V(this).outerHeight(!0)}),this.panels.each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,V(this).height("").height())}).height(i))},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget).closest("li"),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():this._getPanelForTab(s),r=i.length?this._getPanelForTab(i):V(),i={oldTab:i,oldPanel:r,newTab:o?V():s,newPanel:a};t.preventDefault(),s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||n&&!e.collapsible||!1===this._trigger("beforeActivate",t,i)||(e.active=!o&&this.tabs.index(s),this.active=n?V():s,this.xhr&&this.xhr.abort(),r.length||a.length||V.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,i))},_toggle:function(t,e){var i=this,s=e.newPanel,n=e.oldPanel;function o(){i.running=!1,i._trigger("activate",t,e)}function a(){i._addClass(e.newTab.closest("li"),"ui-tabs-active","ui-state-active"),s.length&&i.options.show?i._show(s,i.options.show,o):(s.show(),o())}this.running=!0,n.length&&this.options.hide?this._hide(n,this.options.hide,function(){i._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),a()}):(this._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n.hide(),a()),n.attr("aria-hidden","true"),e.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),s.length&&n.length?e.oldTab.attr("tabIndex",-1):s.length&&this.tabs.filter(function(){return 0===V(this).attr("tabIndex")}).attr("tabIndex",-1),s.attr("aria-hidden","false"),e.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var t=this._findActive(t);t[0]!==this.active[0]&&(t=(t=!t.length?this.active:t).find(".ui-tabs-anchor")[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return!1===t?V():this.tabs.eq(t)},_getIndex:function(t){return t="string"==typeof t?this.anchors.index(this.anchors.filter("[href$='"+V.escapeSelector(t)+"']")):t},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){V.data(this,"ui-tabs-destroy")?V(this).remove():V(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var t=V(this),e=t.data("ui-tabs-aria-controls");e?t.attr("aria-controls",e).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var t=this.options.disabled;!1!==t&&(t=void 0!==i&&(i=this._getIndex(i),Array.isArray(t)?V.map(t,function(t){return t!==i?t:null}):V.map(this.tabs,function(t,e){return e!==i?e:null})),this._setOptionDisabled(t))},disable:function(t){var e=this.options.disabled;if(!0!==e){if(void 0===t)e=!0;else{if(t=this._getIndex(t),-1!==V.inArray(t,e))return;e=Array.isArray(e)?V.merge([t],e).sort():[t]}this._setOptionDisabled(e)}},load:function(t,s){t=this._getIndex(t);function n(t,e){"abort"===e&&o.panels.stop(!1,!0),o._removeClass(i,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===o.xhr&&delete o.xhr}var o=this,i=this.tabs.eq(t),t=i.find(".ui-tabs-anchor"),a=this._getPanelForTab(i),r={tab:i,panel:a};this._isLocal(t[0])||(this.xhr=V.ajax(this._ajaxSettings(t,s,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(i,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,i){setTimeout(function(){a.html(t),o._trigger("load",s,r),n(i,e)},1)}).fail(function(t,e){setTimeout(function(){n(t,e)},1)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href").replace(/#.*$/,""),beforeSend:function(t,e){return n._trigger("beforeLoad",i,V.extend({jqXHR:t,ajaxSettings:e},s))}}},_getPanelForTab:function(t){t=V(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+t))}}),!1!==V.uiBackCompat&&V.widget("ui.tabs",V.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}});V.ui.tabs;V.widget("ui.tooltip",{version:"1.13.2",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var t=V(this).attr("title");return V("").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(t,e){var i=(t.attr("aria-describedby")||"").split(/\s+/);i.push(e),t.data("ui-tooltip-id",e).attr("aria-describedby",String.prototype.trim.call(i.join(" ")))},_removeDescribedBy:function(t){var e=t.data("ui-tooltip-id"),i=(t.attr("aria-describedby")||"").split(/\s+/),e=V.inArray(e,i);-1!==e&&i.splice(e,1),t.removeData("ui-tooltip-id"),(i=String.prototype.trim.call(i.join(" ")))?t.attr("aria-describedby",i):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=V("
").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=V([])},_setOption:function(t,e){var i=this;this._super(t,e),"content"===t&&V.each(this.tooltips,function(t,e){i._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur");i.target=i.currentTarget=e.element[0],s.close(i,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var t=V(this);if(t.is("[title]"))return t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")}))},_enable:function(){this.disabledTitles.each(function(){var t=V(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))}),this.disabledTitles=V([])},open:function(t){var i=this,e=V(t?t.target:this.element).closest(this.options.items);e.length&&!e.data("ui-tooltip-id")&&(e.attr("title")&&e.data("ui-tooltip-title",e.attr("title")),e.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&e.parents().each(function(){var t,e=V(this);e.data("ui-tooltip-open")&&((t=V.Event("blur")).target=t.currentTarget=this,i.close(t,!0)),e.attr("title")&&(e.uniqueId(),i.parents[this.id]={element:this,title:e.attr("title")},e.attr("title",""))}),this._registerCloseHandlers(t,e),this._updateContent(e,t))},_updateContent:function(e,i){var t=this.options.content,s=this,n=i?i.type:null;if("string"==typeof t||t.nodeType||t.jquery)return this._open(i,e,t);(t=t.call(e[0],function(t){s._delay(function(){e.data("ui-tooltip-open")&&(i&&(i.type=n),this._open(i,e,t))})}))&&this._open(i,e,t)},_open:function(t,e,i){var s,n,o,a=V.extend({},this.options.position);function r(t){a.of=t,n.is(":hidden")||n.position(a)}i&&((s=this._find(e))?s.tooltip.find(".ui-tooltip-content").html(i):(e.is("[title]")&&(t&&"mouseover"===t.type?e.attr("title",""):e.removeAttr("title")),s=this._tooltip(e),n=s.tooltip,this._addDescribedBy(e,n.attr("id")),n.find(".ui-tooltip-content").html(i),this.liveRegion.children().hide(),(i=V("
").html(n.find(".ui-tooltip-content").html())).removeAttr("name").find("[name]").removeAttr("name"),i.removeAttr("id").find("[id]").removeAttr("id"),i.appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:r}),r(t)):n.position(V.extend({of:e},this.options.position)),n.hide(),this._show(n,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(o=this.delayedShow=setInterval(function(){n.is(":visible")&&(r(a.of),clearInterval(o))},13)),this._trigger("open",t,{tooltip:n})))},_registerCloseHandlers:function(t,e){var i={keyup:function(t){t.keyCode===V.ui.keyCode.ESCAPE&&((t=V.Event(t)).currentTarget=e[0],this.close(t,!0))}};e[0]!==this.element[0]&&(i.remove=function(){var t=this._find(e);t&&this._removeTooltip(t.tooltip)}),t&&"mouseover"!==t.type||(i.mouseleave="close"),t&&"focusin"!==t.type||(i.focusout="close"),this._on(!0,e,i)},close:function(t){var e,i=this,s=V(t?t.currentTarget:this.element),n=this._find(s);n?(e=n.tooltip,n.closing||(clearInterval(this.delayedShow),s.data("ui-tooltip-title")&&!s.attr("title")&&s.attr("title",s.data("ui-tooltip-title")),this._removeDescribedBy(s),n.hiding=!0,e.stop(!0),this._hide(e,this.options.hide,function(){i._removeTooltip(V(this))}),s.removeData("ui-tooltip-open"),this._off(s,"mouseleave focusout keyup"),s[0]!==this.element[0]&&this._off(s,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&V.each(this.parents,function(t,e){V(e.element).attr("title",e.title),delete i.parents[t]}),n.closing=!0,this._trigger("close",t,{tooltip:e}),n.hiding||(n.closing=!1))):s.removeData("ui-tooltip-open")},_tooltip:function(t){var e=V("
").attr("role","tooltip"),i=V("
").appendTo(e),s=e.uniqueId().attr("id");return this._addClass(i,"ui-tooltip-content"),this._addClass(e,"ui-tooltip","ui-widget ui-widget-content"),e.appendTo(this._appendTo(t)),this.tooltips[s]={element:t,tooltip:e}},_find:function(t){t=t.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(t){clearInterval(this.delayedShow),t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){t=t.closest(".ui-front, dialog");return t=!t.length?this.document[0].body:t},_destroy:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur"),e=e.element;i.target=i.currentTarget=e[0],s.close(i,!0),V("#"+t).remove(),e.data("ui-tooltip-title")&&(e.attr("title")||e.attr("title",e.data("ui-tooltip-title")),e.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),!1!==V.uiBackCompat&&V.widget("ui.tooltip",V.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}});V.ui.tooltip}); +(t=>{"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(V){V.ui=V.ui||{};V.ui.version="1.14.1";var n,s,x,k,o,a,r,l,h,i,E=0,N=Array.prototype.hasOwnProperty,c=Array.prototype.slice;V.cleanData=(n=V.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=V._data(i,"events"))&&e.remove&&V(i).triggerHandler("remove");n(t)}),V.widget=function(t,i,e){var s,n,o,a,r={},l=t.split(".")[0];return"__proto__"===(t=t.split(".")[1])||"constructor"===t?V.error("Invalid widget name: "+t):(a=l+"-"+t,e||(e=i,i=V.Widget),Array.isArray(e)&&(e=V.extend.apply(null,[{}].concat(e))),V.expr.pseudos[a.toLowerCase()]=function(t){return!!V.data(t,a)},V[l]=V[l]||{},s=V[l][t],n=V[l][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},V.extend(n,s,{version:e.version,_proto:V.extend({},e),_childConstructors:[]}),(o=new i).options=V.widget.extend({},o.options),V.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}r[e]="function"!=typeof s?s:function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}}),n.prototype=V.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},r,{constructor:n,namespace:l,widgetName:t,widgetFullName:a}),s?(V.each(s._childConstructors,function(t,e){var i=e.prototype;V.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),V.widget.bridge(t,n),n)},V.widget.extend=function(t){for(var e,i,s=c.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=V(e||this.defaultElement||this)[0],this.element=V(e),this.uuid=E++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=V(),this.hoverable=V(),this.focusable=V(),this.classesElementLookup={},e!==this&&(V.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=V(e.style?e.ownerDocument:e.document||e),this.window=V(this.document[0].defaultView||this.document[0].parentWindow)),this.options=V.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:V.noop,_create:V.noop,_init:V.noop,destroy:function(){var i=this;this._destroy(),V.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:V.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return V.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=V.widget.extend({},this.options[t]),n=0;n{var i=[];n.element.each(function(t,e){V.map(a.classesElementLookup,function(t){return t}).some(function(t){return t.is(e)})||i.push(e)}),a._on(V(i),{remove:"_untrackClassesElement"})})(),V(V.uniqueSort(i.get().concat(n.element.get())))):V(i.not(n.element).get()),a.classesElementLookup[t[s]]=i,o.push(t[s]),e&&n.classes[t[s]]&&o.push(n.classes[t[s]])}return(n=V.extend({element:this.element,classes:this.options.classes||{}},n)).keys&&t(n.keys.match(/\S+/g)||[],!0),n.extra&&t(n.extra.match(/\S+/g)||[]),o.join(" ")},_untrackClassesElement:function(i){var s=this;V.each(s.classesElementLookup,function(t,e){-1!==V.inArray(i.target,e)&&(s.classesElementLookup[t]=V(e.not(i.target).get()))}),this._off(V(i.target))},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){var n="string"==typeof t||null===t,e={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s="boolean"==typeof s?s:i};return e.element.toggleClass(this._classes(e),s),this},_on:function(n,o,t){var a,r=this;"boolean"!=typeof n&&(t=o,o=n,n=!1),t?(o=a=V(o),this.bindings=this.bindings.add(o)):(t=o,o=this.element,a=this.widget()),V.each(t,function(t,e){function i(){if(n||!0!==r.options.disabled&&!V(this).hasClass("ui-state-disabled"))return("string"==typeof e?r[e]:e).apply(r,arguments)}"string"!=typeof e&&(i.guid=e.guid=e.guid||i.guid||V.guid++);var t=t.match(/^([\w:-]*)\s*(.*)$/),s=t[1]+r.eventNamespace,t=t[2];t?a.on(s,t,i):o.on(s,i)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.off(e),this.bindings=V(this.bindings.not(t).get()),this.focusable=V(this.focusable.not(t).get()),this.hoverable=V(this.hoverable.not(t).get())},_delay:function(t,e){var i=this;return setTimeout(function(){return("string"==typeof t?i[t]:t).apply(i,arguments)},e||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){this._addClass(V(t.currentTarget),null,"ui-state-hover")},mouseleave:function(t){this._removeClass(V(t.currentTarget),null,"ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){this._addClass(V(t.currentTarget),null,"ui-state-focus")},focusout:function(t){this._removeClass(V(t.currentTarget),null,"ui-state-focus")}})},_trigger:function(t,e,i){var s,n,o=this.options[t];if(i=i||{},(e=V.Event(e)).type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),e.target=this.element[0],n=e.originalEvent)for(s in n)s in e||(e[s]=n[s]);return this.element.trigger(e,i),!("function"==typeof o&&!1===o.apply(this.element[0],[e].concat(i))||e.isDefaultPrevented())}},V.each({show:"fadeIn",hide:"fadeOut"},function(o,a){V.Widget.prototype["_"+o]=function(e,t,i){var s,n=(t="string"==typeof t?{effect:t}:t)?!0!==t&&"number"!=typeof t&&t.effect||a:o;"number"==typeof(t=t||{})?t={duration:t}:!0===t&&(t={}),s=!V.isEmptyObject(t),t.complete=i,t.delay&&e.delay(t.delay),s&&V.effects&&V.effects.effect[n]?e[o](t):n!==o&&e[n]?e[n](t.duration,t.easing,i):e.queue(function(t){V(this)[o](),i&&i.call(e[0]),t()})}}),V.widget;function C(t,e,i){return[parseFloat(t[0])*(h.test(t[0])?e/100:1),parseFloat(t[1])*(h.test(t[1])?i/100:1)]}function D(t,e){return parseInt(V.css(t,e),10)||0}function I(t){return null!=t&&t===t.window}x=Math.max,k=Math.abs,o=/left|center|right/,a=/top|center|bottom/,r=/[\+\-]\d+(\.[\d]+)?%?/,l=/^\w+/,h=/%$/,i=V.fn.position,V.position={scrollbarWidth:function(){var t,e,i;return void 0!==s?s:(i=(e=V("
")).children()[0],V("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i)},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(k(s),k(n))?o.important="horizontal":o.important="vertical",u.using.call(this,t,o)}),a.offset(V.extend(h,{using:t}))})):i.apply(this,arguments)},V.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,s=s.width,o=t.left-e.collisionPosition.marginLeft,a=n-o,r=o+e.collisionWidth-s-n;s=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),V.ui.plugin={add:function(t,e,i){var s,n=V.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n").css("position","absolute").appendTo(t.parent()).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(t){var e=this.document[0].activeElement;V(t.target).closest(e).length||V(e).trigger("blur")},_mouseStart:function(t){var e=this.options;return this.helper=this._createHelper(t),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),V.ui.ddmanager&&(V.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=0i[2]&&(o=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3])&&(a=i[3]+this.offset.click.top),s.grid&&(e=s.grid[1]?this.originalPageY+Math.round((a-this.originalPageY)/s.grid[1])*s.grid[1]:this.originalPageY,a=!i||e-this.offset.click.top>=i[1]||e-this.offset.click.top>i[3]?e:e-this.offset.click.top>=i[1]?e-s.grid[1]:e+s.grid[1],t=s.grid[0]?this.originalPageX+Math.round((o-this.originalPageX)/s.grid[0])*s.grid[0]:this.originalPageX,o=!i||t-this.offset.click.left>=i[0]||t-this.offset.click.left>i[2]?t:t-this.offset.click.left>=i[0]?t-s.grid[0]:t+s.grid[0]),"y"===s.axis&&(o=this.originalPageX),"x"===s.axis)?this.originalPageY:a)-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:n?0:this.offset.scroll.top),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:n?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(t,e,i){return i=i||this._uiHash(),V.ui.plugin.call(this,t,[e,i,this],!0),/^(drag|start|stop)/.test(t)&&(this.positionAbs=this._convertPositionTo("absolute"),i.offset=this.positionAbs),V.Widget.prototype._trigger.call(this,t,e,i)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),V.ui.plugin.add("draggable","connectToSortable",{start:function(e,t,i){var s=V.extend({},t,{item:i.element});i.sortables=[],V(i.options.connectToSortable).each(function(){var t=V(this).sortable("instance");t&&!t.options.disabled&&(i.sortables.push(t),t.refreshPositions(),t._trigger("activate",e,s))})},stop:function(e,t,i){var s=V.extend({},t,{item:i.element});i.cancelHelperRemoval=!1,V.each(i.sortables,function(){var t=this;t.isOver?(t.isOver=0,i.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,s))})},drag:function(i,s,n){V.each(n.sortables,function(){var t=!1,e=this;e.positionAbs=n.positionAbs,e.helperProportions=n.helperProportions,e.offset.click=n.offset.click,e._intersectsWith(e.containerCache)&&(t=!0,V.each(n.sortables,function(){return this.positionAbs=n.positionAbs,this.helperProportions=n.helperProportions,this.offset.click=n.offset.click,t=this!==e&&this._intersectsWith(this.containerCache)&&V.contains(e.element[0],this.element[0])?!1:t})),t?(e.isOver||(e.isOver=1,n._parent=s.helper.parent(),e.currentItem=s.helper.appendTo(e.element).data("ui-sortable-item",!0),e.options._helper=e.options.helper,e.options.helper=function(){return s.helper[0]},i.target=e.currentItem[0],e._mouseCapture(i,!0),e._mouseStart(i,!0,!0),e.offset.click.top=n.offset.click.top,e.offset.click.left=n.offset.click.left,e.offset.parent.left-=n.offset.parent.left-e.offset.parent.left,e.offset.parent.top-=n.offset.parent.top-e.offset.parent.top,n._trigger("toSortable",i),n.dropped=e.element,V.each(n.sortables,function(){this.refreshPositions()}),n.currentItem=n.element,e.fromOutside=n),e.currentItem&&(e._mouseDrag(i),s.position=e.position)):e.isOver&&(e.isOver=0,e.cancelHelperRemoval=!0,e.options._revert=e.options.revert,e.options.revert=!1,e._trigger("out",i,e._uiHash(e)),e._mouseStop(i,!0),e.options.revert=e.options._revert,e.options.helper=e.options._helper,e.placeholder&&e.placeholder.remove(),s.helper.appendTo(n._parent),n._refreshOffsets(i),s.position=n._generatePosition(i,!0),n._trigger("fromSortable",i),n.dropped=!1,V.each(n.sortables,function(){this.refreshPositions()}))})}}),V.ui.plugin.add("draggable","cursor",{start:function(t,e,i){var s=V("body"),i=i.options;s.css("cursor")&&(i._cursor=s.css("cursor")),s.css("cursor",i.cursor)},stop:function(t,e,i){i=i.options;i._cursor&&V("body").css("cursor",i._cursor)}}),V.ui.plugin.add("draggable","opacity",{start:function(t,e,i){e=V(e.helper),i=i.options;e.css("opacity")&&(i._opacity=e.css("opacity")),e.css("opacity",i.opacity)},stop:function(t,e,i){i=i.options;i._opacity&&V(e.helper).css("opacity",i._opacity)}}),V.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(t,e,i){var s=i.options,n=!1,o=i.scrollParentNotHidden[0],a=i.document[0];o!==a&&"HTML"!==o.tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+o.offsetHeight-t.pageY
").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this._proportionallyResize()),this._setupHandles(),e.autoHide&&V(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){V(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,a=this;if(this.handles=o.handles||(V(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=V(),this._addedHandles=V(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=V(this.handles[e]),this._on(this.handles[e],{mousedown:a._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=V(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?s.outerHeight():s.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=V(this.handles[e])[0])!==t.target&&!V.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s,n=this.options,o=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),n.containment&&(e+=V(n.containment).scrollLeft()||0,i+=V(n.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this._helper||(s=this._calculateAdjustedElementDimensions(o)),this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:s.width,height:s.height},this.originalSize=this._helper?{width:o.outerWidth(),height:o.outerHeight()}:{width:s.width,height:s.height},this.sizeDiff={width:o.outerWidth()-o.width(),height:o.outerHeight()-o.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof n.aspectRatio?n.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=V(".ui-resizable-"+this.axis).css("cursor"),V("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(i=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),V.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(i=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,e=e?0:o.sizeDiff.width,e={width:o.helper.width()-e,height:o.helper.height()-i},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(V.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper)&&!n.animate&&this._proportionallyResize(),V("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.helper.css(t),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px",this.helper.width(t.width)),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px",this.helper.height(t.height)),t},_updateVirtualBoundaries:function(t){var e,i,s,n=this.options,n={minWidth:this._isNumber(n.minWidth)?n.minWidth:0,maxWidth:this._isNumber(n.maxWidth)?n.maxWidth:1/0,minHeight:this._isNumber(n.minHeight)?n.minHeight:0,maxHeight:this._isNumber(n.maxHeight)?n.maxHeight:1/0};(this._aspectRatio||t)&&(t=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,e=n.maxHeight*this.aspectRatio,s=n.maxWidth/this.aspectRatio,n.minWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,l=this.originalPosition.top+this.originalSize.height,h=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&h&&(t.left=r-e.minWidth),s&&h&&(t.left=r-e.maxWidth),a&&i&&(t.top=l-e.minHeight),n&&i&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_calculateAdjustedElementDimensions:function(t){var e,i,s=t.get(0);return"content-box"!==t.css("box-sizing")||!this._hasScroll(s)&&!this._hasScroll(s,"left")?{height:parseFloat(t.css("height")),width:parseFloat(t.css("width"))}:(e=parseFloat(s.style.width),s=parseFloat(s.style.height),i=this._getPaddingPlusBorderDimensions(t),e=isNaN(e)?this._getElementTheoreticalSize(t,i,"width"):e,{height:isNaN(s)?this._getElementTheoreticalSize(t,i,"height"):s,width:e})},_getElementTheoreticalSize:function(t,e,i){return Math.max(0,Math.ceil(t.get(0)["offset"+i[0].toUpperCase()+i.slice(1)]-e[i]-.5))||0},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e
").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return V.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return V.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){V.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),V.ui.plugin.add("resizable","animate",{stop:function(e){var i=V(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,n=n?0:i.sizeDiff.width,n={width:i.size.width-n,height:i.size.height-o},o=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,a=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(V.extend(n,a&&o?{top:a,left:o}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&V(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),V.ui.plugin.add("resizable","containment",{start:function(){var i,s,t,e,n=V(this).resizable("instance"),o=n.options,a=n.element,o=o.containment,a=o instanceof V?o.get(0):/parent/.test(o)?a.parent().get(0):o;a&&(n.containerElement=V(a),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:V(document),left:0,top:0,width:V(document).width(),height:V(document).height()||document.body.parentNode.scrollHeight}):(i=V(a),s=[],V(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},o=n.containerOffset,e=n.containerSize.height,t=n.containerSize.width,t=n._hasScroll(a,"left")?a.scrollWidth:t,e=n._hasScroll(a)?a.scrollHeight:e,n.parentData={element:a,left:o.left,top:o.top,width:t,height:e}))},resize:function(t){var e=V(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,t=e._aspectRatio||t.shiftKey,o={top:0,left:0},a=e.containerElement,r=!0;a[0]!==document&&/static/.test(a.css("position"))&&(o=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-o.left),t&&(e.size.height=e.size.width/e.aspectRatio,r=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),t&&(e.size.width=e.size.height*e.aspectRatio,r=!1),e.position.top=e._helper?s.top:0),a=e.containerElement.get(0)===e.element.parent().get(0),i=/relative|absolute/.test(e.containerElement.css("position")),a&&i?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-o.left:e.offset.left-s.left)),a=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-o.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,t)&&(e.size.height=e.size.width/e.aspectRatio,r=!1),a+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-a,t)&&(e.size.width=e.size.height*e.aspectRatio,r=!1),r||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=V(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=V(t.helper),a=o.offset(),r=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&V(this).css({left:a.left-s.left-i.left,width:r,height:o})}}),V.ui.plugin.add("resizable","alsoResize",{start:function(){var i=V(this).resizable("instance"),t=i.options;V(t.alsoResize).each(function(){var t=V(this),e=i._calculateAdjustedElementDimensions(t);t.data("ui-resizable-alsoresize",{width:e.width,height:e.height,left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=V(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,a={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};V(s.alsoResize).each(function(){var t=V(this),s=V(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];V.each(e,function(t,e){var i=(s[e]||0)+(a[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){V(this).removeData("ui-resizable-alsoresize")}}),V.ui.plugin.add("resizable","ghost",{start:function(){var t=V(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!0===V.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=V(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=V(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),V.ui.plugin.add("resizable","grid",{resize:function(){var t,e=V(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,l=r[0]||1,h=r[1]||1,c=Math.round((s.width-n.width)/l)*l,s=Math.round((s.height-n.height)/h)*h,u=n.width+c,d=n.height+s,p=i.maxWidth&&i.maxWidthu,m=i.minHeight&&i.minHeight>d;i.grid=r,g&&(u+=l),m&&(d+=h),p&&(u-=l),f&&(d-=h),/^(se|s|e)$/.test(a)?(e.size.width=u,e.size.height=d):/^(ne)$/.test(a)?(e.size.width=u,e.size.height=d,e.position.top=o.top-s):/^(sw)$/.test(a)?(e.size.width=u,e.size.height=d,e.position.left=o.left-c):((d-h<=0||u-l<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(i){var s=this,t=this.options;this.opos=[i.pageX,i.pageY],this.elementPos=V(this.element[0]).offset(),this.options.disabled||(this.selectees=V(t.filter,this.element[0]),this._trigger("start",i),V(t.appendTo).append(this.helper),this.helper.css({left:i.pageX,top:i.pageY,width:0,height:0}),t.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var t=V.data(this,"selectable-item");t.startselected=!0,i.metaKey||i.ctrlKey||(s._removeClass(t.$element,"ui-selected"),t.selected=!1,s._addClass(t.$element,"ui-unselecting"),t.unselecting=!0,s._trigger("unselecting",i,{unselecting:t.element}))}),V(i.target).parents().addBack().each(function(){var t,e=V.data(this,"selectable-item");if(e)return t=!i.metaKey&&!i.ctrlKey||!e.$element.hasClass("ui-selected"),s._removeClass(e.$element,t?"ui-unselecting":"ui-selected")._addClass(e.$element,t?"ui-selecting":"ui-unselecting"),e.unselecting=!t,e.selecting=t,(e.selected=t)?s._trigger("selecting",i,{selecting:e.element}):s._trigger("unselecting",i,{unselecting:e.element}),!1}))},_mouseDrag:function(s){var t,n,o,a,r,l,h;if(this.dragged=!0,!this.options.disabled)return o=(n=this).options,a=this.opos[0],r=this.opos[1],(l=s.pageX) *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return e<=t&&t*{ cursor: "+o.cursor+" !important; }").appendTo(n)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!i)for(s=this.containers.length-1;0<=s;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return V.ui.ddmanager&&(V.ui.ddmanager.current=this),V.ui.ddmanager&&!o.dropBehaviour&&V.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this.helper.parent().is(this.appendTo)||(this.helper.detach().appendTo(this.appendTo),this.offset.parent=this._getParentOffset()),this.position=this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,this.lastPositionAbs=this.positionAbs=this._convertPositionTo("absolute"),this._mouseDrag(t),!0},_scroll:function(t){var e=this.options,i=!1;return this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageYt[this.floating?"width":"height"]?h&&c:o",i.document[0]);return i._addClass(t,"ui-sortable-placeholder",s||i.currentItem[0].className)._removeClass(t,"ui-sortable-helper"),"tbody"===n?i._createTrPlaceholder(i.currentItem.find("tr").eq(0),V("
",i.document[0]).appendTo(t)):"tr"===n?i._createTrPlaceholder(i.currentItem,t):"img"===n&&t.attr("src",i.currentItem.attr("src")),s||t.css("visibility","hidden"),t},update:function(t,e){s&&!o.forcePlaceholderSize||(e.height()&&(!o.forcePlaceholderSize||"tbody"!==n&&"tr"!==n)||e.height(i.currentItem.innerHeight()-parseInt(i.currentItem.css("paddingTop")||0,10)-parseInt(i.currentItem.css("paddingBottom")||0,10)),e.width())||e.width(i.currentItem.innerWidth()-parseInt(i.currentItem.css("paddingLeft")||0,10)-parseInt(i.currentItem.css("paddingRight")||0,10))}}),i.placeholder=V(o.placeholder.element.call(i.element,i.currentItem)),i.currentItem.after(i.placeholder),o.placeholder.update(i,i.placeholder)},_createTrPlaceholder:function(t,e){var i=this;t.children().each(function(){V("",i.document[0]).attr("colspan",V(this).attr("colspan")||1).appendTo(e)})},_contactContainers:function(t){for(var e,i,s,n,o,a,r,l,h,c=null,u=null,d=this.containers.length-1;0<=d;d--)V.contains(this.currentItem[0],this.containers[d].element[0])||(this._intersectsWith(this.containers[d].containerCache)?c&&V.contains(this.containers[d].element[0],c.element[0])||(c=this.containers[d],u=d):this.containers[d].containerCache.over&&(this.containers[d]._trigger("out",t,this._uiHash(this)),this.containers[d].containerCache.over=0));if(c)if(1===this.containers.length)this.containers[u].containerCache.over||(this.containers[u]._trigger("over",t,this._uiHash(this)),this.containers[u].containerCache.over=1);else{for(i=1e4,s=null,n=(l=c.floating||this._isFloating(this.currentItem))?"left":"top",o=l?"width":"height",h=l?"pageX":"pageY",e=this.items.length-1;0<=e;e--)V.contains(this.containers[u].element[0],this.items[e].item[0])&&this.items[e].item[0]!==this.currentItem[0]&&(a=this.items[e].item.offset()[n],r=!1,t[h]-a>this.items[e][o]/2&&(r=!0),Math.abs(t[h]-a)this.containment[2]&&(i=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3])&&(s=this.containment[3]+this.offset.click.top),e.grid)&&(t=this.originalPageY+Math.round((s-this.originalPageY)/e.grid[1])*e.grid[1],s=!this.containment||t-this.offset.click.top>=this.containment[1]&&t-this.offset.click.top<=this.containment[3]?t:t-this.offset.click.top>=this.containment[1]?t-e.grid[1]:t+e.grid[1],t=this.originalPageX+Math.round((i-this.originalPageX)/e.grid[0])*e.grid[0],i=!this.containment||t-this.offset.click.left>=this.containment[0]&&t-this.offset.click.left<=this.containment[2]?t:t-this.offset.click.left>=this.containment[0]?t-e.grid[0]:t+e.grid[0]),{top:s-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop()),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)"auto"!==this._storedCSS[i]&&"static"!==this._storedCSS[i]||(this._storedCSS[i]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();function n(e,i,s){return function(t){s._trigger(e,t,i._uiHash(i))}}for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this===this.currentContainer||e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))),i=this.containers.length-1;0<=i;i--)e||s.push(n("deactivate",this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(n("out",this,this.containers[i])),this.containers[i].containerCache.over=0);if(this._storedStylesheet&&(this._storedStylesheet.remove(),this._storedStylesheet=null),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(i=0;i li > :first-child").add(t.find("> :not(li)").filter(function(t){return t%2==0}))},heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=V(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||!1!==t.active&&null!=t.active||(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():V()}},_createIcons:function(){var t,e=this.options.icons;e&&(t=V(""),this._addClass(t,"ui-accordion-header-icon","ui-icon "+e.header),t.prependTo(this.headers),t=this.active.children(".ui-accordion-header-icon"),this._removeClass(t,e.header)._addClass(t,null,e.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){"active"===t?this._activate(e):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),"icons"===t&&(this._destroyIcons(),e)&&this._createIcons())},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var e=V.ui.keyCode,i=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case e.RIGHT:case e.DOWN:n=this.headers[(s+1)%i];break;case e.LEFT:case e.UP:n=this.headers[(s-1+i)%i];break;case e.SPACE:case e.ENTER:this._eventHandler(t);break;case e.HOME:n=this.headers[0];break;case e.END:n=this.headers[i-1]}n&&(V(t.target).attr("tabIndex",-1),V(n).attr("tabIndex",0),V(n).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===V.ui.keyCode.UP&&t.ctrlKey&&V(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),!1===t.active&&!0===t.collapsible||!this.headers.length?(t.active=!1,this.active=V()):!1===t.active?this._activate(0):this.active.length&&!V.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=V()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;"function"==typeof this.options.header?this.headers=this.options.header(this.element):this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var i,t=this.options,e=t.heightStyle,s=this.element.parent();this.active=this._findActive(t.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=V(this),e=t.uniqueId().attr("id"),i=t.next(),s=i.uniqueId().attr("id");t.attr("aria-controls",s),i.attr("aria-labelledby",e)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(t.event),"fill"===e?(i=s.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=V(this).outerHeight(!0)}),this.headers.next().each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.headers.next().each(function(){var t=V(this).is(":visible");t||V(this).show(),i=Math.max(i,V(this).css("height","").height()),t||V(this).hide()}).height(i))},_activate:function(t){t=this._findActive(t)[0];t!==this.active[0]&&(t=t||this.active[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):V()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():s.next(),r=i.next(),r={oldHeader:i,oldPanel:r,newHeader:o?V():s,newPanel:a};t.preventDefault(),n&&!e.collapsible||!1===this._trigger("beforeActivate",t,r)||(e.active=!o&&this.headers.index(s),this.active=n?V():s,this._toggle(r),this._removeClass(i,"ui-accordion-header-active","ui-state-active"),e.icons&&(a=i.children(".ui-accordion-header-icon"),this._removeClass(a,null,e.icons.activeHeader)._addClass(a,null,e.icons.header)),n)||(this._removeClass(s,"ui-accordion-header-collapsed")._addClass(s,"ui-accordion-header-active","ui-state-active"),e.icons&&(t=s.children(".ui-accordion-header-icon"),this._removeClass(t,null,e.icons.header)._addClass(t,null,e.icons.activeHeader)),this._addClass(s.next(),"ui-accordion-content-active"))},_toggle:function(t){var e=t.newPanel,i=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=e,this.prevHide=i,this.options.animate?this._animate(e,i,t):(i.hide(),e.show(),this._toggleComplete(t)),i.attr({"aria-hidden":"true"}),i.prev().attr({"aria-selected":"false","aria-expanded":"false"}),e.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):e.length&&this.headers.filter(function(){return 0===parseInt(V(this).attr("tabIndex"),10)}).attr("tabIndex",-1),e.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,i,e){function s(){o._toggleComplete(e)}var n,o=this,a=0,r=t.css("box-sizing"),l=t.length&&(!i.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=V(t.target),i=V(this.document[0].activeElement);!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active)&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){V.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=V(t.target).closest(".ui-menu-item"),i=V(t.currentTarget),e[0]!==i[0])||i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=V(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case V.ui.keyCode.PAGE_UP:this.previousPage(t);break;case V.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case V.ui.keyCode.HOME:this._move("first","first",t);break;case V.ui.keyCode.END:this._move("last","last",t);break;case V.ui.keyCode.UP:this.previous(t);break;case V.ui.keyCode.DOWN:this.next(t);break;case V.ui.keyCode.LEFT:this.collapse(t);break;case V.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case V.ui.keyCode.ENTER:case V.ui.keyCode.SPACE:this._activate(t);break;case V.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),t=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=V(this),e=t.prev(),i=V("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(t,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=V(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),e=(i=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(i,"ui-menu-item")._addClass(e,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!V.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(e=parseFloat(V.css(this.activeMenu[0],"borderTopWidth"))||0,i=parseFloat(V.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-e-i,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&"true"===this.element.prop("contentEditable"),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)i=!1,this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault();else if(!s){var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){n?(n=!1,t.preventDefault()):this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=V("
_(Parity)_
@@ -653,7 +653,7 @@ for (let n=0,x; x=index[n]; n++) { } function hideShow() { let n = 0, inactive = []; - var count = {'db-box1':0, 'db-box2':0, 'db-box3':0}; + var count = {'db_box1':0, 'db_box2':0, 'db_box3':0}; $('input.checker').each(function(){ var tbody = $('table.dashboard').find('tbody[sort="'+sort[n]+'"]'); var id = tbody.parent().prop('id'); @@ -669,9 +669,9 @@ function hideShow() { n++; }); count[table.find('tbody.system').parent().prop('id')]++; - if (count['db-box1']>0) $('div#tile1').show(); else $('div#tile1').hide(); - if (count['db-box2']>0) $('div#tile2').show(); else $('div#tile2').hide(); - if (count['db-box3']>0) $('div#tile3').show(); else $('div#tile3').hide(); + if (count['db_box1']>0) $('div#tile1').show(); else $('div#tile1').hide(); + if (count['db_box2']>0) $('div#tile2').show(); else $('div#tile2').hide(); + if (count['db_box3']>0) $('div#tile3').show(); else $('div#tile3').hide(); if (inactive.length>0) { cookie.inactive_content = inactive.join(';'); } else { @@ -1294,7 +1294,7 @@ function addProperties() { } function showContent() { - var count = {'db-box1':$('table#db-box1 tbody').length, 'db-box2':$('table#db-box2 tbody').length, 'db-box3':$('table#db-box3 tbody').length} + var count = {'db_box1':$('table#db_box1 tbody').length, 'db_box2':$('table#db_box2 tbody').length, 'db_box3':$('table#db_box3 tbody').length} var inactive = cookie.inactive_content; if (inactive) { inactive = inactive.split(';'); @@ -1317,9 +1317,9 @@ function showContent() { tbody.find('span.button').hide(); } } - if (count['db-box1']>0) $('div#tile1').show(); - if (count['db-box2']>0) $('div#tile2').show(); - if (count['db-box3']>0) $('div#tile3').show(); + if (count['db_box1']>0) $('div#tile1').show(); + if (count['db_box2']>0) $('div#tile2').show(); + if (count['db_box3']>0) $('div#tile3').show(); } function setColor(l, t1, t2) { @@ -1406,9 +1406,9 @@ function contentMgmt() { modal: true, buttons: { "_(Reset)_": function(){ - delete cookie['db-box1']; - delete cookie['db-box2']; - delete cookie['db-box3']; + delete cookie.db_box1; + delete cookie.db_box2; + delete cookie.db_box3; delete cookie.inactive_content; delete cookie.hidden_content; saveCookie(); @@ -1557,7 +1557,7 @@ function LockButton() { $('i.tile').show(); $('tbody.sortable').css({'cursor':'move'}); $('div.nav-item.LockButton span').text("_(Lock sortable items)_"); - $('#db-box1,#db-box2,#db-box3').sortable({connectWith:'#db-box1,#db-box2,#db-box3'}); + $('#db_box1,#db_box2,#db_box3').sortable({connectWith:'#db_box1,#db_box2,#db_box3'}); $('table.dashboard').sortable({helper:sortableHelper,items:'.sortable',cursor:'grab',opacity:0.6,placeholder:'dashboard-sortable',zIndex:9999,forceHelperSize:true,forcePlaceholderSize:true, receive:function(e,ui){ var table = ui.sender, index = []; From 885a4cc654e7643865ee7c853eb36fc81b5a7003 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 01:45:28 +0100 Subject: [PATCH 104/122] Update DashStats.page --- emhttp/plugins/dynamix/DashStats.page | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 37b4718c0..8016b8675 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -1145,8 +1145,10 @@ function dropdown(menu) { } function toggleCPU(init) { - if (!init) {if (!cookie.cpu) cookie.cpu = 'close'; else delete cookie.cpu;} - saveCookie(); + if (!init) { + if (!cookie.cpu) cookie.cpu = 'close'; else delete cookie.cpu; + saveCookie(); + } if (!cookie.cpu) { $('.cpu_open').show(); $('.cpu_close').text("_(Hide details)_"); @@ -1158,8 +1160,10 @@ function toggleCPU(init) { } function toggleChart(init) { - if (!init) {if (!cookie.cpu_chart) cookie.cpu_chart = 'close'; else delete cookie.cpu_chart;} - saveCookie(); + if (!init) { + if (!cookie.cpu_chart) cookie.cpu_chart = 'close'; else delete cookie.cpu_chart; + saveCookie(); + } $('#cpu_main').removeClass('last'); $('.cpu_open:last').removeClass('last'); if (!cookie.cpu_chart) { From 5e8d17b20c0389918b00ce62bf10768868a0279a Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 10:45:09 +0100 Subject: [PATCH 105/122] Update DashStats.page --- emhttp/plugins/dynamix/DashStats.page | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 8016b8675..1fbe44ad0 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -833,7 +833,7 @@ var options_net = { var cpuchart = new ApexCharts(document.querySelector('#cpuchart'), options_cpu); var netchart = new ApexCharts(document.querySelector('#netchart'), options_net); -if (cookie.port_select!=null && !ports.includes(cookie.port_select)) { +if (cookie.port_select && !ports.includes(cookie.port_select)) { delete cookie.port_select; saveCookie(); } @@ -1356,7 +1356,6 @@ function openClose(button) { hidden.splice(hidden.indexOf(tbody.attr('sort')),1); } cookie.hidden_content = hidden.join(';'); - saveCookie(); } else { // show/hide all tiles content if (hidden.length==0) { @@ -1366,16 +1365,15 @@ function openClose(button) { hidden.push($(this).attr('sort')); }); cookie.hidden_content = hidden.join(';'); - saveCookie(); } else { $('div.frame tbody').each(function(){ $(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up'); $(this).mixedView(1); }); delete cookie.hidden_content; - saveCookie(); } } + saveCookie(); } function dismiss(button) { From 8a70852c5e778edb1b4aee41a491cb5b4d2c3e38 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 10:50:18 +0100 Subject: [PATCH 106/122] Revert "Update DashStats.page" This reverts commit 5e8d17b20c0389918b00ce62bf10768868a0279a. --- emhttp/plugins/dynamix/DashStats.page | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 1fbe44ad0..8016b8675 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -833,7 +833,7 @@ var options_net = { var cpuchart = new ApexCharts(document.querySelector('#cpuchart'), options_cpu); var netchart = new ApexCharts(document.querySelector('#netchart'), options_net); -if (cookie.port_select && !ports.includes(cookie.port_select)) { +if (cookie.port_select!=null && !ports.includes(cookie.port_select)) { delete cookie.port_select; saveCookie(); } @@ -1356,6 +1356,7 @@ function openClose(button) { hidden.splice(hidden.indexOf(tbody.attr('sort')),1); } cookie.hidden_content = hidden.join(';'); + saveCookie(); } else { // show/hide all tiles content if (hidden.length==0) { @@ -1365,15 +1366,16 @@ function openClose(button) { hidden.push($(this).attr('sort')); }); cookie.hidden_content = hidden.join(';'); + saveCookie(); } else { $('div.frame tbody').each(function(){ $(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up'); $(this).mixedView(1); }); delete cookie.hidden_content; + saveCookie(); } } - saveCookie(); } function dismiss(button) { From d05b8105e0b9201a52b7d1a5d97a2180e06bf891 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 11:06:03 +0100 Subject: [PATCH 107/122] Update DashStats.page --- emhttp/plugins/dynamix/DashStats.page | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 8016b8675..8aae610e1 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -833,7 +833,7 @@ var options_net = { var cpuchart = new ApexCharts(document.querySelector('#cpuchart'), options_cpu); var netchart = new ApexCharts(document.querySelector('#netchart'), options_net); -if (cookie.port_select!=null && !ports.includes(cookie.port_select)) { +if (cookie.port_select && !ports.includes(cookie.port_select)) { delete cookie.port_select; saveCookie(); } @@ -1028,11 +1028,11 @@ function changeMode(item) { function changeView(item) { if (item==0) delete cookie.enter_view; else cookie.enter_view = item; + saveCookie(); if (item==0) $('.view1').show(); else $('.view1').hide(); if (item==1) $('.view2').show(); else $('.view2').hide(); if (item==2) $('.view3').show(); else $('.view3').hide(); if (item==3) $('.view4').show(); else $('.view4').hide(); - saveCookie(); } function changeCPUline(val) { @@ -1356,7 +1356,6 @@ function openClose(button) { hidden.splice(hidden.indexOf(tbody.attr('sort')),1); } cookie.hidden_content = hidden.join(';'); - saveCookie(); } else { // show/hide all tiles content if (hidden.length==0) { @@ -1366,16 +1365,15 @@ function openClose(button) { hidden.push($(this).attr('sort')); }); cookie.hidden_content = hidden.join(';'); - saveCookie(); } else { $('div.frame tbody').each(function(){ $(this).find('.openclose').removeClass('fa-chevron-up fa-chevron-down').addClass('fa-chevron-up'); $(this).mixedView(1); }); delete cookie.hidden_content; - saveCookie(); } } + saveCookie(); } function dismiss(button) { From 0c67eb28e6cd78b96e69adf09d4b57cb034ef68b Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 11:22:04 +0100 Subject: [PATCH 108/122] Update DashStats.page --- emhttp/plugins/dynamix/DashStats.page | 44 +++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 8aae610e1..0f68cb030 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -2,8 +2,8 @@ Menu="Dashboard" Nchan="wg_poller,update_1,update_2,update_3,ups_status:stop,vm_dashusage" --- /dev/null|grep -c 'fan[0-9]_input'"); -$autofan = is_executable("$docroot/plugins/dynamix.system.autofan/scripts/rc.autofan"); -$group = _var($var,'shareSMBEnabled')=='yes' | _var($var,'shareNFSEnabled')=='yes'; -$names = []; +$wg_up = $wireguard ? exec("wg show interfaces") : ''; +$wg_up = $wg_up ? explode(' ',$wg_up) : []; +$up = count($wg_up); +$down = max(count($conf)-$up,0); +$fans = exec("sensors -uA 2>/dev/null|grep -c 'fan[0-9]_input'"); +$autofan = is_executable("$docroot/plugins/dynamix.system.autofan/scripts/rc.autofan"); +$group = _var($var,'shareSMBEnabled')=='yes' | _var($var,'shareNFSEnabled')=='yes'; +$names = []; $cache_only = $encrypted = 0; + foreach ($shares as $share) { if ($share['useCache']=='only') $cache_only++; if ($share['luksStatus']>0) $encrypted++; } + $passwd = $nopass = 0; foreach ($users as $user) if ($user['passwd']=='yes') $passwd++; else $nopass++; -$boot = "/boot/config/plugins/dynamix"; -$myfile = "case-model.cfg"; -$mycase = file_exists("$boot/$myfile") ? file_get_contents("$boot/$myfile") : false; +$boot = "/boot/config/plugins/dynamix"; +$myfile = "case-model.cfg"; +$mycase = file_exists("$boot/$myfile") ? file_get_contents("$boot/$myfile") : false; -$board = dmidecode('Base Board Information','2',0); -$serial = _("s/n").": ".($board['Serial Number'] ?? "--"); -$board = ($board['Manufacturer'] ?? "").' '.($board['Product Name'] ?? "").' '.(isset($board['Version']) ? ", "._("Version")." ".$board['Version'] : ""); +$board = dmidecode('Base Board Information','2',0); +$serial = _("s/n").": ".($board['Serial Number'] ?? "--"); +$board = ($board['Manufacturer'] ?? "").' '.($board['Product Name'] ?? "").' '.(isset($board['Version']) ? ", "._("Version")." ".$board['Version'] : ""); -$bios = dmidecode('BIOS Information','0',0); +$bios = dmidecode('BIOS Information','0',0); $biosdate = _("BIOS dated").": "._(my_time(strtotime($bios['Release Date'] ?? ""),$display['date']),0); -$bios = $bios['Vendor'].(isset($bios['Version']) ? ", "._("Version")." ".$bios['Version'] : ""); +$bios = $bios['Vendor'].(isset($bios['Version']) ? ", "._("Version")." ".$bios['Version'] : ""); -$cpu = dmidecode('Processor Information','4',0); +$cpu = dmidecode('Processor Information','4',0); $cpumodel = str_ireplace(["Processor","(C)","(R)","(TM)"],["","©","®","™"],exec("grep -Pom1 '^model name\s+:\s*\K.+' /proc/cpuinfo") ?: $cpu['Version']); $cpumodel .= (strpos($cpumodel,'@')===false && !empty($cpu['Current Speed']) ? " @ {$cpu['Current Speed']}" : ""); From 1c308a5928ae391da2941c8f8694bb21b2eca786 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 12:42:59 +0100 Subject: [PATCH 109/122] Main page: make disk I/O default view --- emhttp/plugins/dynamix/ArrayOperation.page | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/emhttp/plugins/dynamix/ArrayOperation.page b/emhttp/plugins/dynamix/ArrayOperation.page index 0c79a61bd..6c59f0fd6 100644 --- a/emhttp/plugins/dynamix/ArrayOperation.page +++ b/emhttp/plugins/dynamix/ArrayOperation.page @@ -4,8 +4,8 @@ Tag="snowflake-o" Nchan="device_list,disk_load,parity_list" --- Date: Mon, 3 Feb 2025 14:03:35 +0100 Subject: [PATCH 110/122] jquery 3.7.1 update --- emhttp/plugins/dynamix/javascript/dynamix.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/javascript/dynamix.js b/emhttp/plugins/dynamix/javascript/dynamix.js index 683a02162..f60a4082d 100644 --- a/emhttp/plugins/dynamix/javascript/dynamix.js +++ b/emhttp/plugins/dynamix/javascript/dynamix.js @@ -1,8 +1,8 @@ /* This file includes source code derived from different libraries that are originally available under various licenses. The references for these libraries and their authors are given below. */ /* LATEST is checked on March 3, 2022 */ -/*! jQuery v3.7.0 | (c) OpenJS Foundation and other contributors | jquery.org/license LATEST */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.0",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&z(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function X(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function z(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Me(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 Date: Mon, 3 Feb 2025 14:12:36 +0100 Subject: [PATCH 111/122] jqueryUI 1.14.1 update --- emhttp/plugins/dynamix/javascript/dynamix.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/javascript/dynamix.js b/emhttp/plugins/dynamix/javascript/dynamix.js index f60a4082d..ce177787d 100644 --- a/emhttp/plugins/dynamix/javascript/dynamix.js +++ b/emhttp/plugins/dynamix/javascript/dynamix.js @@ -4,9 +4,9 @@ /*! jQuery v3.7.1 | (c) OpenJS Foundation and other contributors | jquery.org/license LATEST */ !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.1",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},M=function(){V()},R=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&U(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function z(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&R(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function X(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function U(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,r.msMatchesSelector&&ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",M),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||I.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Re(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return M(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return M(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.on("mouseenter",e).on("mouseleave",t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=V(e||this.defaultElement||this)[0],this.element=V(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=V(),this.hoverable=V(),this.focusable=V(),this.classesElementLookup={},e!==this&&(V.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=V(e.style?e.ownerDocument:e.document||e),this.window=V(this.document[0].defaultView||this.document[0].parentWindow)),this.options=V.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:V.noop,_create:V.noop,_init:V.noop,destroy:function(){var i=this;this._destroy(),V.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:V.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return V.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=V.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return V("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(k(s),k(n))?o.important="horizontal":o.important="vertical",u.using.call(this,t,o)}),a.offset(V.extend(h,{using:t}))})},V.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,a=s-o,r=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0")[0],w=d.each;function P(t){return null==t?t+"":"object"==typeof t?p[e.call(t)]||"object":typeof t}function M(t,e,i){var s=v[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:Math.min(s.max,Math.max(0,t)))}function S(s){var n=m(),o=n._rgba=[];return s=s.toLowerCase(),w(g,function(t,e){var i=e.re.exec(s),i=i&&e.parse(i),e=e.space||"rgba";if(i)return i=n[e](i),n[_[e].cache]=i[_[e].cache],o=n._rgba=i._rgba,!1}),o.length?("0,0,0,0"===o.join()&&d.extend(o,B.transparent),n):B[s]}function H(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}y.style.cssText="background-color:rgba(1,1,1,.5)",b.rgba=-1o.mod/2?s+=o.mod:s-n>o.mod/2&&(s-=o.mod)),l[i]=M((n-s)*a+s,e)))}),this[e](l)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=m(t)._rgba;return m(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null!=t?t:2").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return i.wrap(t),i[0]!==n&&!V.contains(i[0],n)||V(n).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(V.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),V.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!V.contains(t[0],e)||V(e).trigger("focus")),t}}),V.extend(V.effects,{version:"1.13.2",define:function(t,e,i){return i||(i=e,e="effect"),V.effects.effect[t]=i,V.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,e="vertical"!==i?(e||100)/100:1;return{height:t.height()*e,width:t.width()*s,outerHeight:t.outerHeight()*e,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(j+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=j+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){V.effects.restoreStyle(t),V.effects.removePlaceholder(t)},setTransition:function(s,t,n,o){return o=o||{},V.each(t,function(t,e){var i=s.cssUnit(e);0");l.appendTo("body").addClass(t.className).css({top:s.top-a,left:s.left-r,height:i.innerHeight(),width:i.innerWidth(),position:n?"fixed":"absolute"}).animate(o,t.duration,t.easing,function(){l.remove(),"function"==typeof e&&e()})}}),V.fx.step.clip=function(t){t.clipInit||(t.start=V(t.elem).cssClip(),"string"==typeof t.end&&(t.end=G(t.end,t.elem)),t.clipInit=!0),V(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},Y={},V.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){Y[t]=function(t){return Math.pow(t,e+2)}}),V.extend(Y,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),V.each(Y,function(t,e){V.easing["easeIn"+t]=e,V.easing["easeOut"+t]=function(t){return 1-e(1-t)},V.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});y=V.effects,V.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=V(this),n=t.direction||"up",o=s.cssClip(),a={clip:V.extend({},o)},r=V.effects.createPlaceholder(s);a.clip[i[n][0]]=a.clip[i[n][1]],"show"===t.mode&&(s.cssClip(a.clip),r&&r.css(V.effects.clipToBox(a)),a.clip=o),r&&r.animate(V.effects.clipToBox(a),t.duration,t.easing),s.animate(a,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("bounce",function(t,e){var i,s,n=V(this),o=t.mode,a="hide"===o,r="show"===o,l=t.direction||"up",h=t.distance,c=t.times||5,o=2*c+(r||a?1:0),u=t.duration/o,d=t.easing,p="up"===l||"down"===l?"top":"left",f="up"===l||"left"===l,g=0,t=n.queue().length;for(V.effects.createPlaceholder(n),l=n.css(p),h=h||n["top"==p?"outerHeight":"outerWidth"]()/3,r&&((s={opacity:1})[p]=l,n.css("opacity",0).css(p,f?2*-h:2*h).animate(s,u,d)),a&&(h/=Math.pow(2,c-1)),(s={})[p]=l;g").css({position:"absolute",visibility:"visible",left:-s*p,top:-i*f}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:p,height:f,left:n+(u?a*p:0),top:o+(u?r*f:0),opacity:u?0:1}).animate({left:n+(u?0:a*p),top:o+(u?0:r*f),opacity:u?1:0},t.duration||500,t.easing,m)}),V.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;V(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("fold","hide",function(e,t){var i=V(this),s=e.mode,n="show"===s,o="hide"===s,a=e.size||15,r=/([0-9]+)%/.exec(a),l=!!e.horizFirst?["right","bottom"]:["bottom","right"],h=e.duration/2,c=V.effects.createPlaceholder(i),u=i.cssClip(),d={clip:V.extend({},u)},p={clip:V.extend({},u)},f=[u[l[0]],u[l[1]]],s=i.queue().length;r&&(a=parseInt(r[1],10)/100*f[o?0:1]),d.clip[l[0]]=a,p.clip[l[0]]=a,p.clip[l[1]]=0,n&&(i.cssClip(p.clip),c&&c.css(V.effects.clipToBox(p)),p.clip=u),i.queue(function(t){c&&c.animate(V.effects.clipToBox(d),h,e.easing).animate(V.effects.clipToBox(p),h,e.easing),t()}).animate(d,h,e.easing).animate(p,h,e.easing).queue(t),V.effects.unshift(i,s,4)}),V.effects.define("highlight","show",function(t,e){var i=V(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),V.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("size",function(s,e){var n,i=V(this),t=["fontSize"],o=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],a=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],r=s.mode,l="effect"!==r,h=s.scale||"both",c=s.origin||["middle","center"],u=i.css("position"),d=i.position(),p=V.effects.scaledDimensions(i),f=s.from||p,g=s.to||V.effects.scaledDimensions(i,0);V.effects.createPlaceholder(i),"show"===r&&(r=f,f=g,g=r),n={from:{y:f.height/p.height,x:f.width/p.width},to:{y:g.height/p.height,x:g.width/p.width}},"box"!==h&&"both"!==h||(n.from.y!==n.to.y&&(f=V.effects.setTransition(i,o,n.from.y,f),g=V.effects.setTransition(i,o,n.to.y,g)),n.from.x!==n.to.x&&(f=V.effects.setTransition(i,a,n.from.x,f),g=V.effects.setTransition(i,a,n.to.x,g))),"content"!==h&&"both"!==h||n.from.y!==n.to.y&&(f=V.effects.setTransition(i,t,n.from.y,f),g=V.effects.setTransition(i,t,n.to.y,g)),c&&(c=V.effects.getBaseline(c,p),f.top=(p.outerHeight-f.outerHeight)*c.y+d.top,f.left=(p.outerWidth-f.outerWidth)*c.x+d.left,g.top=(p.outerHeight-g.outerHeight)*c.y+d.top,g.left=(p.outerWidth-g.outerWidth)*c.x+d.left),delete f.outerHeight,delete f.outerWidth,i.css(f),"content"!==h&&"both"!==h||(o=o.concat(["marginTop","marginBottom"]).concat(t),a=a.concat(["marginLeft","marginRight"]),i.find("*[width]").each(function(){var t=V(this),e=V.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},e={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=V.effects.setTransition(t,o,n.from.y,i),e=V.effects.setTransition(t,o,n.to.y,e)),n.from.x!==n.to.x&&(i=V.effects.setTransition(t,a,n.from.x,i),e=V.effects.setTransition(t,a,n.to.x,e)),l&&V.effects.saveStyle(t),t.css(i),t.animate(e,s.duration,s.easing,function(){l&&V.effects.restoreStyle(t)})})),i.animate(g,{queue:!1,duration:s.duration,easing:s.easing,complete:function(){var t=i.offset();0===g.opacity&&i.css("opacity",f.opacity),l||(i.css("position","static"===u?"relative":u).offset(t),V.effects.saveStyle(i)),e()}})}),V.effects.define("scale",function(t,e){var i=V(this),s=t.mode,s=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),s=V.extend(!0,{from:V.effects.scaledDimensions(i),to:V.effects.scaledDimensions(i,s,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(s.from.opacity=1,s.to.opacity=0),V.effects.effect.size.call(this,s,e)}),V.effects.define("puff","hide",function(t,e){t=V.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});V.effects.effect.scale.call(this,t,e)}),V.effects.define("pulsate","show",function(t,e){var i=V(this),s=t.mode,n="show"===s,o=2*(t.times||5)+(n||"hide"===s?1:0),a=t.duration/o,r=0,l=1,s=i.queue().length;for(!n&&i.is(":visible")||(i.css("opacity",0).show(),r=1);l li > :first-child").add(t.find("> :not(li)").even())},heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=V(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||!1!==t.active&&null!=t.active||(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():V()}},_createIcons:function(){var t,e=this.options.icons;e&&(t=V(""),this._addClass(t,"ui-accordion-header-icon","ui-icon "+e.header),t.prependTo(this.headers),t=this.active.children(".ui-accordion-header-icon"),this._removeClass(t,e.header)._addClass(t,null,e.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){"active"!==t?("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons())):this._activate(e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var e=V.ui.keyCode,i=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case e.RIGHT:case e.DOWN:n=this.headers[(s+1)%i];break;case e.LEFT:case e.UP:n=this.headers[(s-1+i)%i];break;case e.SPACE:case e.ENTER:this._eventHandler(t);break;case e.HOME:n=this.headers[0];break;case e.END:n=this.headers[i-1]}n&&(V(t.target).attr("tabIndex",-1),V(n).attr("tabIndex",0),V(n).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===V.ui.keyCode.UP&&t.ctrlKey&&V(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),!1===t.active&&!0===t.collapsible||!this.headers.length?(t.active=!1,this.active=V()):!1===t.active?this._activate(0):this.active.length&&!V.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=V()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;"function"==typeof this.options.header?this.headers=this.options.header(this.element):this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var i,t=this.options,e=t.heightStyle,s=this.element.parent();this.active=this._findActive(t.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=V(this),e=t.uniqueId().attr("id"),i=t.next(),s=i.uniqueId().attr("id");t.attr("aria-controls",s),i.attr("aria-labelledby",e)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(t.event),"fill"===e?(i=s.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=V(this).outerHeight(!0)}),this.headers.next().each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.headers.next().each(function(){var t=V(this).is(":visible");t||V(this).show(),i=Math.max(i,V(this).css("height","").height()),t||V(this).hide()}).height(i))},_activate:function(t){t=this._findActive(t)[0];t!==this.active[0]&&(t=t||this.active[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):V()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():s.next(),r=i.next(),a={oldHeader:i,oldPanel:r,newHeader:o?V():s,newPanel:a};t.preventDefault(),n&&!e.collapsible||!1===this._trigger("beforeActivate",t,a)||(e.active=!o&&this.headers.index(s),this.active=n?V():s,this._toggle(a),this._removeClass(i,"ui-accordion-header-active","ui-state-active"),e.icons&&(i=i.children(".ui-accordion-header-icon"),this._removeClass(i,null,e.icons.activeHeader)._addClass(i,null,e.icons.header)),n||(this._removeClass(s,"ui-accordion-header-collapsed")._addClass(s,"ui-accordion-header-active","ui-state-active"),e.icons&&(n=s.children(".ui-accordion-header-icon"),this._removeClass(n,null,e.icons.header)._addClass(n,null,e.icons.activeHeader)),this._addClass(s.next(),"ui-accordion-content-active")))},_toggle:function(t){var e=t.newPanel,i=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=e,this.prevHide=i,this.options.animate?this._animate(e,i,t):(i.hide(),e.show(),this._toggleComplete(t)),i.attr({"aria-hidden":"true"}),i.prev().attr({"aria-selected":"false","aria-expanded":"false"}),e.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):e.length&&this.headers.filter(function(){return 0===parseInt(V(this).attr("tabIndex"),10)}).attr("tabIndex",-1),e.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,i,e){var s,n,o,a=this,r=0,l=t.css("box-sizing"),h=t.length&&(!i.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=V(t.target),i=V(V.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){V.contains(this.element[0],V.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=V(t.target).closest(".ui-menu-item"),i=V(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=V(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case V.ui.keyCode.PAGE_UP:this.previousPage(t);break;case V.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case V.ui.keyCode.HOME:this._move("first","first",t);break;case V.ui.keyCode.END:this._move("last","last",t);break;case V.ui.keyCode.UP:this.previous(t);break;case V.ui.keyCode.DOWN:this.next(t);break;case V.ui.keyCode.LEFT:this.collapse(t);break;case V.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case V.ui.keyCode.ENTER:case V.ui.keyCode.SPACE:this._activate(t);break;case V.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=V(this),e=t.prev(),i=V("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=V(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!V.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(V.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(V.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=V("
 
 
",_=o?"":"",c=0;c<7;c++)_+="";for(m+=_+"",b=this._getDaysInMonth(E,A),E===t.selectedYear&&A===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,b)),v=(this._getFirstDayOfMonth(E,A)-n+7)%7,b=Math.ceil((v+b)/7),B=U&&this.maxRows>b?this.maxRows:b,this.maxRows=B,y=this._daylightSavingAdjust(new Date(E,A,1-v)),j=0;j",q=o?"":"",c=0;c<7;c++)w=a?a.apply(t.input?t.input[0]:null,[y]):[!0,""],k=(x=y.getMonth()!==A)&&!R||!w[0]||z&&y"+(x&&!r?" ":k?""+y.getDate()+"":""+y.getDate()+"")+"",y.setDate(y.getDate()+1),y=this._daylightSavingAdjust(y);m+=q+""}11<++A&&(A=0,E++),d+=m+="
"+this._get(t,"weekHeader")+""+W[Y]+"
"+this._get(t,"calculateWeek")(y)+"
"+(U?"
"+(0":""):"")}h+=d}return h+=T,t._keyEvent=!1,h},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var l,h,c,u,d,p,f=this._get(t,"changeMonth"),g=this._get(t,"changeYear"),m=this._get(t,"showMonthAfterYear"),_=this._get(t,"selectMonthLabel"),v=this._get(t,"selectYearLabel"),b="
",y="";if(o||!f)y+=""+a[e]+"";else{for(l=s&&s.getFullYear()===i,h=n&&n.getFullYear()===i,y+=""}if(m||(b+=y+(!o&&f&&g?"":" ")),!t.yearshtml)if(t.yearshtml="",o||!g)b+=""+i+"";else{for(a=this._get(t,"yearRange").split(":"),u=(new Date).getFullYear(),d=(_=function(t){t=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?u+parseInt(t,10):parseInt(t,10);return isNaN(t)?u:t})(a[0]),p=Math.max(d,_(a[1]||"")),d=s?Math.max(d,s.getFullYear()):d,p=n?Math.min(p,n.getFullYear()):p,t.yearshtml+="",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),m&&(b+=(!o&&f&&g?"":" ")+y),b+="
"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),e=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),s=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,e)));t.selectedDay=s.getDate(),t.drawMonth=t.selectedMonth=s.getMonth(),t.drawYear=t.selectedYear=s.getFullYear(),"M"!==i&&"Y"!==i||this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),t=this._getMinMaxDate(t,"max"),i=i&&e=s.getTime())&&(!n||e.getTime()<=n.getTime())&&(!o||e.getFullYear()>=o)&&(!a||e.getFullYear()<=a)},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return{shortYearCutoff:"string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);s=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),s,this._getFormatConfig(t))}}),V.fn.datepicker=function(t){if(!this.length)return this;V.datepicker.initialized||(V(document).on("mousedown",V.datepicker._checkExternalClick),V.datepicker.initialized=!0),0===V("#"+V.datepicker._mainDivId).length&&V("body").append(V.datepicker.dpDiv);var e=Array.prototype.slice.call(arguments,1);return"string"==typeof t&&("isDisabled"===t||"getDate"===t||"widget"===t)||"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this[0]].concat(e)):this.each(function(){"string"==typeof t?V.datepicker["_"+t+"Datepicker"].apply(V.datepicker,[this].concat(e)):V.datepicker._attachDatepicker(this,t)})},V.datepicker=new Y,V.datepicker.initialized=!1,V.datepicker.uuid=(new Date).getTime(),V.datepicker.version="1.14.1";V.widget("ui.dialog",{version:"1.14.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var e=V(this).css(t).offset().top;e<0&&V(this).css("top",t.top-e)}},resizable:!0,show:null,title:null,uiDialogTitleHeadingLevel:0,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&V.fn.draggable&&this._makeDraggable(),this.options.resizable&&V.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?V(t):this.document.find(t||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),(t=e.parent.children().eq(e.index)).length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:V.noop,enable:V.noop,close:function(t){var e=this;this._isOpen&&!1!==this._trigger("beforeClose",t)&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||V(this.document[0].activeElement).trigger("blur"),this._hide(this.uiDialog,this.options.hide,function(){e._trigger("close",t)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!1,s=this.uiDialog.siblings(".ui-front:visible").map(function(){return+V(this).css("z-index")}).get(),s=Math.max.apply(null,s);return s>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",s+1),i=!0),i&&!e&&this._trigger("focus",t),i},open:function(){var t=this;this._isOpen?this._moveToTop()&&this._focusTabbable():(this._isOpen=!0,this.opener=V(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"))},_focusTabbable:function(){var t=this._focusedElement;(t=(t=(t=(t=(t=t||this.element.find("[autofocus]")).length?t:this.element.find(":tabbable")).length?t:this.uiDialogButtonPane.find(":tabbable")).length?t:this.uiDialogTitlebarClose.filter(":tabbable")).length?t:this.uiDialog).eq(0).trigger("focus")},_restoreTabbableFocus:function(){var t=this.document[0].activeElement;this.uiDialog[0]===t||V.contains(this.uiDialog[0],t)||this._focusTabbable()},_keepFocus:function(t){t.preventDefault(),this._restoreTabbableFocus()},_createWrapper:function(){this.uiDialog=V("
").hide().attr({tabIndex:-1,role:"dialog","aria-modal":this.options.modal?"true":null}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(t){var e,i,s;this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===V.ui.keyCode.ESCAPE?(t.preventDefault(),this.close(t)):t.keyCode!==V.ui.keyCode.TAB||t.isDefaultPrevented()||(e=this.uiDialog.find(":tabbable"),i=e.first(),s=e.last(),t.target!==s[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==i[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(this._delay(function(){s.trigger("focus")}),t.preventDefault()):(this._delay(function(){i.trigger("focus")}),t.preventDefault()))},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){this.uiDialogTitlebar=V("
"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(t){V(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=V("").button({label:V("").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}});var t=Number.isInteger(this.options.uiDialogTitleHeadingLevel)&&0").uniqueId().prependTo(this.uiDialogTitlebar);this._addClass(t,"ui-dialog-title"),this._title(t),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html(" ")},_createButtonPane:function(){this.uiDialogButtonPane=V("
"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=V("
").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var s=this,t=this.options.buttons;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),V.isEmptyObject(t)||Array.isArray(t)&&!t.length?this._removeClass(this.uiDialog,"ui-dialog-buttons"):(V.each(t,function(t,e){var i;e=V.extend({type:"button"},e="function"==typeof e?{click:e,text:t}:e),i=e.click,t={icon:e.icon,iconPosition:e.iconPosition,showLabel:e.showLabel,icons:e.icons,text:e.text},delete e.click,delete e.icon,delete e.iconPosition,delete e.showLabel,delete e.icons,"boolean"==typeof e.text&&delete e.text,V("",e).button(t).appendTo(s.uiButtonSet).on("click",function(){i.apply(s.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog))},_makeDraggable:function(){var n=this,o=this.options;function a(t){return{position:t.position,offset:t.offset}}this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(t,e){n._addClass(V(this),"ui-dialog-dragging"),n._blockFrames(),n._trigger("dragStart",t,a(e))},drag:function(t,e){n._trigger("drag",t,a(e))},stop:function(t,e){var i=e.offset.left-n.document.scrollLeft(),s=e.offset.top-n.document.scrollTop();o.position={my:"left top",at:"left"+(0<=i?"+":"")+i+" top"+(0<=s?"+":"")+s,of:n.window},n._removeClass(V(this),"ui-dialog-dragging"),n._unblockFrames(),n._trigger("dragStop",t,a(e))}})},_makeResizable:function(){var n=this,o=this.options,t=o.resizable,e=this.uiDialog.css("position"),t="string"==typeof t?t:"n,e,s,w,se,sw,ne,nw";function a(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:o.maxWidth,maxHeight:o.maxHeight,minWidth:o.minWidth,minHeight:this._minHeight(),handles:t,start:function(t,e){n._addClass(V(this),"ui-dialog-resizing"),n._blockFrames(),n._trigger("resizeStart",t,a(e))},resize:function(t,e){n._trigger("resize",t,a(e))},stop:function(t,e){var i=n.uiDialog.offset(),s=i.left-n.document.scrollLeft(),i=i.top-n.document.scrollTop();o.height=n.uiDialog.height(),o.width=n.uiDialog.width(),o.position={my:"left top",at:"left"+(0<=s?"+":"")+s+" top"+(0<=i?"+":"")+i,of:n.window},n._removeClass(V(this),"ui-dialog-resizing"),n._unblockFrames(),n._trigger("resizeStop",t,a(e))}}).css("position",e)},_trackFocus:function(){this._on(this.widget(),{focusin:function(t){this._makeFocusTarget(),this._focusedElement=V(t.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var t=this._trackingInstances(),e=V.inArray(this,t);-1!==e&&t.splice(e,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||this.document.data("ui-dialog-instances",t=[]),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,n={};V.each(t,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(t,e){var i,s=this.uiDialog;"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:V("").text(""+this.options.closeText).html()}),"draggable"===t&&((i=s.is(":data(ui-draggable)"))&&!e&&s.draggable("destroy"),!i)&&e&&this._makeDraggable(),"position"===t&&this._position(),"resizable"===t&&((i=s.is(":data(ui-resizable)"))&&!e&&s.resizable("destroy"),i&&"string"==typeof e&&s.resizable("option","handles",e),i||!1===e||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")),"modal"===t)&&s.attr("aria-modal",e?"true":null)},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=V(this);return V("
").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return!!V(t.target).closest(".ui-dialog").length||!!V(t.target).closest(".ui-datepicker").length},_createOverlay:function(){var i;this.options.modal&&(i=!0,this._delay(function(){i=!1}),this.document.data("ui-dialog-overlays")||this.document.on("focusin.ui-dialog",function(t){var e;i||(e=this._trackingInstances()[0])._allowInteraction(t)||(t.preventDefault(),e._focusTabbable())}.bind(this)),this.overlay=V("
").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1))},_destroyOverlay:function(){var t;this.options.modal&&this.overlay&&((t=this.document.data("ui-dialog-overlays")-1)?this.document.data("ui-dialog-overlays",t):(this.document.off("focusin.ui-dialog"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null)}}),!0===V.uiBackCompat&&V.widget("ui.dialog",V.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),V.ui.dialog,V.widget("ui.progressbar",{version:"1.14.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=V("
").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){if(void 0===t)return this.options.value;this.options.value=this._constrainedValue(t),this._refreshValue()},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=!1===t,"number"!=typeof t&&(t=0),!this.indeterminate&&Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,e=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).width(e.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,t===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=V("
").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}}),V.widget("ui.selectmenu",[V.ui.formResetMixin,{version:"1.14.1",defaultElement:"",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var s=this._super(),n=this.element;return V.each(["min","max","step"],function(t,e){var i=n.attr(e);null!=i&&i.length&&(s[e]=i)}),s},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t)},mousewheel:function(t,e){var i=this.document[0].activeElement;if(this.element[0]===i&&e){if(!this.spinning&&!this._start(t))return!1;this._spin((0").parent().append("")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&0e.max?e.max:null!==e.min&&t"},_buttonHtml:function(){return""}});V.ui.spinner,V.widget("ui.tabs",{version:"1.14.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:(f=/#.*$/,function(t){var e=t.href.replace(f,""),i=location.href.replace(f,"");try{e=decodeURIComponent(e)}catch(t){}try{i=decodeURIComponent(i)}catch(t){}return 1 li",function(t){V(this).is(".ui-state-disabled")&&t.preventDefault()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return V("a",this)[0]}).attr({tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=V(),this.anchors.each(function(t,e){var i,s,n=V(e).uniqueId().attr("id"),o=V(e).closest("li"),a=o.attr("aria-controls");r._isLocal(e)?(s=decodeURIComponent(e.hash).substring(1),i=r.element.find("#"+CSS.escape(s))):(s=o.attr("aria-controls")||V({}).uniqueId()[0].id,(i=r.element.find("#"+s)).length||(i=r._createPanel(s)).insertAfter(r.panels[t-1]||r.tablist),i.attr("aria-live","polite")),i.length&&(r.panels=r.panels.add(i)),a&&o.data("ui-tabs-aria-controls",a),o.attr({"aria-controls":s,"aria-labelledby":n}),i.attr("aria-labelledby",n)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),t&&(this._off(t.not(this.tabs)),this._off(e.not(this.anchors)),this._off(i.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(t){return V("
").attr("id",t).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(t){var e,i;for(Array.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1),i=0;e=this.tabs[i];i++)e=V(e),!0===t||-1!==V.inArray(i,t)?(e.attr("aria-disabled","true"),this._addClass(e,null,"ui-state-disabled")):(e.removeAttr("aria-disabled"),this._removeClass(e,null,"ui-state-disabled"));this.options.disabled=t,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!0===t)},_setupEvents:function(t){var i={};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,e=this.element.parent();"fill"===t?(i=e.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=V(this).outerHeight(!0)}),this.panels.each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,V(this).height("").height())}).height(i))},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget).closest("li"),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():this._getPanelForTab(s),r=i.length?this._getPanelForTab(i):V(),i={oldTab:i,oldPanel:r,newTab:o?V():s,newPanel:a};t.preventDefault(),s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||n&&!e.collapsible||!1===this._trigger("beforeActivate",t,i)||(e.active=!o&&this.tabs.index(s),this.active=n?V():s,this.xhr&&this.xhr.abort(),r.length||a.length||V.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,i))},_toggle:function(t,e){var i=this,s=e.newPanel,n=e.oldPanel;function o(){i.running=!1,i._trigger("activate",t,e)}function a(){i._addClass(e.newTab.closest("li"),"ui-tabs-active","ui-state-active"),s.length&&i.options.show?i._show(s,i.options.show,o):(s.show(),o())}this.running=!0,n.length&&this.options.hide?this._hide(n,this.options.hide,function(){i._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),a()}):(this._removeClass(e.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n.hide(),a()),n.attr("aria-hidden","true"),e.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),s.length&&n.length?e.oldTab.attr("tabIndex",-1):s.length&&this.tabs.filter(function(){return 0===V(this).attr("tabIndex")}).attr("tabIndex",-1),s.attr("aria-hidden","false"),e.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(t){var t=this._findActive(t);t[0]!==this.active[0]&&(t=(t=t.length?t:this.active).find(".ui-tabs-anchor")[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return!1===t?V():this.tabs.eq(t)},_getIndex:function(t){return t="string"==typeof t?this.anchors.index(this.anchors.filter("[href$='"+CSS.escape(t)+"']")):t},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){V.data(this,"ui-tabs-destroy")?V(this).remove():V(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var t=V(this),e=t.data("ui-tabs-aria-controls");e?t.attr("aria-controls",e).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var t=this.options.disabled;!1!==t&&(t=void 0!==i&&(i=this._getIndex(i),Array.isArray(t)?V.map(t,function(t){return t!==i?t:null}):V.map(this.tabs,function(t,e){return e!==i?e:null})),this._setOptionDisabled(t))},disable:function(t){var e=this.options.disabled;if(!0!==e){if(void 0===t)e=!0;else{if(t=this._getIndex(t),-1!==V.inArray(t,e))return;e=Array.isArray(e)?V.merge([t],e).sort():[t]}this._setOptionDisabled(e)}},load:function(t,s){t=this._getIndex(t);function n(t,e){"abort"===e&&o.panels.stop(!1,!0),o._removeClass(i,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===o.xhr&&delete o.xhr}var o=this,i=this.tabs.eq(t),t=i.find(".ui-tabs-anchor"),a=this._getPanelForTab(i),r={tab:i,panel:a};this._isLocal(t[0])||(this.xhr=V.ajax(this._ajaxSettings(t,s,r)),"canceled"!==this.xhr.statusText&&(this._addClass(i,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,i){a.html(t),o._trigger("load",s,r),n(i,e)}).fail(function(t,e){n(t,e)})))},_ajaxSettings:function(t,i,s){var n=this;return{url:t.attr("href"),beforeSend:function(t,e){return n._trigger("beforeLoad",i,V.extend({jqXHR:t,ajaxSettings:e},s))}}},_getPanelForTab:function(t){t=V(t).attr("aria-controls");return this.element.find("#"+CSS.escape(t))}}),!0===V.uiBackCompat&&V.widget("ui.tabs",V.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),V.ui.tabs,V.widget("ui.tooltip",{version:"1.14.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var t=V(this).attr("title");return V("").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(t,e){var i=(t.attr("aria-describedby")||"").split(/\s+/);i.push(e),t.data("ui-tooltip-id",e).attr("aria-describedby",String.prototype.trim.call(i.join(" ")))},_removeDescribedBy:function(t){var e=t.data("ui-tooltip-id"),i=(t.attr("aria-describedby")||"").split(/\s+/),e=V.inArray(e,i);-1!==e&&i.splice(e,1),t.removeData("ui-tooltip-id"),(i=String.prototype.trim.call(i.join(" ")))?t.attr("aria-describedby",i):t.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=V("
").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=V([])},_setOption:function(t,e){var i=this;this._super(t,e),"content"===t&&V.each(this.tooltips,function(t,e){i._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur");i.target=i.currentTarget=e.element[0],s.close(i,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var t=V(this);if(t.is("[title]"))return t.data("ui-tooltip-title",t.attr("title")).removeAttr("title")}))},_enable:function(){this.disabledTitles.each(function(){var t=V(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))}),this.disabledTitles=V([])},open:function(t){var i=this,e=V(t?t.target:this.element).closest(this.options.items);e.length&&!e.data("ui-tooltip-id")&&(e.attr("title")&&e.data("ui-tooltip-title",e.attr("title")),e.data("ui-tooltip-open",!0),t&&"mouseover"===t.type&&e.parents().each(function(){var t,e=V(this);e.data("ui-tooltip-open")&&((t=V.Event("blur")).target=t.currentTarget=this,i.close(t,!0)),e.attr("title")&&(e.uniqueId(),i.parents[this.id]={element:this,title:e.attr("title")},e.attr("title",""))}),this._registerCloseHandlers(t,e),this._updateContent(e,t))},_updateContent:function(e,i){var t=this.options.content,s=this,n=i?i.type:null;if("string"==typeof t||t.nodeType||t.jquery)return this._open(i,e,t);(t=t.call(e[0],function(t){e.data("ui-tooltip-open")&&(i&&(i.type=n),s._open(i,e,t))}))&&this._open(i,e,t)},_open:function(t,e,i){var s,n,o,a=V.extend({},this.options.position);function r(t){a.of=t,s.is(":hidden")||s.position(a)}i&&((o=this._find(e))?o.tooltip.find(".ui-tooltip-content").html(i):(e.is("[title]")&&(t&&"mouseover"===t.type?e.attr("title",""):e.removeAttr("title")),o=this._tooltip(e),s=o.tooltip,this._addDescribedBy(e,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.liveRegion.children().hide(),(o=V("
").html(s.find(".ui-tooltip-content").html())).removeAttr("name").find("[name]").removeAttr("name"),o.removeAttr("id").find("[id]").removeAttr("id"),o.appendTo(this.liveRegion),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:r}),r(t)):s.position(V.extend({of:e},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(n=this.delayedShow=setInterval(function(){s.is(":visible")&&(r(a.of),clearInterval(n))},13)),this._trigger("open",t,{tooltip:s})))},_registerCloseHandlers:function(t,e){var i={keyup:function(t){t.keyCode===V.ui.keyCode.ESCAPE&&((t=V.Event(t)).currentTarget=e[0],this.close(t,!0))}};e[0]!==this.element[0]&&(i.remove=function(){var t=this._find(e);t&&this._removeTooltip(t.tooltip)}),t&&"mouseover"!==t.type||(i.mouseleave="close"),t&&"focusin"!==t.type||(i.focusout="close"),this._on(!0,e,i)},close:function(t){var e,i=this,s=V(t?t.currentTarget:this.element),n=this._find(s);n?(e=n.tooltip,n.closing||(clearInterval(this.delayedShow),s.data("ui-tooltip-title")&&!s.attr("title")&&s.attr("title",s.data("ui-tooltip-title")),this._removeDescribedBy(s),n.hiding=!0,e.stop(!0),this._hide(e,this.options.hide,function(){i._removeTooltip(V(this))}),s.removeData("ui-tooltip-open"),this._off(s,"mouseleave focusout keyup"),s[0]!==this.element[0]&&this._off(s,"remove"),this._off(this.document,"mousemove"),t&&"mouseleave"===t.type&&V.each(this.parents,function(t,e){V(e.element).attr("title",e.title),delete i.parents[t]}),n.closing=!0,this._trigger("close",t,{tooltip:e}),n.hiding)||(n.closing=!1)):s.removeData("ui-tooltip-open")},_tooltip:function(t){var e=V("
").attr("role","tooltip"),i=V("
").appendTo(e),s=e.uniqueId().attr("id");return this._addClass(i,"ui-tooltip-content"),this._addClass(e,"ui-tooltip","ui-widget ui-widget-content"),e.appendTo(this._appendTo(t)),this.tooltips[s]={element:t,tooltip:e}},_find:function(t){t=t.data("ui-tooltip-id");return t?this.tooltips[t]:null},_removeTooltip:function(t){clearInterval(this.delayedShow),t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){t=t.closest(".ui-front, dialog");return t=t.length?t:this.document[0].body},_destroy:function(){var s=this;V.each(this.tooltips,function(t,e){var i=V.Event("blur"),e=e.element;i.target=i.currentTarget=e[0],s.close(i,!0),V("#"+t).remove(),e.data("ui-tooltip-title")&&(e.attr("title")||e.attr("title",e.data("ui-tooltip-title")),e.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),!0===V.uiBackCompat&&V.widget("ui.tooltip",V.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),V.ui.tooltip;var f,g=V,m={},q=m.toString,K=/^([\-+])=\s*(\d+\.?\d*)/,U=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16),t[4]?(parseInt(t[4],16)/255).toFixed(2):1]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16),t[4]?(parseInt(t[4]+t[4],16)/255).toFixed(2):1]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],_=g.Color=function(t,e,i,s){return new g.Color.fn.parse(t,e,i,s)},v={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},X={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},b=g.each;function y(t){return null==t?t+"":"object"==typeof t?m[q.call(t)]||"object":typeof t}function w(t,e,i){var s=X[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),s.mod?(t+s.mod)%s.mod:Math.min(s.max,Math.max(0,t)))}function $(s){var n=_(),o=n._rgba=[];return s=s.toLowerCase(),b(U,function(t,e){var i=e.re.exec(s),i=i&&e.parse(i),e=e.space||"rgba";if(i)return i=n[e](i),n[v[e].cache]=i[v[e].cache],o=n._rgba=i._rgba,!1}),o.length?("0,0,0,0"===o.join()&&g.extend(o,M.transparent),n):M[s]}function T(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}b(v,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),g.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(t,e){m["[object "+e+"]"]=e.toLowerCase()}),_.fn=g.extend(_.prototype,{parse:function(n,t,e,i){if(void 0===n)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=g(n).css(t),t=void 0);var o=this,s=y(n),a=this._rgba=[];return void 0!==t&&(n=[n,t,e,i],s="array"),"string"===s?this.parse($(n)||M._default):"array"===s?(b(v.rgba.props,function(t,e){a[e.idx]=w(n[e.idx],e)}),this):"object"===s?(n instanceof _?b(v,function(t,e){n[e.cache]&&(o[e.cache]=n[e.cache].slice())}):b(v,function(t,i){var s=i.cache;b(i.props,function(t,e){if(!o[s]&&i.to){if("alpha"===t||null==n[t])return;o[s]=i.to(o._rgba)}o[s][e.idx]=w(n[t],e,!0)}),o[s]&&g.inArray(null,o[s].slice(0,3))<0&&(null==o[s][3]&&(o[s][3]=1),i.from)&&(o._rgba=i.from(o[s]))}),this):void 0},is:function(t){var n=_(t),o=!0,a=this;return b(v,function(t,e){var i,s=n[e.cache];return s&&(i=a[e.cache]||e.to&&e.to(a._rgba)||[],b(e.props,function(t,e){if(null!=s[e.idx])return o=s[e.idx]===i[e.idx]})),o}),o},_space:function(){var i=[],s=this;return b(v,function(t,e){s[e.cache]&&i.push(t)}),i.pop()},transition:function(t,a){var t=(h=_(t))._space(),e=v[t],i=0===this.alpha()?_("transparent"):this,r=i[e.cache]||e.to(i._rgba),l=r.slice(),h=h[e.cache];return b(e.props,function(t,e){var i=e.idx,s=r[i],n=h[i],o=X[e.type]||{};null!==n&&(null===s?l[i]=n:(o.mod&&(n-s>o.mod/2?s+=o.mod:s-n>o.mod/2&&(s-=o.mod)),l[i]=w((n-s)*a+s,e)))}),this[t](l)},blend:function(t){var e,i,s;return 1===this._rgba[3]?this:(e=this._rgba.slice(),i=e.pop(),s=_(t)._rgba,_(g.map(e,function(t,e){return(1-i)*s[e]+i*t})))},toRgbaString:function(){var t="rgba(",e=g.map(this._rgba,function(t,e){return null!=t?t:2{var i,s,n={};for(i in e)s=e[i],t[i]===s||tt[i]||!V.fx.step[i]&&isNaN(parseFloat(s))||(n[i]=s);return n})(this.start,this.end),this}),i.attr("class",t),e=e.map(function(){var t=this,e=V.Deferred(),i=V.extend({},o,{queue:!1,complete:function(){e.resolve(t)}});return this.el.animate(this.diff,i),e.promise()}),V.when.apply(V,e.get()).done(function(){s(),V.each(arguments,function(){var e=this.el;V.each(this.diff,function(t){e.css(t,"")})}),o.complete.call(i[0])})})},V.fn.extend({addClass:(J=V.fn.addClass,function(t,e,i,s){return e?V.effects.animateClass.call(this,{add:t},e,i,s):J.apply(this,arguments)}),removeClass:(Q=V.fn.removeClass,function(t,e,i,s){return 1
").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return i.wrap(t),i[0]!==n&&!V.contains(i[0],n)||V(n).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(V.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),V.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!V.contains(t[0],e)||V(e).trigger("focus")),t}}),V.extend(V.effects,{version:"1.14.1",define:function(t,e,i){return i||(i=e,e="effect"),V.effects.effect[t]=i,V.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){var s;return 0===e?{height:0,width:0,outerHeight:0,outerWidth:0}:(s="horizontal"!==i?(e||100)/100:1,i="vertical"!==i?(e||100)/100:1,{height:t.height()*i,width:t.width()*s,outerHeight:t.outerHeight()*i,outerWidth:t.outerWidth()*s})},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(S+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=S+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){V.effects.restoreStyle(t),V.effects.removePlaceholder(t)},setTransition:function(s,t,n,o){return o=o||{},V.each(t,function(t,e){var i=s.cssUnit(e);0
");l.appendTo("body").addClass(t.className).css({top:s.top-a,left:s.left-o,height:i.innerHeight(),width:i.innerWidth(),position:n?"fixed":"absolute"}).animate(r,t.duration,t.easing,function(){l.remove(),"function"==typeof e&&e()})}}),V.fx.step.clip=function(t){t.clipInit||(t.start=V(t.elem).cssClip(),"string"==typeof t.end&&(t.end=at(t.end,t.elem)),t.clipInit=!0),V(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},P={},V.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){P[t]=function(t){return Math.pow(t,e+2)}}),V.extend(P,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),V.each(P,function(t,e){V.easing["easeIn"+t]=e,V.easing["easeOut"+t]=function(t){return 1-e(1-t)},V.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});var rt=V.effects;V.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=V(this),n=t.direction||"up",o=s.cssClip(),a={clip:V.extend({},o)},r=V.effects.createPlaceholder(s);a.clip[i[n][0]]=a.clip[i[n][1]],"show"===t.mode&&(s.cssClip(a.clip),r&&r.css(V.effects.clipToBox(a)),a.clip=o),r&&r.animate(V.effects.clipToBox(a),t.duration,t.easing),s.animate(a,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("bounce",function(t,e){var i,s,n=V(this),o=t.mode,a="hide"===o,o="show"===o,r=t.direction||"up",l=t.distance,h=t.times||5,c=2*h+(o||a?1:0),u=t.duration/c,d=t.easing,p="up"===r||"down"===r?"top":"left",f="up"===r||"left"===r,g=0,t=n.queue().length;for(V.effects.createPlaceholder(n),r=n.css(p),l=l||n["top"==p?"outerHeight":"outerWidth"]()/3,o&&((s={opacity:1})[p]=r,n.css("opacity",0).css(p,f?2*-l:2*l).animate(s,u,d)),a&&(l/=Math.pow(2,h-1)),(s={})[p]=r;g
").css({position:"absolute",visibility:"visible",left:-s*p,top:-i*f}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:p,height:f,left:n+(u?a*p:0),top:o+(u?r*f:0),opacity:u?0:1}).animate({left:n+(u?0:a*p),top:o+(u?0:r*f),opacity:u?1:0},t.duration||500,t.easing,m)}),V.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;V(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("fold","hide",function(e,t){var i=V(this),s=e.mode,n="show"===s,s="hide"===s,o=e.size||15,a=/([0-9]+)%/.exec(o),r=!!e.horizFirst?["right","bottom"]:["bottom","right"],l=e.duration/2,h=V.effects.createPlaceholder(i),c=i.cssClip(),u={clip:V.extend({},c)},d={clip:V.extend({},c)},p=[c[r[0]],c[r[1]]],f=i.queue().length;a&&(o=parseInt(a[1],10)/100*p[s?0:1]),u.clip[r[0]]=o,d.clip[r[0]]=o,d.clip[r[1]]=0,n&&(i.cssClip(d.clip),h&&h.css(V.effects.clipToBox(d)),d.clip=c),i.queue(function(t){h&&h.animate(V.effects.clipToBox(u),l,e.easing).animate(V.effects.clipToBox(d),l,e.easing),t()}).animate(u,l,e.easing).animate(d,l,e.easing).queue(t),V.effects.unshift(i,f,4)}),V.effects.define("highlight","show",function(t,e){var i=V(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),V.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("size",function(s,e){var n,i=V(this),t=["fontSize"],o=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],a=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],r=s.mode,l="effect"!==r,h=s.scale||"both",c=s.origin||["middle","center"],u=i.css("position"),d=i.position(),p=V.effects.scaledDimensions(i),f=s.from||p,g=s.to||V.effects.scaledDimensions(i,0);V.effects.createPlaceholder(i),"show"===r&&(r=f,f=g,g=r),n={from:{y:f.height/p.height,x:f.width/p.width},to:{y:g.height/p.height,x:g.width/p.width}},"box"!==h&&"both"!==h||(n.from.y!==n.to.y&&(f=V.effects.setTransition(i,o,n.from.y,f),g=V.effects.setTransition(i,o,n.to.y,g)),n.from.x!==n.to.x&&(f=V.effects.setTransition(i,a,n.from.x,f),g=V.effects.setTransition(i,a,n.to.x,g))),"content"!==h&&"both"!==h||n.from.y!==n.to.y&&(f=V.effects.setTransition(i,t,n.from.y,f),g=V.effects.setTransition(i,t,n.to.y,g)),c&&(r=V.effects.getBaseline(c,p),f.top=(p.outerHeight-f.outerHeight)*r.y+d.top,f.left=(p.outerWidth-f.outerWidth)*r.x+d.left,g.top=(p.outerHeight-g.outerHeight)*r.y+d.top,g.left=(p.outerWidth-g.outerWidth)*r.x+d.left),delete f.outerHeight,delete f.outerWidth,i.css(f),"content"!==h&&"both"!==h||(o=o.concat(["marginTop","marginBottom"]).concat(t),a=a.concat(["marginLeft","marginRight"]),i.find("*[width]").each(function(){var t=V(this),e=V.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},e={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=V.effects.setTransition(t,o,n.from.y,i),e=V.effects.setTransition(t,o,n.to.y,e)),n.from.x!==n.to.x&&(i=V.effects.setTransition(t,a,n.from.x,i),e=V.effects.setTransition(t,a,n.to.x,e)),l&&V.effects.saveStyle(t),t.css(i),t.animate(e,s.duration,s.easing,function(){l&&V.effects.restoreStyle(t)})})),i.animate(g,{queue:!1,duration:s.duration,easing:s.easing,complete:function(){var t=i.offset();0===g.opacity&&i.css("opacity",f.opacity),l||(i.css("position","static"===u?"relative":u).offset(t),V.effects.saveStyle(i)),e()}})}),V.effects.define("scale",function(t,e){var i=V(this),s=t.mode,s=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),i=V.extend(!0,{from:V.effects.scaledDimensions(i),to:V.effects.scaledDimensions(i,s,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(i.from.opacity=1,i.to.opacity=0),V.effects.effect.size.call(this,i,e)}),V.effects.define("puff","hide",function(t,e){t=V.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});V.effects.effect.scale.call(this,t,e)}),V.effects.define("pulsate","show",function(t,e){var i=V(this),s=t.mode,n="show"===s,o=2*(t.times||5)+(n||"hide"===s?1:0),a=t.duration/o,r=0,l=1,s=i.queue().length;for(!n&&i.is(":visible")||(i.css("opacity",0).show(),r=1);l1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); From 0cbf4d519d3b9d9290f1f8a6c79a9154ecaf92c9 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 14:26:14 +0100 Subject: [PATCH 112/122] Update wlan0 --- emhttp/plugins/dynamix/nchan/wlan0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index 7ad24f319..ce5950c1f 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -59,6 +59,6 @@ while (true) { $echo['title'] = _('No active WiFi'); } publish('wlan0',json_encode($echo)); - sleep(5); + sleep(3); } ?> From bc3d1eaeb25322d2027b3669f47fad9a4845fcc7 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 17:16:40 +0100 Subject: [PATCH 113/122] Wireless support --- emhttp/plugins/dynamix/Wireless.page | 2 +- emhttp/plugins/dynamix/include/Wireless.php | 2 +- etc/rc.d/rc.wireless | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/emhttp/plugins/dynamix/Wireless.page b/emhttp/plugins/dynamix/Wireless.page index 34990a1ed..07cff7675 100644 --- a/emhttp/plugins/dynamix/Wireless.page +++ b/emhttp/plugins/dynamix/Wireless.page @@ -73,7 +73,7 @@ function update_wifi() { $('#other_networks').html(wifi.other); } }); - timers.wifi = setTimeout(update_wifi,5000); + timers.wifi = setTimeout(update_wifi,10000); } function manage_wifi(ssid,task) { diff --git a/emhttp/plugins/dynamix/include/Wireless.php b/emhttp/plugins/dynamix/include/Wireless.php index 68b9a126a..54e82c1a8 100644 --- a/emhttp/plugins/dynamix/include/Wireless.php +++ b/emhttp/plugins/dynamix/include/Wireless.php @@ -82,7 +82,7 @@ case 'list': $index = 0; if (count(array_column($wlan,'ssid'))) { $up = file_exists($carrier) && file_get_contents($carrier)==1; - $alive = $up ? exec("iw ".escapeshellarg($port)." link | grep -Pom1 'SSID: \K.+'") : ''; + $alive = $up ? exec("iw ".escapeshellarg($port)." link 2>/dev/null | grep -Pom1 'SSID: \K.+'") : ''; $state = $up ? _('Connected') : _('Disconnected'); $color = $up ? 'blue' : 'red'; diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index 1c01646ff..096b89cc5 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -155,7 +155,8 @@ ipaddr_down(){ wpa_configuration(){ PSK=$(wpa_passphrase "$SSID" "$PASSWORD" 2>/dev/null | grep -Pom1 '^\s+psk=\K.+') [[ -z $PSK ]] && PSK="\"$PASSWORD\"" - echo "network={" >$WPA + echo "bgscan=\"\"" >$WPA + echo "network={" >>$WPA echo "ssid=\"$SSID\"" >>$WPA [[ $1 == "PSK" ]] && echo "key_mgmt=WPA-PSK" >>$WPA [[ $1 == "SAE" ]] && echo "key_mgmt=SAE" >>$WPA @@ -214,7 +215,7 @@ wifi_stop(){ ipaddr_down fi pkill wpa_supplicant - iw dev $PORT disconnect + iw dev $PORT disconnect 2>/dev/null rm -f $INI if ! wifi_running; then REPLY="Stopped"; else REPLY="Failed"; fi else @@ -238,15 +239,15 @@ wifi_join(){ SECURITY=${SECURITY:-$ATTR3} if [[ -z $SECURITY || ${SECURITY^^} == "OPEN" ]]; then # open network - iw dev $PORT connect "$SSID" auth open + iw dev $PORT connect "$SSID" auth open 2>/dev/null elif [[ $SECURITY =~ "WEP" ]]; then # WEP encryption - iw dev $PORT connect "$SSID" auth shared key 0:$(hex "$PASSWORD") + iw dev $PORT connect "$SSID" auth shared key 0:$(hex "$PASSWORD") 2>/dev/null else # WPA encryption wpa_configuration "$SECURITY" [[ -n $(pgrep wpa_supplicant) ]] && pkill wpa_supplicant - wpa_supplicant -B -i $PORT -c $WPA + wpa_supplicant -B -i $PORT -c $WPA 2>/dev/null fi # IPv4 address assignment IP=ipv4 From 6db4ef75207011d8deeb15e5fc56378b227398d7 Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 3 Feb 2025 18:46:16 +0100 Subject: [PATCH 114/122] Add wlan to port selection --- emhttp/plugins/dynamix/DashStats.page | 3 ++- emhttp/plugins/dynamix/nchan/update_3 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 0f68cb030..8e46f29f8 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -145,7 +145,8 @@ $cpumodel = str_ireplace(["Processor","(C)","(R)","(TM)"],["","©","®", $cpumodel .= (strpos($cpumodel,'@')===false && !empty($cpu['Current Speed']) ? " @ {$cpu['Current Speed']}" : ""); $total = exec("awk '/^MemTotal/{print $2*1024}' /proc/meminfo"); -unset($ports); exec("ls /sys/class/net|grep -Po '^(lo|(bond|eth)\d+)$'",$ports); +unset($ports); exec("ls --indicator-style=none /sys/class/net|grep -Po '^(bond|eth|wlan)\d+$'",$ports); +$ports[] = 'lo'; $sizes = ['MB','GB','TB']; $memory_type = $ecc = ''; diff --git a/emhttp/plugins/dynamix/nchan/update_3 b/emhttp/plugins/dynamix/nchan/update_3 index a5ab73355..89db15da0 100755 --- a/emhttp/plugins/dynamix/nchan/update_3 +++ b/emhttp/plugins/dynamix/nchan/update_3 @@ -50,7 +50,8 @@ function update_translation($locale) { } function ports() { global $net; - exec("ls --indicator-style=none $net|grep -Po '^(lo|(bond|eth)\d+)$'",$ports); + exec("ls --indicator-style=none $net|grep -Po '^(bond|eth|wlan)\d+$'",$ports); + $ports[] = 'lo'; return $ports; } From 125092fb8cae08ad316e9f81a518d608fb87943a Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 4 Feb 2025 05:49:35 +0100 Subject: [PATCH 115/122] Wireless support - finetuning --- emhttp/plugins/dynamix/DashStats.page | 4 ++-- etc/rc.d/rc.docker | 16 ++++++++-------- etc/rc.d/rc.wireless | 11 ++++------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index 8e46f29f8..b12ed8a37 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -1011,7 +1011,7 @@ function getCase() { function changeMode(item) { if (item==0) delete cookie.enter_share; else cookie.enter_share = item; - saveCookie(); + if (!startup) saveCookie(); if (startup || $('.smb.share1').parent().find('tr:eq(1)').is(':visible')) { if (item==0) $('.smb.share1').show(); else $('.smb.share1').hide(); @@ -1033,7 +1033,7 @@ function changeMode(item) { function changeView(item) { if (item==0) delete cookie.enter_view; else cookie.enter_view = item; - saveCookie(); + if (!startup) saveCookie(); if (item==0) $('.view1').show(); else $('.view1').hide(); if (item==1) $('.view2').show(); else $('.view2').hide(); if (item==2) $('.view3').show(); else $('.view3').hide(); diff --git a/etc/rc.d/rc.docker b/etc/rc.d/rc.docker index e233fa6c8..aed81b96d 100755 --- a/etc/rc.d/rc.docker +++ b/etc/rc.d/rc.docker @@ -418,10 +418,10 @@ docker_network_start(){ if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then # create shim interface and copy parent IPv4 address to shim interface [[ -e $SYSTEM/$LINK ]] || run ip link add $LINK link $NETWORK type $ATTACH mode $MODE - run ip -4 addr flush dev $LINK + run ip addr flush dev $LINK run ip -4 addr add $IPV4 dev $LINK metric 0 # disable IPv6 on shim interface - echo 1 > $CONF6/$LINK/disable_ipv6 + echo 1 >$CONF6/$LINK/disable_ipv6 run ip link set $LINK up if [[ -n $GW ]]; then if [[ -z ${GW[1]} ]]; then @@ -438,19 +438,19 @@ docker_network_start(){ elif [[ -e $SYSTEM/$LINK ]]; then # remove shim interface [[ -n $GW ]] && ip -4 route del default via $GW dev $LINK - run ip -4 addr flush dev $LINK + run ip addr flush dev $LINK run ip link set $LINK down run ip link del $LINK fi else if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then - run ip -4 addr flush dev $VHOST - # copy parent IPv4 address to vhost interface + run ip addr flush dev $VHOST + # copy IPv4 address to vhost interface run ip -4 addr add $IPV4 dev $VHOST metric 0 log "prepared network $VHOST for host access" elif [[ -e $SYSTEM/$VHOST ]]; then # remove IP addresses - run ip -4 addr flush dev $VHOST + run ip addr flush dev $VHOST fi fi fi @@ -481,13 +481,13 @@ docker_network_stop(){ if [[ -e $SYSTEM/$LINK ]]; then GW=$(ip -4 route show default dev $LINK | awk '{print $3;exit}') [[ -n $GW ]] && run ip -4 route del default via $GW dev $LINK - run ip -4 addr flush dev $LINK + run ip addr flush dev $LINK run ip link set $LINK down run ip link del $LINK fi else VHOST=vhost${NETWORK//[^0-9.]/} - [[ -e $SYSTEM/$VHOST ]] && run ip -4 addr flush dev $VHOST + [[ -e $SYSTEM/$VHOST ]] && run ip addr flush dev $VHOST fi done done diff --git a/etc/rc.d/rc.wireless b/etc/rc.d/rc.wireless index 096b89cc5..ea62d0336 100755 --- a/etc/rc.d/rc.wireless +++ b/etc/rc.d/rc.wireless @@ -64,12 +64,6 @@ carrier_up(){ return 1 } -# function to enable/disable ipv6 protocol per interface -ipv6_up(){ - [[ -d $CONF6/${PORT/$1/$2} ]] && echo $4 >$CONF6/${PORT/$1/$2}/disable_ipv6 - [[ -d $CONF6/${PORT/$1/$3} ]] && echo $4 >$CONF6/${PORT/$1/$3}/disable_ipv6 -} - # function to enable/disable ipv6 assignment per interface ipv6_addr(){ if [[ -d $CONF6/$1 ]]; then @@ -81,6 +75,9 @@ ipv6_addr(){ # function to assign IP address ipaddr_up(){ + # disable IPv6 per interface when IPv4 only + [[ $IP == ipv4 ]] && DISABLE6=1 || DISABLE6=0 + [[ -d $CONF6/$PORT ]] && echo $DISABLE6 >$CONF6/$PORT/disable_ipv6 if [[ $DHCP == yes ]]; then # bring up interface using DHCP/SLAAC ipv6_addr 1 1 @@ -182,7 +179,7 @@ wifi_start(){ log "Starting $DAEMON..." local REPLY if [[ -e $SYSTEM/$PORT ]]; then - ip link set $PORT up + run ip link set $PORT up ssl_init # start active SSID $STARTWIFI From cc7703f0c724b0dba11dcce5a82db9739bb561be Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 4 Feb 2025 10:02:46 +0100 Subject: [PATCH 116/122] Rename file to "dashboard_settings.json" --- emhttp/plugins/dynamix/DashStats.page | 2 +- emhttp/plugins/dynamix/include/InitCharts.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/DashStats.page b/emhttp/plugins/dynamix/DashStats.page index b12ed8a37..e442e02ee 100644 --- a/emhttp/plugins/dynamix/DashStats.page +++ b/emhttp/plugins/dynamix/DashStats.page @@ -58,7 +58,7 @@ exec("/etc/rc.d/rc.libvirt status >/dev/null",$dummy,$libvirtd); $dockerd = $dockerd==0; $libvirtd = $libvirtd==0; $apcupsd = file_exists('/var/run/apcupsd.pid'); -$cookie = '/boot/config/cookie.json'; +$cookie = '/boot/config/dashboard_settings.json'; $conf = glob('/etc/wireguard/wg*.conf'); $wireguard = is_executable('/usr/bin/wg') && count($conf); $started = _var($var,'fsState')=='Started'; diff --git a/emhttp/plugins/dynamix/include/InitCharts.php b/emhttp/plugins/dynamix/include/InitCharts.php index 4576fc5ae..4d6be9dbb 100644 --- a/emhttp/plugins/dynamix/include/InitCharts.php +++ b/emhttp/plugins/dynamix/include/InitCharts.php @@ -14,7 +14,7 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); $charts = '/var/tmp/charts_data.tmp'; -$cookie = '/boot/config/cookie.json'; +$cookie = '/boot/config/dashboard_settings.json'; switch ($_POST['cmd']) { case 'get': From e162795f91592a793519b4a05ca5994e8955c950 Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 01:27:04 +0100 Subject: [PATCH 117/122] Docker: show wireless IP address when fixed connection is not present --- .../dynamix.docker.manager/include/DockerClient.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index b30b6d331..6e1b9403a 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -36,9 +36,11 @@ $dockerManPaths = [ ]; // load network variables if needed. -$ethX = 'eth0'; -if (!isset($$ethX)) extract(parse_ini_file("$docroot/state/network.ini",true)); -$host = ipaddr($ethX); +$system = '/sys/class/net'; +$port = file_exists("$system/br0") ? 'br0' : (file_exists("$system/bond0") ? 'bond0' : 'eth0'); +$host = exec ("ip -br -4 addr show $port scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); + +if (empty($host) && file_exists("$system/wlan0")) $host = exec ("ip -br -4 addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); // get network drivers $driver = DockerUtil::driver(); From bc830d71cd59f9b43daeccbe26c93675ae5e562b Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 12:30:52 +0100 Subject: [PATCH 118/122] Wireless support : finetuning --- .../include/DockerClient.php | 45 ++++++++++--------- .../include/DockerContainers.php | 23 ++++++---- .../include/Helpers.php | 8 ++-- emhttp/plugins/dynamix/include/Wrappers.php | 36 ++++++++++++++- sbin/create_network_ini | 12 ++--- 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 6e1b9403a..26e1a0b15 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -1,6 +1,6 @@ "$docroot/state/plugins/dynamix.docker.manager/docker.json" ]; -// load network variables if needed. -$system = '/sys/class/net'; -$port = file_exists("$system/br0") ? 'br0' : (file_exists("$system/bond0") ? 'bond0' : 'eth0'); -$host = exec ("ip -br -4 addr show $port scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); - -if (empty($host) && file_exists("$system/wlan0")) $host = exec ("ip -br -4 addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); - -// get network drivers -$driver = DockerUtil::driver(); - -// determine active port name -$port = file_exists('/sys/class/net/br0') ? 'BR0' : (file_exists('/sys/class/net/bond0') ? 'BOND0' : 'ETH0'); - // Docker configuration file - guaranteed to exist $docker_cfgfile = '/boot/config/docker.cfg'; if (file_exists($docker_cfgfile)) { + $port = strtoupper(DockerUtil::port()); exec("grep -Pom2 '_SUBNET_|_{$port}(_[0-9]+)?=' $docker_cfgfile",$cfg); if (isset($cfg[0]) && $cfg[0]=='_SUBNET_' && empty($cfg[1])) { # interface has changed, update configuration @@ -279,9 +267,8 @@ class DockerTemplates { } private function getControlURL(&$ct, $myIP, $WebUI) { - global $host; $port = &$ct['Ports'][0]; - $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? $host : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); + $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? DockerUtils::host() : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); // Get the WebUI address from the templates as a fallback $WebUI = preg_replace("%\[IP\]%", $myIP, $WebUI ?? $this->getTemplateValue($ct['Image'], 'WebUI')); if (preg_match("%\[PORT:(\d+)\]%", $WebUI, $matches)) { @@ -305,9 +292,11 @@ class DockerTemplates { } public function getAllInfo($reload=false,$com=true,$communityApplications=false) { - global $driver, $dockerManPaths, $host; + global $dockerManPaths; $DockerClient = new DockerClient(); $DockerUpdate = new DockerUpdate(); + $driver = DockerUtil::driver(); + $host = DockerUtil::host(); //$DockerUpdate->verbose = $this->verbose; $info = DockerUtil::loadJSON($dockerManPaths['webui-info']); $autoStart = array_map('var_split', @file($dockerManPaths['autostart-file'],FILE_IGNORE_NEW_LINES) ?: []); @@ -959,7 +948,8 @@ class DockerClient { } public function getDockerContainers() { - global $driver, $host; + $driver = DockerUtil::driver(); + $host = DockerUtil::host(); // Return cached values if (is_array($this::$containersCache)) return $this::$containersCache; $this::$containersCache = []; @@ -1176,5 +1166,20 @@ class DockerUtil { public static function ctMap($ct, $type='Name') { return static::docker("inspect --format='{{.$type}}' $ct"); } + + public static function port() { + if (lan_port('br0')) return 'br0'; + if (lan_port('bond0')) return 'bond0'; + if (lan_port('eth0')) return 'eth0'; + if (lan_port('wlan0')) return 'wlan0'; + return ''; + } + + public static function host() { + $port = static::port(); + if (!$port) return ''; + $port = lan_port($port,true)==0 && lan_port('wlan0') ? 'wlan0' : $port; + return exec("ip -br -4 addr show $port scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}'"); + } } ?> diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php index 3b12a9507..8cc1d6670 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php @@ -1,6 +1,6 @@ getAllInfo(); $docker = []; @@ -144,23 +147,25 @@ foreach ($containers as $ct) { $ports_internal = []; $ports_external = []; if (isset($ct['Ports']['vlan'])) { - foreach ($ct['Ports']['vlan'] as $i) + foreach ($ct['Ports']['vlan'] as $i) { $ports_external[] = sprintf('%s', $i); + } $ports_internal[0] = sprintf('%s', 'all'); } foreach($ct['Networks'] as $netName => $netVals) { $networks[] = $netName; $network_ips[] = $running ? $netVals['IPAddress'] : null; - if (isset($ct['Networks']['host'])) { $ports_external[] = sprintf('%s', $netVals['IPAddress']); $ports_internal[0] = sprintf('%s', 'all'); - } else if (!isset($ct['Ports']['vlan']) || strpos($ct['NetworkMode'], 'container:') != 0) { + } elseif (!isset($ct['Ports']['vlan']) || strpos($ct['NetworkMode'],'container:')!==false) { foreach ($ct['Ports'] as $port) { - if (_var($port,'PublicPort') && _var($port,'Driver') == 'bridge') + if (_var($port,'PublicPort') && _var($port,'Driver') == 'bridge') { $ports_external[] = sprintf('%s:%s', $host, strtoupper(_var($port,'PublicPort'))); - if ((!isset($ct['Networks']['host'])) || (!isset($ct['Networks']['vlan']))) + } + if ((!isset($ct['Networks']['host'])) || (!isset($ct['Networks']['vlan']))) { $ports_internal[] = sprintf('%s:%s', _var($port,'PrivatePort'), strtoupper(_var($port,'Type'))); + } } } } @@ -246,7 +251,7 @@ foreach ($containers as $ct) { if (!empty($TS_version)) { if (!empty($TS_latest_version)) { if (version_compare($TS_version, $TS_latest_version, '<')) { - $TSinfo .= "
"._("Tailscale:")."v" . $TS_version . " ➔ v" . $TS_latest_version . " "._("available!")."
"; + $TSinfo .= "
"._("Tailscale:")."v".$TS_version." ➔ v".$TS_latest_version." "._("available!")."
"; } else { $TSinfo .= "
"._("Tailscale").":v".$TS_version."
"; } diff --git a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php index 28dab85c6..706790bee 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/Helpers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/Helpers.php @@ -1,6 +1,6 @@ getDockerContainers() as $ct) { $list = $port = []; diff --git a/emhttp/plugins/dynamix/include/Wrappers.php b/emhttp/plugins/dynamix/include/Wrappers.php index 37e4be227..36e5c4d63 100644 --- a/emhttp/plugins/dynamix/include/Wrappers.php +++ b/emhttp/plugins/dynamix/include/Wrappers.php @@ -1,6 +1,6 @@ =')) return $remote; } } + function _var(&$name, $key=null, $default='') { return is_null($key) ? ($name ?? $default) : ($name[$key] ?? $default); } + function celsius($temp) { return round(($temp-32)*5/9); } + function fahrenheit($temp) { return round(9/5*$temp)+32; } + function displayTemp($temp) { global $display; return (is_numeric($temp) && _var($display,'unit')=='F') ? fahrenheit($temp) : $temp; } + function get_value(&$name, $key, $default) { global $var; $value = $name[$key] ?? -1; return $value!==-1 ? $value : ($var[$key] ?? $default); } + function get_ctlr_options(&$type, &$disk) { if (!$type) return; $ports = []; @@ -106,12 +119,15 @@ function get_ctlr_options(&$type, &$disk) { if (isset($disk['smPort3'])) $ports[] = $disk['smPort3']; $type .= ($ports ? ','.implode($disk['smGlue'] ?? ',',$ports) : ''); } + function port_name($port) { return substr($port,-2)!='n1' ? $port : substr($port,0,-2); } + function exceed($value, $limit, $top=100) { return is_numeric($value) && $limit>0 ? ($value>$limit && $value<=$top) : false; } + function ipaddr($ethX='eth0', $prot=4) { global $$ethX; switch (_var($$ethX,'PROTOCOL:0')) { @@ -128,16 +144,20 @@ function ipaddr($ethX='eth0', $prot=4) { return _var($$ethX,'IPADDR:0'); } } + function no_tilde($name) { global $_tilde_ ,$_proxy_; return str_replace($_tilde_,$_proxy_,$name); } + function prefix($key) { return preg_replace('/\d+$/','',$key); } + function pool_name($key) { return preg_replace('/(\d+$|~.*$)/', '', $key); } + function native($name, $full=0) { global $_tilde_, $_arrow_; switch ($full) { @@ -145,11 +165,13 @@ function native($name, $full=0) { case 1: return strpos($name,$_tilde_)!==false ? "$_arrow_ ".explode($_tilde_,$name)[1] : $name; } } + function isSubpool($name) { global $subpools, $_tilde_; $subpool = my_explode($_tilde_,$name)[1]; return in_array($subpool,$subpools) ? $subpool : false; } + function get_nvme_info($device, $info) { switch ($info) { case 'temp': @@ -167,15 +189,18 @@ function get_nvme_info($device, $info) { return exec("smartctl -c /dev/$device 2>/dev/null | grep -Pom1 '^ *$state [+-] +\K[^W]+'"); } } + // convert strftime to date format function my_date($fmt, $time) { $legacy = ['%c' => 'D j M Y h:i A','%A' => 'l','%Y' => 'Y','%B' => 'F','%e' => 'j','%d' => 'd','%m' => 'm','%I' => 'h','%H' => 'H','%M' => 'i','%S' => 's','%p' => 'a','%R' => 'H:i', '%F' => 'Y-m-d', '%T' => 'H:i:s']; return date(strtr($fmt,$legacy), $time); } + // ensure params passed to logger are properly escaped function my_logger($message, $logger='webgui') { exec('logger -t '.escapeshellarg($logger).' -- '.escapeshellarg($message)); } + // Original PHP code by Chirp Internet: www.chirpinternet.eu // Please acknowledge use of this code by including this header. // https://www.the-art-of-web.com/php/http-get-contents/ @@ -226,6 +251,7 @@ function http_get_contents(string $url, array $opts = [], array &$getinfo = NULL curl_close($ch); return $out; } + /** * Detect network connectivity via Network Connectivity Status Indicator * @return bool @@ -235,4 +261,10 @@ function check_network_connectivity(): bool { $out = http_get_contents($url); return ($out=="Microsoft NCSI"); } + +function lan_port($port, $state=false) { + $system = '/sys/class/net'; + $exist = file_exists("$system/$port"); + return !$state ? $exist : ($exist ? file_get_contents("$system/$port/carrier") : false); +} ?> diff --git a/sbin/create_network_ini b/sbin/create_network_ini index fb5a1bd55..645aa1a37 100755 --- a/sbin/create_network_ini +++ b/sbin/create_network_ini @@ -2,8 +2,8 @@ # # script: create_network_ini # -# Copyright 2005-2023, Lime Technology -# Copyright 2012-2023, Bergware International. +# Copyright 2005-2025, Lime Technology +# Copyright 2012-2025, Bergware International. # # create initial network.ini file on system start # create system welcome message @@ -241,15 +241,15 @@ if [[ -z $interface || "eth0 br0 bond0 wlan0" =~ $interface ]]; then # find management interface [[ -e /sys/class/net/bond0 ]] && dev=bond0 || dev=eth0 [[ -e /sys/class/net/br0 ]] && dev=br0 - IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -br -6 addr show $dev scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv4=$(ip -br -4 addr show $dev scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show $dev scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') # show current IP assignment [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue if [[ -e /sys/class/net/wlan0 ]]; then echo "Wireless network:" >>/etc/issue - IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') - IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/metric [0-9]+//g; s/\/[0-9]+//g' | awk '{print $3;exit}') + IPv4=$(ip -br -4 addr show wlan0 scope global | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') + IPv6=$(ip -br -6 addr show wlan0 scope global -temporary -deprecated | sed -r 's/\/[0-9]+//g' | awk '{print $3;exit}') [[ -n $IPv4 ]] && echo " IPv4 address: $IPv4" >>/etc/issue || echo " IPv4 address: not set" >>/etc/issue [[ -n $IPv6 ]] && echo " IPv6 address: $IPv6" >>/etc/issue || echo " IPv6 address: not set" >>/etc/issue fi From fe61abe435a34e6fda78d2bde11276718fdca94a Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 12:38:47 +0100 Subject: [PATCH 119/122] Update DockerContainers.php --- .../plugins/dynamix.docker.manager/include/DockerContainers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php index 8cc1d6670..406464250 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerContainers.php @@ -13,8 +13,8 @@ ?> Date: Thu, 6 Feb 2025 12:43:59 +0100 Subject: [PATCH 120/122] Fix typo --- emhttp/plugins/dynamix.docker.manager/include/DockerClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 26e1a0b15..1d3764fd3 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -268,7 +268,7 @@ class DockerTemplates { private function getControlURL(&$ct, $myIP, $WebUI) { $port = &$ct['Ports'][0]; - $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? DockerUtils::host() : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); + $myIP = $myIP ?: $this->getTemplateValue($ct['Image'],'MyIP') ?: (_var($ct,'NetworkMode')=='host'||_var($port,'NAT') ? DockerUtil::host() : (_var($port,'IP') ?: DockerUtil::myIP($ct['Name']))); // Get the WebUI address from the templates as a fallback $WebUI = preg_replace("%\[IP\]%", $myIP, $WebUI ?? $this->getTemplateValue($ct['Image'], 'WebUI')); if (preg_match("%\[PORT:(\d+)\]%", $WebUI, $matches)) { From ee5409dd3df77e6223760520f2dc6fb1ad8a62f1 Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 15:45:23 +0100 Subject: [PATCH 121/122] Update DockerClient.php --- emhttp/plugins/dynamix.docker.manager/include/DockerClient.php | 1 + 1 file changed, 1 insertion(+) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index 1d3764fd3..a1b28d358 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -1163,6 +1163,7 @@ class DockerUtil { exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus); return $cpus; } + public static function ctMap($ct, $type='Name') { return static::docker("inspect --format='{{.$type}}' $ct"); } From dcc95fe8825406d6e477357b121ff517474f2be0 Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 6 Feb 2025 15:49:06 +0100 Subject: [PATCH 122/122] Update DockerClient.php --- .../plugins/dynamix.docker.manager/include/DockerClient.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php index a1b28d358..708e50456 100644 --- a/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/emhttp/plugins/dynamix.docker.manager/include/DockerClient.php @@ -1150,7 +1150,7 @@ class DockerUtil { } public static function custom() { - return static::docker("network ls --filter driver='bridge' --filter driver='macvlan' --filter driver='ipvlan' --format='{{.Name}}' 2>/dev/null|grep -v '^bridge$'",true); + return static::docker("network ls --filter driver='bridge' --filter driver='macvlan' --filter driver='ipvlan' --format='{{.Name}}' 2>/dev/null | grep -v '^bridge$'",true); } public static function network($custom) { @@ -1160,7 +1160,7 @@ class DockerUtil { } public static function cpus() { - exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus); + exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list | sort -nu', $cpus); return $cpus; }